python-trio / trio-asyncio

a re-implementation of the asyncio mainloop on top of Trio

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

aiohttp example from their README does not work

lordi opened this issue · comments

I took the example from aiohttp README and added trio_asyncio magic:

import aiohttp
import trio
import trio_asyncio
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'http://python.org')
        print(len(html))

async def async_main_wrapper(*args):
    async with trio_asyncio.open_loop() as loop:
        assert loop == asyncio.get_event_loop()
        await main()

trio.run(async_main_wrapper)

This results in:

Traceback (most recent call last):
  File "test.py", line 20, in <module>
    trio.run(async_main_wrapper)
  File "venv/lib/python3.7/site-packages/trio/_core/_run.py", line 1337, in run
    raise runner.main_task_outcome.error
  File "test.py", line 18, in async_main_wrapper
    await main()
  File "test.py", line 12, in main
    html = await fetch(session, 'http://python.org')
  File "test.py", line 7, in fetch
    async with session.get(url) as response:
  File "venv/lib/python3.7/site-packages/aiohttp/client.py", line 1005, in __aenter__
    self._resp = await self._coro
  File "venv/lib/python3.7/site-packages/aiohttp/client.py", line 417, in _request
    with timer:
  File "venv/lib/python3.7/site-packages/aiohttp/helpers.py", line 568, in __enter__
    raise RuntimeError('Timeout context manager should be used '
RuntimeError: Timeout context manager should be used inside a task

What causes this error? What would be a better way to call aiohttp from trio?

Opening an asyncio loop is just the first step. You didn't actually switch to that asyncio context.

You can fix this by decorating your main with @aio_as_trio, or by calling aio_as_trio(fetch)(session, …). (Not both!)

However, aiohttp is a bit fiddly in that it expects to be in asyncio context for some sync operations, thus I'd definitely recommend the former method.

Ok, this works. Thank you.
Maybe the docs can be improved with regard to that. It was not clear to me.