Gufo Ping Example: Series of Requests
Lets send the sequence of the ICMP echo requests and get the
replies.
series.py import asyncio
import sys
from gufo.ping import Ping
async def main ( addr : str ) -> None :
ping = Ping ()
async for r in ping . iter_rtt ( addr , count = 5 ):
print ( r )
if __name__ == "__main__" :
asyncio . run ( main ( sys . argv [ 1 ]))
The code is straightforward:
series.py import asyncio
import sys
from gufo.ping import Ping
async def main ( addr : str ) -> None :
ping = Ping ()
async for r in ping . iter_rtt ( addr , count = 5 ):
print ( r )
if __name__ == "__main__" :
asyncio . run ( main ( sys . argv [ 1 ]))
We need asyncio.run() to run asynchronous code, so lets import the asyncio.
series.py import asyncio
import sys
from gufo.ping import Ping
async def main ( addr : str ) -> None :
ping = Ping ()
async for r in ping . iter_rtt ( addr , count = 5 ):
print ( r )
if __name__ == "__main__" :
asyncio . run ( main ( sys . argv [ 1 ]))
Import sys module to parse the CLI argument.
Warning
We use sys.argv only for demonstration purposes. Use argsparse or alternatives
in real-world applications.
series.py import asyncio
import sys
from gufo.ping import Ping
async def main ( addr : str ) -> None :
ping = Ping ()
async for r in ping . iter_rtt ( addr , count = 5 ):
print ( r )
if __name__ == "__main__" :
asyncio . run ( main ( sys . argv [ 1 ]))
Ping object holds all necessary API, so import it from gufo.ping.
series.py import asyncio
import sys
from gufo.ping import Ping
async def main ( addr : str ) -> None :
ping = Ping ()
async for r in ping . iter_rtt ( addr , count = 5 ):
print ( r )
if __name__ == "__main__" :
asyncio . run ( main ( sys . argv [ 1 ]))
Asynchronous code must be executed in the asynchronous functions, or coroutines.
So we define our function as async. We expect an address to ping as the
addr argument.
series.py import asyncio
import sys
from gufo.ping import Ping
async def main ( addr : str ) -> None :
ping = Ping ()
async for r in ping . iter_rtt ( addr , count = 5 ):
print ( r )
if __name__ == "__main__" :
asyncio . run ( main ( sys . argv [ 1 ]))
First we need to create Ping object. Ping constructor offers a lots
of configuration variables for fine-tuning. Refer to the
Ping reference
for further details. Defaults are good enough for our tutorial, so
we ommited them.
series.py import asyncio
import sys
from gufo.ping import Ping
async def main ( addr : str ) -> None :
ping = Ping ()
async for r in ping . iter_rtt ( addr , count = 5 ):
print ( r )
if __name__ == "__main__" :
asyncio . run ( main ( sys . argv [ 1 ]))
Ping.iter_rtt() returns the asynchronous iterator, yielding for each attempt the:
In case of success: Round-trip-time (RTT), as float, measured in seconds.
In case of failure: None.
The only mandatory parameter is IP address.
Gufo Ping detects IPv4/IPv6 usage, so all we need is to pass an address.
Function may accept the additional parameters for fine-tuning,
Refer to the
Ping.ping reference
for details.
Note
Ping.iter_rtt() is the asynchronous iterator and should be
used along with async for construction.
series.py import asyncio
import sys
from gufo.ping import Ping
async def main ( addr : str ) -> None :
ping = Ping ()
async for r in ping . iter_rtt ( addr , count = 5 ):
print ( r )
if __name__ == "__main__" :
asyncio . run ( main ( sys . argv [ 1 ]))
Lets print the result of each iteration.
series.py import asyncio
import sys
from gufo.ping import Ping
async def main ( addr : str ) -> None :
ping = Ping ()
async for r in ping . iter_rtt ( addr , count = 5 ):
print ( r )
if __name__ == "__main__" :
asyncio . run ( main ( sys . argv [ 1 ]))
To run our example from command line we need to check
we're in __main__ module.
series.py import asyncio
import sys
from gufo.ping import Ping
async def main ( addr : str ) -> None :
ping = Ping ()
async for r in ping . iter_rtt ( addr , count = 5 ):
print ( r )
if __name__ == "__main__" :
asyncio . run ( main ( sys . argv [ 1 ]))
Lets run our asyncronous main() function via asyncio.run
and pass first command-line parameter as address.
Running
Lets check the success case. Run example as:
$ sudo python3 examples/series.py 127.0.0.1
0.001022267
0.001339276
0.000560895
0.000832927
0.001220127
Ok, we got a measured RTT.
Lets check the faulty cause. RFC-5737 defines the special range
of addresses - 192.0.2.0/24, which can be used as unresponsible addresses.
So, lets ping a 192.0.2.1:
$ sudo python3 examples/series.py 192.0.2.1
None
None
None
None
None
After second or so of awaiting we finally got a None, which means our
request is timed out.