Skip to main content

aiodrf-asgi-lifespan

ASGI lifespan contexts and typed resource access for Django. It runs an async context manager for each server lifespan and gives requests its resource. It requires Python 3.12+ and Django 5.2+, and depends on neither Django REST framework nor django-aiodrf.

pip install aiodrf-asgi-lifespan

Usage

Write the resources as an async context manager:

# project/lifecycle.py
from contextlib import asynccontextmanager
from dataclasses import dataclass


@dataclass
class Resources:
    label: str


@asynccontextmanager
async def resources():
    # Open async clients here, and close them after the yield, with their
    # own context managers or a contextlib.AsyncExitStack.
    yield Resources(label="worker")

Name it in the DJANGO_LIFESPAN setting:

# settings.py
DJANGO_LIFESPAN = "project.lifecycle.resources"

and serve the application this package builds:

# project/asgi.py
import os

from aiodrf_asgi_lifespan.asgi import get_asgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "project.settings")
application = get_asgi_application()

The ASGI server must support the lifespan protocol and scope["state"]. Each server process, and each event loop, enters its own context. Requests receive a shallow copy of the server's state, so the resources themselves are shared within the lifespan.

A view reads the resource with its type:

from django.http import JsonResponse

from aiodrf_asgi_lifespan.asgi import get_lifespan_state
from project.lifecycle import Resources


async def status(request):
    resources = get_lifespan_state(request, Resources)
    return JsonResponse({"label": resources.label})

get_lifespan_state() checks the resource's type and that its context is still open: a request kept beyond shutdown cannot reach a closed resource. It accepts Django and DRF requests.

Other entry points

  • get_asgi_application(lifespan=factory) uses factory instead of the setting; lifespan=None runs no resource context.
  • LifespanApplication(application, lifespan=factory) wraps any other ASGI application without building Django's handler.
  • aiodrf_asgi_lifespan.signals.asgi_startup and asgi_shutdown are sent with Django's robust async dispatch: startup receivers run after the context is entered, shutdown receivers before it is closed. A failure in either is reported to the server. The signals work without a resource context too.

Testing

aiodrf_asgi_lifespan.testing.lifespan() runs startup and shutdown around a block and yields the lifespan state:

from aiodrf_asgi_lifespan.testing import lifespan


async def test_status():
    async with lifespan() as state:
        ...  # give `state` to an ASGI test client

With django-aiodrf, pass it to aiodrf.test.AsyncAPIClient(lifespan=state).

With django-aiodrf

Install django-aiodrf's lifespan extra. When AIODRF["REQUEST_THREADS"] is set, keep aiodrf.asgi.get_asgi_application(): it adds request thread reuse around this package's lifespan.

Contributing

See CONTRIBUTING.md.

Metadata

Release files for aiodrf-asgi-lifespan 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for aiodrf-asgi-lifespan 0.1.0
File Size Uploaded
aiodrf_asgi_lifespan-0.1.0.tar.gz 16.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for aiodrf-asgi-lifespan 0.1.0
File Interpreter ABI Platform
aiodrf_asgi_lifespan-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 25.5 kB

Release files / aiodrf_asgi_lifespan-0.1.0.tar.gz

Download URL aiodrf_asgi_lifespan-0.1.0.tar.gz
Size 16.0 kB
Tags Source
SHA-256 checksum
How to use checksums
1ac5381b534a997d6c976f80b1a4cace41f0298f740c58e918cfe4f101f08e90
BLAKE2b-256 checksum
How to use checksums
3ea542ea3c1ed9a2463620e5eb8e56dd857992bd068e69eaa985730d89095de5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / aiodrf_asgi_lifespan-0.1.0-py3-none-any.whl

Download URL aiodrf_asgi_lifespan-0.1.0-py3-none-any.whl
Size 9.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
36630bd33fef446bc976801ff49b5d57c5df9463b0734ad166ba52fbb875da6b
BLAKE2b-256 checksum
How to use checksums
29aa32aa4abb861635cf30d643a66de08662906489c2c39d5df0f6b5b830848a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page