13.20. AsyncIO Context Manager

  • __aenter__

  • __aexit__

13.20.1. Example

>>> class AsyncContextManager:
...     async def __aenter__(self):
...         await print('entering context')
...
...     async def __aexit__(self, exc_type, exc, tb):
...         await print('exiting context')

13.20.2. Use Case - 0x01

>>> from unittest import IsolatedAsyncioTestCase
>>> from httpx import AsyncClient, Response, HTTPStatusError
>>> from http import HTTPStatus
>>>
>>>
>>> BASE_URL = 'https://python3.info'
>>>
>>> async def request(method: str = 'GET',
...             path: str = '/',
...             data: dict | None = None,
...             headers: dict | None = None,
...             ) -> Response:
...     async with AsyncClient(base_url=BASE_URL) as ac:
...         return await ac.request(method=method, url=path, data=data, headers=headers)
...
...
>>> class WebsiteTest(IsolatedAsyncioTestCase):
...     async def test_index(self):
...         resp = await request('GET', '/index.html')
...         self.assertEqual(resp.status_code, HTTPStatus.OK)
...         self.assertIn('Python - from None to AI', resp.text)
...         self.assertIn('Matt Harasymczuk', resp.text)
...         self.assertIn('Creative Commons Attribution-ShareAlike 4.0 International License', resp.text)
...
...     async def test_license(self):
...         resp = await request('GET', '/LICENSE.html')
...         self.assertEqual(resp.status_code, HTTPStatus.OK)
...         self.assertIn('Matt Harasymczuk', resp.text)
...         self.assertIn('matt@astronaut.center', resp.text)
...         self.assertIn('last update: ', resp.text)
...         self.assertIn('Creative Commons Attribution-ShareAlike 4.0 International Public License', resp.text)
...
...     async def test_login(self):
...         resp = await request('POST', '/login.html', data={'username':'mwatney', 'password': 'Ares3'})
...         self.assertEqual(resp.status_code, HTTPStatus.FORBIDDEN)
...         with self.assertRaises(HTTPStatusError):
...             resp.raise_for_status()
...
...     async def test_install(self):
...         resp = await request('GET', '/install.html')
...         self.assertEqual(resp.status_code, HTTPStatus.OK)
...         with self.subTest('Python'):
...             self.assertNotIn('3.8', resp.text)
...             self.assertNotIn('3.9', resp.text)
...             self.assertNotIn('3.10', resp.text)
...             self.assertIn('3.11', resp.text)
...             self.assertIn('3.12', resp.text)
...         with self.subTest('PyCharm'):
...             self.assertNotIn('2021.1', resp.text)
...             self.assertNotIn('2021.2', resp.text)
...             self.assertNotIn('2021.3', resp.text)
...             self.assertNotIn('2022.1', resp.text)
...             self.assertNotIn('2022.2', resp.text)
...             self.assertNotIn('2022.3', resp.text)
...             self.assertNotIn('2023.1', html.text)
...             self.assertNotIn('2023.1', html.text)
...             self.assertIn('2023.3', html.text)
...         with self.subTest('Git'):
...             self.assertIn('2.40 lub nowszy', resp.text)