Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Completing Asynchronous Support

00:00 Completing Asynchronous Support. In this part of the course, you’ll complete the asynchronous support you started earlier on, starting by adding an async option to the CLI.

00:14 The option can just be a Boolean flag. To implement this kind of option, you use the action argument of the .add_argument() method.

00:22 Open the cli.py file and update read_user_cli_args() with the code seen on-screen.

00:32 This call to .add_argument() adds a new -a or --asynchronous option to the application’s CLI. The action argument is set to "store_true", which tells argparse that -a and --asynchronous are Boolean flags that will store True when provided at the command line.

00:52 To check the connectivity of multiple websites asynchronously you’ll write an async function that calls and awaits site_is_online_async() from the checker module.

01:02 Add the code seen on-screen to the __main__.py file. First, the imports are updated to add asyncio and site_is_online_async().

01:25 Next, _asynchronous_check() is defined as an asynchronous function using the async keyword. This function takes a list of URLs and checks their connectivity asynchronously. Here, you define an inner async function, which allows you to reuse the code that checks a single URL for connectivity.

01:45 Here, you define and initialize a placeholder error variable, which will be used in the call to display_check_result() later. Here, you define a tryexcept statement to wrap the connectivity check. The try block calls and awaits site_is_online_async() with the target URL as an argument. If the call succeeds, then result will be True.

02:09 If the call raises an exception, then result will be False and error will hold the resulting error message.

02:18 This line calls display_check_result() using result, url, and error as arguments. This calls and awaits the gather() function from the asyncio module.

02:30 This function runs a list of awaitable objects concurrently and returns an aggregated list of resulting values if all the awaitable objects complete successfully. To provide the list of awaitable objects, you use a generator expression that calls _check() for each target URL.

02:49 To add the asynchronous functionality to your application’s main() function, you’ll use a conditional statement to check if the user provided the -a or --asynchronous flag at the command line.

03:00 This conditional will allow you to run the connectivity checks with the right tool according to the user’s input. Open the __main__.py file again, and update the code as seen on-screen.

03:16 The conditional statement checks if the user has provided the -a or --asynchronous flag at the command line. If that’s the case, main() runs the connectivity checks asynchronously using asyncio.run().

03:30 Otherwise, it runs the check synchronously using the _synchronous_check() function. That’s it. You can now test this new feature of your website connectivity checker in practice.

03:41 Go back to your command line and run the command seen on-screen. This shows that your application now has an -a or --asynchronous option that will run the connectivity checks asynchronously. Next, the content of the sample-urls file is shown on-screen. Note the order of the websites, starting with python.org.

04:04 Next, rpchecker runs the connectivity check synchronously, just like you did in a previous section. This is because you don’t provide the -a or --asynchronous flags. Note that the URLs are checked in the same order that they appear in the text file.

04:20 Now you use the -a flag at the end of the line. This flag makes rpchecker run the connectivity checks concurrently. Now the check results aren’t displayed in the same order as the URLs are entered, but in the order in which the responses come from the target websites.

04:39 As an exercise, run the connectivity checker with a long list of target URLs and compare the execution time when the app runs synchronously and asynchronously.

04:59 Now that you have a fully featured site connectivity checker, in the next section, you’ll take a look back at what you’ve learned in this course.

Avatar image for padmabharti22

padmabharti22 on June 15, 2023

Hi,

I am getting the below attribute error when I run the command - python -m rpchecker -f sample-urls.txt and I am unable to resolve it. Can you please help?

File “<frozen runpy>”, line 198, in _run_module_as_main File “<frozen runpy>”, line 88, in _run_code

File “C:\Users\pk050\OneDrive\Desktop\rpchecker_project\rpchecker__main__.py”, line 60, in <module> main()

File “C:\Users\pk050\OneDrive\Desktop\rpchecker_project\rpchecker__main__.py”, line 14, in main if user_args.asynchronous: ^^^^^^^^^^^^^^^^^^^^^^

AttributeError: ‘Namespace’ object has no attribute ‘asynchronous’

(drive.google.com/file/d/1eCVxnUuQe3BPXV1bPRDhSrX-IZdPoAAR/view?usp=sharing)

Avatar image for Darren Jones

Darren Jones RP Team on June 21, 2023

@padmabharti22 - it’s hard to tell without seeing your code, but my guess is that there’s a problem with the definition of read_user_args in cli.py.

If I comment out the following code in my cli.py file, I get the same error:

# parser.add_argument( # "-a", # "--asynchronous", # action="store_true", # help="run the connectivity check asynchronously", # )

So, it looks to me as if that argument isn’t defined correctly (possibly asynchronous is missing or incorrectly spelled), and as a result the namespace that is being returned doesn’t have that attribute.

Become a Member to join the conversation.