question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`uvicorn.run` event loop behaviour when running programmatically.

See original GitHub issue

I am trying to run Uvicorn in the same asyncio loop as some other components like the asyncpg DB connection pool.

As far as I can tell we can specify the callable that receives the scope and creates the request coroutine two ways:

  • Passing a str containing the path to uvicorn.run but then we can’t setup our dependencies (db, redis) since that function is called each new request. We could load the dependencies by creating them when the file is imported but there is no way that will pass codereview.

  • Pass a callable to uvicorn.run with the dependencies in the scope. Unfortunately uvicorn destroy the current event loop and replaces the event loop policy during the setup phase.

What is the recommended way to do things like this? If I could pass a loop instance in the loop parameter to run and have uvicorn use that directly without destroying it then it then I could use alternative 2 as long as we don’t call unicorn.run from a async function due to the server.run behaviour..

@tomchristie

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

6reactions
alexshpilkincommented, May 19, 2019

Am I correct in assuming this is no longer supported? As far as I can see, Config.setup_event_loop (config.py line 213) now once again unconditionally dereferences LOOP_SETUPS with the loop argument.

0reactions
Eduard-gancommented, Jul 28, 2019

Pull request was merged and then the behavior was removed i believe in this commit: https://github.com/encode/uvicorn/pull/276

In my case i need to run message-consumers based on aio-pika aside a set HTTP endpoints served by uvicorn in the same event loop in my microservice application.

The only way of doing this i found is to move configuration and initialization of my consumers inside app served by uvicorn.

for example like this(sorry for a shitcode but the way is exactly the same - we’re just not messing around with event loop before uvicorn kiks in):

import uvicorn
import json
import asyncio
from aio_pika import connect_robust


async def consume_qq(channel):
    qq = await channel.declare_queue("qq")
    async with qq.iterator() as queue_iter:
        async for message in queue_iter:
            await kek(message=message)


async def queues_consuming_app():
    connection = await connect_robust(host="localhost")
    channel = await connection.channel()
    print(f"Got connection {connection}")
    print(f"Got channel {channel}")

    # Consumer-level error-handling
    while True:
        try:
            print("Starting to consume QQ")
            await consume_qq(channel=channel)
        except Exception as e:
            print(f"CRITICAL ERROR IN CUNSUMER OF QQ: [ {e} ]")
            await asyncio.sleep(7)


async def kek(message=None, text=None):
    await asyncio.sleep(3)
    if message:
        async with message.process(requeue=True, reject_on_redelivered=True):
            print(f'Got message: {json.loads(getattr(message, "body", b"{}").decode())}')
    else:
        print(f"No messege, text is {text}")


async def root_app(scope, receive, send):
    print(f"HTTP CALL OR LIFESPAN: {scope}, {receive}, {send}")
    # Hooking up message consuming
    asyncio.ensure_future(queues_consuming_app(), loop=asyncio.get_event_loop())


if __name__ == "__main__":
    uvicorn.run(root_app, host="127.0.0.1", port=5000, log_level="info")
Read more comments on GitHub >

github_iconTop Results From Across the Web

How to use event loop created by uvicorn? - Stack Overflow
Basically you have to create your own event loop and pass it to uvicorn. import asyncio from uvicorn import Config, Server async def ......
Read more >
esg - Python Package Health Analysis | Snyk
Is a hard fork of the awesome uvicorn project. Protocol implementation based on: llhttp - For HTTP payload; http-parser - For URL parsing;...
Read more >
tiangolo/fastapi - Gitter
I'm using https://github.com/tiangolo/uvicorn-gunicorn-docker as the base ... time.sleep will block the event loop, you need await asyncio.sleep in an async ...
Read more >
GraphQL Code Libraries, Tools and Services
To run a GraphQL.js hello world script from the command line: ... Logical yet simple default behaviour and document caching, and normalized caching...
Read more >
YAML: The Missing Battery in Python
Parsing YAML Documents at a Low Level. Tokenize a YAML Document; Parse a Stream of Events; Build a Tree of Nodes. Conclusion.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found