asgiref
Async/sync bridging utilities and the reference toolkit behind the ASGI spec, maintained by the Django project.
Repository Health
Technical Analysis
asgiref is the Django project’s implementation of core ASGI (Asynchronous Server Gateway Interface) utilities — the plumbing that lets synchronous and asynchronous Python code call into each other safely. Its centerpiece is a pair of wrappers, async_to_sync and sync_to_async, that manage thread affinity, event-loop lifecycle, and context propagation so that calling code doesn’t have to reason about which thread or event loop it’s actually running on.
Beyond the sync/async bridge, the package ships a Local storage primitive that behaves like threading.local but stays coherent across the sync/async boundary (with a thread_critical mode for resources like database connections that must never leave their original thread), a WsgiToAsgi adapter that wraps existing WSGI applications so they can run inside an ASGI server, and a StatelessServer base class for building servers that manage per-connection scopes without holding raw sockets directly.
asgiref underpins Django’s async views and ORM, and is a transitive dependency of most of the modern Python async web ecosystem, including Channels, Uvicorn, and Starlette-adjacent tooling — despite being a small, dependency-free library that most developers never import directly.
What You Get
async_to_sync/sync_to_async— decorator-style wrappers that let synchronous code call async functions and vice versa, handling event-loop and thread-affinity bookkeeping automaticallyLocal— a threading.local-like namespace that stays coherent when execution moves between sync threads and async tasks, with athread_criticalmode for strictly thread-bound resourcesWsgiToAsgi— an adapter that wraps an existing WSGI application so it can run unmodified behind an ASGI serverStatelessServer— an abstract base class for building servers that manage per-connection scopes over external streams rather than raw socketsThreadSensitiveContext/AsyncSingleThreadContext— context managers for controlling which thread pool executes thread-sensitive synchronous code- A full companion
typingmodule with TypedDicts for ASGI scope and event dictionaries, plus the ASGI/Lifespan/WWW/TLS spec text mirrored underspecs/
Common Use Cases
- Calling synchronous, blocking code (e.g. a synchronous ORM call) from inside an async view or async framework without blocking the event loop
- Calling async code from synchronous entry points, such as Django’s synchronous middleware stack or management commands
- Wrapping a legacy WSGI application so it can be served by an ASGI-only server during a migration to async
- Building a custom ASGI-compliant server or protocol adapter on top of
StatelessServerinstead of implementing the scope-lifecycle contract from scratch - Keeping request-scoped state (like the current user or DB connection) correctly isolated when code hops between sync threadpool workers and the async event loop
Under The Hood
Architecture
asgiref is organized as a flat set of focused, single-purpose modules rather than layered subpackages — sync.py (667 lines) is the core, providing the AsyncToSync/SyncToAsync dual-mode callable wrappers built on contextvars.Context propagation; current_thread_executor.py supplies a CurrentThreadExecutor that lets a blocked synchronous thread service work items submitted from an async caller without deadlocking; and local.py layers a thread-tagged _Storage wrapper over contextvars to emulate threading.local semantics across the sync/async boundary, including a thread_critical mode for genuinely thread-bound resources like DB connections. wsgi.py’s WsgiToAsgi/WsgiToAsgiInstance classes are a thin adapter built entirely on the sync.py primitives, and server.py’s StatelessServer is an abstract per-connection-scope base class for building servers around external streams. There’s no dependency-injection or plugin system — the library is a handful of independent primitives that other projects (Django, Channels, Uvicorn) compose directly; changing the thread-affinity contract in sync.py or the re-homing logic in local.py would ripple through Django’s async view machinery and every downstream ASGI server.
Tech Stack
Pure Python 3.11+, with zero runtime dependencies — everything is stdlib (asyncio, contextvars, concurrent.futures, threading, contextlib). Packaging is plain setuptools (setup.py/setup.cfg, no pyproject.toml build backend), tests run under pytest + pytest-asyncio in strict asyncio mode, static typing is enforced with mypy --strict (with a short, explicit list of per-module exceptions for the trickiest concurrency internals), and linting runs through flake8 + isort (black-compatible profile). CI is GitHub Actions. The package is a transitive dependency of Django’s async layer, Channels, Uvicorn, and much of the modern async Python web stack.
Code Quality
An extensive test suite lives under tests/ (test_sync.py, test_local.py, test_wsgi.py, test_server.py, test_compatibility.py, test_garbage_collection.py, test_sync_contextvars.py, test_testing.py), exercising thread-affinity edge cases, executor garbage collection, and WSGI-adapter behavior. mypy runs in strict mode across the package, and typing.py provides a full companion TypedDict surface for ASGI scope/event dictionaries. Error handling is explicit and deliberate — CurrentThreadExecutor and the sync/async wrappers raise RuntimeError with specific, actionable messages rather than swallowing failures, and comments document non-obvious concurrency invariants (such as how _Storage re-homing interacts with Python 3.14’s thread_inherit_context). Naming is consistent and descriptive throughout, and CI runs the full suite on every change.
API Design
The public API centers on two wrapper callables, async_to_sync and sync_to_async, usable as plain function wrappers or as configurable decorators (@sync_to_async(thread_sensitive=False)), keeping the common case to one line while still exposing knobs for advanced thread-affinity control via ThreadSensitiveContext and AsyncSingleThreadContext. WsgiToAsgi requires no configuration to adapt an existing WSGI callable. Documentation is unusually thorough for a low-level primitives library — a dedicated Read the Docs site, the full ASGI spec text mirrored under specs/, and docstrings with runnable usage examples on every public class. The main friction is conceptual rather than mechanical: correctly reasoning about thread/task affinity when nesting sync_to_async and async_to_sync calls requires reading the README’s dedicated threading-model section, which the maintainers call out explicitly as a genuinely hard problem.
Used by 11 apps in this directory
Apache Airflow
Data Engineering
Define, schedule, and monitor complex data workflows as Python code — with a powerful UI, 80+ provider integrations, and battle-tested scalability across thousands of production deployments.
Baserow
No Code Platforms · Databases
Open-source no-code platform to build databases, apps, automations, and AI agents — self-hosted or cloud, with full data ownership.
Beta9
Developer Tools · AI Development · Data Engineering
Run AI workloads at scale with a Pythonic serverless runtime that handles GPU inference, background jobs, and sandboxes with zero infrastructure overhead.
Flagsmith
Developer Tools · Devops · Ab Testing Experimentation
Open-source feature flagging, remote config, and A/B/multivariate testing platform for web, mobile, and server-side apps — self-host or use the hosted SaaS.
Horilla
Human Resources · ERP
Open-source HRMS covering recruitment, attendance, payroll, and biometrics in one self-hosted Django application.
knowhere
AI Development · Developer Tools
Transform messy, unstructured documents into persistent, navigable memory that AI agents can actually use.
Open WebUI
AI Assistants · AI Agents
The extensible, privacy-first AI platform that runs Ollama, OpenAI, and any LLM backend behind a polished, feature-packed web interface.
Phase Console
Security · Devops
End-to-end encrypted secrets management for engineering teams — from local dev to Kubernetes production.
PostHog
Analytics · Monitoring · Developer Tools
The all-in-one open source product platform combining analytics, session replay, feature flags, error tracking, AI observability, and a built-in data warehouse in a single self-hostable stack.