![]() |
|
[Tut] Python Async With Statement — Simplifying Asynchronous Code - Printable Version +- Sick Gaming (https://sickgaming.net) +-- Forum: Programming (https://sickgaming.net/forum-76.html) +--- Forum: Python (https://sickgaming.net/forum-83.html) +--- Thread: [Tut] Python Async With Statement — Simplifying Asynchronous Code (/thread-101051.html) |
[Tut] Python Async With Statement — Simplifying Asynchronous Code - xSicKxBot - 04-28-2023 Python Async With Statement — Simplifying Asynchronous Code 5/5 – (1 vote) To speed up my code, I just decided to (finally) dive into Python’s Code: async with In this article, you’ll find some of my learnings – let’s go! ![]() What Is Python Async With? Python’s Code: async withCode: async with![]() Let’s see some code. Picture this scenario: you’re using Code: asyncioCode: aiohttpCode: withCode: import aiohttp
import asyncio async def fetch(url): with aiohttp.ClientSession() as session: response = await session.get(url) content = await response.read() print(asyncio.run(fetch("https://example.com")))But see the problem? This would block the event loop, making your app slower .The solution is using Code: async withCode: import aiohttp
import asyncio async def fetch(url): async with aiohttp.ClientSession() as session: response = await session.get(url) content = await response.read() print(asyncio.run(fetch("https://example.com")))Thanks to Code: async with![]() No worries if you didn’t quite get it yet. Keep reading! ![]() ![]() ![]() Python Async With Examples ![]() The Code: async with .Let’s jump into an example using an Code: asyncioCode: aiohttpHere’s how you can make an HTTP GET request using an Code: async withCode: ClientSession![]() Code: import aiohttp
import asyncio async def fetch_page(session, url): async with session.get(url) as response: return await response.text() async def main(): async with aiohttp.ClientSession() as session: content = await fetch_page(session, 'https://example.com') print(content) loop = asyncio.get_event_loop()
loop.run_until_complete(main())In the example above , you use an Code: async withCode: fetch_pageCode: mainCode: aiohttp.ClientSessionCode: async with .Now, let’s discuss some key entities in this example:
Async With Await ![]() In Python, the Code: awaitCode: async defIn the context of the Code: async withCode: awaitCode: async withCode: __aenter__()Code: __aexit__()Here’s an example of how Code: async withCode: awaitCode: import aiohttp
import asyncio async def fetch(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: return await response.text() async def main(): url = 'https://example.com/' html = await fetch(url) print(html) loop = asyncio.get_event_loop()
loop.run_until_complete(main())In this example, the Code: fetchCode: aiohttpThe Code: async withCode: aiohttp.ClientSession()Code: session.get(url)The Code: awaitCode: session.get()Async With Open ![]() By using “ Code: async with openWhen working with async code, it’s crucial to avoid blocking operations. To tackle this, some libraries provide asynchronous equivalents of “ Code: openFor example: Code: import aiofiles async def read_file(file_path): async with aiofiles.open(file_path, 'r') as file: contents = await file.read() return contentsHere, we use the Code: aiofilesCode: async with![]() Remember, it’s essential to use an asynchronous file I/O library, like Code: aiofilesCode: async with open![]() Async With Yield When working with Python’s async functions, you might wonder how to use the Code: yieldCode: async with![]() Recommended: Understanding Python’s Code: yieldFirst, it’s essential to understand that you cannot use the standard Code: yieldCode: async def![]() To create an asynchronous generator, you can define a function with the Code: async defCode: yieldCode: import asyncio async def asyncgen(): yield 1 yield 2To consume the generator, use Code: async forCode: async def main(): async for i in asyncgen(): print(i) asyncio.run(main())This code will create a generator that yields values asynchronously and print them using an async context manager. This approach allows you to wrapp an asynchronous generator in a friendly and readable manner. ![]() Now you know how to use the Code: yieldCode: async with![]() Async With Return ![]() The Code: async with![]() When working with Code: async withCode: __enter__()For instance: Code: async def fetch_data(url): async with aiohttp.ClientSession() as session: async with session.get(url) as response: data = await response.json() return dataIn this example, the Code: responseCode: .__enter__()Code: async withCode: response.json() .Here are a few key takeaway points about returning values with Code: async with
Advanced Usage of Async With ![]() As you become more familiar with Python’s Code: async with
Async With Timeout When working with concurrency, it’s essential to manage timeouts effectively. In Code: async withHere’s an example of how you can define an async with statement with a timeout: Code: import asyncio
import aiohttp async def fetch_page(session, url): async with aiohttp.Timeout(10): async with session.get(url) as response: assert response.status == 200 return await response.read()This code sets a 10-second timeout to fetch a web page using the Code: aiohttpAsync With Multiple You can use multiple Code: async withCode: async withCode: async def two_resources(resource_a, resource_b): async with aquire_resource_a(resource_a) as a, aquire_resource_b(resource_b) as b: await do_something(a, b)This example acquires both resources asynchronously and then performs an operation using them. Async With Lock Concurrency can cause issues when multiple tasks access shared resources. To protect these resources and prevent race conditions, you can use Code: async withCode: asyncio.Lock()Code: import asyncio lock = asyncio.Lock() async def my_function(): async with lock: # Section of code that must be executed atomically.This code snippet ensures that the section within the Code: async withAsync With Context Manager Creating your own context managers can make it easier to manage resources in asynchronous code. By defining an Code: async def __aenter__()Code: async def __aexit__()Code: async withCode: class AsyncContextManager: async def __aenter__(self): # Code to initialize resource return resource async def __aexit__(self, exc_type, exc, tb): # Code to release resource async def demo(): async with AsyncContextManager() as my_resource: # Code using my_resourceThis custom context manager initializes and releases a resource within the Code: async with![]() Error Handling and Exceptions ![]() When working with Python’s Async With Statement, handling errors and exceptions properly is essential to ensure your asynchronous code runs smoothly. Using try-except blocks and well-structured clauses can help you manage errors effectively.Be aware of syntax errors, which may occur when using async with statements. To avoid SyntaxError, make sure your Python code is properly formatted and follows PEP 343’s guidelines. If you come across an error while performing an IO operation or dealing with external resources, it’s a good idea to handle it with an Code: except![]() In the case of exceptions, you might want to apply cleanup code to handle any necessary actions before your program closes or moves on to the next task. One way to do this is by wrapping your Code: async withCode: finallyHere’s an example: Code: try: async with some_resource() as resource: # Perform your IO operation or other tasks here
except YourException as e: # Handle the specific exception here
finally: # Add cleanup code hereRemember, you need to handle exceptions explicitly in the parent coroutine if you want to prevent them from canceling the entire task. In the case of multiple exceptions or errors, using Code: asyncio.gather![]() Recommended: Python Beginner Cheat Sheet: 19 Keywords Every Coder Must Know
|