illagrenan / django-asgi-lifespan

Django ASGI handler with Lifespan Protocol support.

Home Page:https://illagrenan.github.io/django-asgi-lifespan/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Django ASGI Handler with Lifespan protocol support

pypi pypi python Build Status codecov

Features

Quickstart

⚠️ This package is experimental. Lifespan signals work correctly only under uvicorn.

  1. Install the package. Only Python 3.10 and Django 4 are supported.

    $ pip install --upgrade django-asgi-lifespan
  2. Modify asgi.py to use a ASGI Lifespan compatible handler.

    from django_asgi_lifespan.asgi import get_asgi_application
    
    django_application = get_asgi_application()
    
    
    async def application(scope, receive, send):
        if scope["type"] in {"http", "lifespan"}:
            await django_application(scope, receive, send)
        else:
            raise NotImplementedError(f"Unknown scope type {scope['type']}")
  3. Subscribe your (async) code to the asgi_startup and asgi_shutdown Django signals that are sent when the server starts/shuts down. See usage for a more advanced code sample.

    import asyncio
    
    import httpx
    
    HTTPX_CLIENT = None
    _signal_lock = asyncio.Lock()
    
    
    async def create_httpx_client():
        global HTTPX_CLIENT
    
        async with _signal_lock:
            if not HTTPX_CLIENT:
                HTTPX_CLIENT = httpx.AsyncClient()
    
    
    async def close_httpx_client():
        if isinstance(HTTPX_CLIENT, httpx.AsyncClient):
            await asyncio.wait_for(asyncio.create_task(HTTPX_CLIENT.aclose()), timeout=5.0)
    from django.apps import AppConfig
    
    from django_asgi_lifespan.signals import asgi_shutdown, asgi_startup
    from .handlers_quickstart import close_httpx_client, create_httpx_client
    
    
    class ExampleAppConfig(AppConfig):
        def ready(self):
            asgi_startup.connect(create_httpx_client)
            asgi_shutdown.connect(close_httpx_client)
  4. Use some resource (in this case the HTTPX client) e.g. in views.

    from django.http import HttpResponse
    
    from . import handlers
    
    
    async def my_library_view(*_) -> HttpResponse:
        external_api_response = await handlers_quickstart.HTTPX_CLIENT.get("https://www.example.com/")
    
        return HttpResponse(f"{external_api_response.text[:42]}", content_type="text/plain")
  5. Run uvicorn:

    ⚠️ Lifespan protocol is not supported if you run uvicorn via gunicorn using worker_class: gunicorn -k uvicorn.workers.UvicornWorker. See other limitations in the documentation.

    uvicorn asgi:application --lifespan=on --port=8080

About

Django ASGI handler with Lifespan Protocol support.

https://illagrenan.github.io/django-asgi-lifespan/

License:MIT License


Languages

Language:Python 100.0%