Django ASGI handler with Lifespan Protocol support.
Project description
Django ASGI Handler with Lifespan protocol support
- Documentation: https://illagrenan.github.io/django-asgi-lifespan
- PyPI: https://pypi.org/project/django-asgi-lifespan/
- License: MIT
Features
- This package contains a subclass of the standard Django
ASGIHandler
that can handle ASGI Lifespan Protocol. (Note: there is no change in handling HTTP requests.) - Startup and Shutdown Lifespan events are converted to Django signals.
- Signal receivers can be awaited. This way it is possible for example to create aiohttp ClientSession /httpx client when the application starts and close these resources safely when the application shuts down. This concept is similar to events in FastAPI (https://fastapi.tiangolo.com/advanced/events/).
Quickstart
:warning: This package is experimental. Lifespan signals work correctly only under uvicorn.
-
To install this package run:
Python 3.10, 3.11 and 3.12 are supported, with Django 4 and 5.
$ pip install --upgrade django-asgi-lifespan # or $ poetry add django-asgi-lifespan@latest
-
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']}")
-
Subscribe your (async) code to the
asgi_startup
andasgi_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)
-
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")
-
Run uvicorn:
:warning: 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
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for django_asgi_lifespan-0.2.0.tar.gz
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6a39fb8ee4ad627fcfb5468c8b0bffe512b1dfe0e660ccb6bb356ae1063e4d62 |
|
MD5 | d1cc05201da92616573f0fe01fa1e04e |
|
BLAKE2b-256 | a3c86e60ccd1120057bedf4f1c2172068aa343a7a4020532f6b7fe118d3b8db5 |
Hashes for django_asgi_lifespan-0.2.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | f62f201eaa2a9d064eb24e3dd227a66a009f2b8cd79ea71ba7edc03cfbbbbd18 |
|
MD5 | fd1607061c0532106b52a924fadc2c26 |
|
BLAKE2b-256 | 695a5208e36adbd1271d9f7a703a5a9cce823d1e762fd404fa95971801bc53c1 |