Skip to content

Instantly share code, notes, and snippets.

@Semnodime
Created September 28, 2018 01:25
Show Gist options
  • Save Semnodime/34dacbef10eaff7a3fa6100719a27222 to your computer and use it in GitHub Desktop.
Save Semnodime/34dacbef10eaff7a3fa6100719a27222 to your computer and use it in GitHub Desktop.
Small python3.6 demo of a single async request utilizing the aiohttp framework. The point is to understand what is going on.
"""Small demo of a single async request utilizing the aiohttp framework. The point is to understand what is going on."""
import aiohttp
import asyncio
async def main():
async with aiohttp.ClientSession() as session:
# session.get() returns a context manager that can be used by `await` and `async with`
_req_context_manager = session.get('http://localhost:10000')
# print(_req_context_manager)
# it is recommended to use the `async with … as …:` similarly to how you would use `with … as …:` for files.
# you can use `async with` to automatically close the request when done or when exceptions occur
async with _req_context_manager as response:
# print(response)
while True:
print('Attempting to read content stream…')
a = await response.content.read(10)
print('Data: %r' % a)
if not a:
break
# .text() has to be used with `await` in order to be truly executed
# it only returns a ClientResponse.text
print('TEXT()________', response.text()) # <generator object ClientResponse.text at …>
# once you await this co-routine it loads all response content into memory and tries to return decoded text
if True:
print('AWAIT TEXT()__', repr((await response.text())[:20])) # '<!doctype html>\n<!--'
# Accessing .text() automatically closes the response
# If you use .content.read() without `async with … as …:` make sure to close the request manually!
# you can also access the binary (already deflated but not decoded) content directly for streaming
# the .content is no function!
# it is a StreamReader
flow_control_stream_reader = response.content
print('CONTENT', flow_control_stream_reader) # <StreamReader 2225 bytes>
# it has an asynchronous .read() which returns the co-routine that can be used by `await`
print('CONTENT.read(10)_____', flow_control_stream_reader.read(20)) # <generator object …>
# so if you `await` .content.read() you read from the content buffer of the response
print('AWAIT CONTENT.read(10)', await flow_control_stream_reader.read(20)) # b''
# since we called await .text() on the response we already emptied and closed the read stream
# you can confirm this behaviour by deactivating the `if True:…` some lines above
# then .content.read(10) will read 10 bytes: b'<!doctype html>\n<!--'
if __name__ == '__main__':
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
# The console output with python3.6 is the following (with censored memory addresses):
r'''
<aiohttp.client._RequestContextManager object at …>
<ClientResponse(https://www.python.org/) [200 OK]>
<CIMultiDictProxy('Server': 'nginx', 'Content-Type': 'text/html; charset=utf-8', 'X-Frame-Options': 'SAMEORIGIN', 'X-Xss-Protection': '1; mode=block', 'X-Clacks-Overhead': 'GNU Terry Pratchett', 'Via': '1.1 varnish', 'Content-Length': '49060', 'Accept-Ranges': 'bytes', 'Date': 'Tue, 25 Sep 2018 10:11:21 GMT', 'Via': '1.1 varnish', 'Age': '2002', 'Connection': 'keep-alive', 'X-Served-By': 'cache-iad2134-IAD, cache-hhn1520-HHN', 'X-Cache': 'HIT, HIT', 'X-Cache-Hits': '1, 4', 'X-Timer': 'S1537870282.892255,VS0,VE0', 'Vary': 'Cookie', 'Strict-Transport-Security': 'max-age=63072000; includeSubDomains')>
TEXT()________ <generator object ClientResponse.text at …>
CONTENT <StreamReader 2225 bytes>
CONTENT.read(10)_____ <generator object FlowControlStreamReader.read at …>
AWAIT TEXT()__ '<!doctype html>\n<!--'
AWAIT CONTENT.read(10) b''
Process finished with exit code 0
'''
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment