httpx: Incompatible with jupyter

import httpx
httpx.get('https://httpbin.org/get')

When run from Jupyter this snippet produces “Cannot run the event loop while another loop is running” error. Works fine in REPL. Apparently the use of asyncio conflicts with Jupters’s own event loop.

httpx version: 0.7.6 os: Fedora 29 python: Python 3.6.9 ipykernel: 5.1.2 ipython: 7.8.0 jupyter: 5.4.1

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 22 (22 by maintainers)

Most upvoted comments

@tomchristie said that he liked that we learned from each other, so I’d like to explain my point above in more detail to explain why it’s actually relevant! It’s not actually the code generation approach that’s important here, but the fact that we’re using the standard library for I/O in the sync case, and not asyncio.

You can keep the async/await annotations and just rely on the fact that all calls will be secretly sync, and wrap the sync API with run_secretly_sync_async_fn (stolen from https://github.com/python-trio/urllib3/issues/1#issuecomment-322028457):

def run_secretly_sync_async_fn(async_fn, *args):
    coro = async_fn(*args)
    try:
        coro.send(None)
    except StopIteration as exc:
        return exc.value
    else:
        raise RuntimeError("you lied, this async function is not secretly synchronous")

The reason we’re not doing this in our urllib3 work is because 1/ we want to support Python 2.7 and 2/ wrapping a large public API with run_secretly_sync_async_fn is actually cumbersome, and adds an unrelated function to the call stack.

But it avoids both code generation and an hidden asyncio loop!

For what it’s worth, this is one advantage of the code generation approach we use in the urllib3 fork: our sync code is really sync and only uses the standard library for the actual I/O. 99% of the code is shared, only the calls to the specific I/O libraries are different.

Careful, or I might start advocating that sync HTTP requests in Python are already well supported via requests, and that httpx should only target the async case. 😇

Yes, I think that would work! Here is our sync backend: https://github.com/python-trio/urllib3/blob/bleach-spike/src/urllib3/_backends/sync_backend.py. It is complete enough to get the urllib3 test suite to pass