aiosignal

A lightweight async callback registry that turns a mutable list of coroutine receivers into a frozen, awaitable dispatch signal.

Library
PyPI
v1.4.0
170 stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
78 /100 Good
Development Activity 96
Maintenance 72
Community 64
Maturity 60
Momentum 20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
73 /100 Good
Architecture 82
Code Quality 88
Innovation 45
Learning Curve 75

aiosignal provides a minimal, type-safe way to manage ordered lists of asynchronous callbacks in Python. Built as a thin subclass of frozenlist’s FrozenList, a Signal starts out mutable so callbacks can be registered with familiar list operations like append, then gets frozen to lock the registration phase closed before any callback fires. Once frozen, calling send() awaits every registered callback in order, giving library authors a small, well-tested primitive for exposing extension points without building their own event-dispatch machinery.

The library originated inside aiohttp, where it powers the web application’s on_startup, on_shutdown, and other lifecycle signals, and it has since become a standalone, widely depended-on part of the aio-libs ecosystem. Its entire implementation is a single module of roughly sixty lines with no runtime behavior beyond freeze/append/send, making it easy to audit and safe to pull in as a transitive dependency.

What You Get

  • Signal class - A FrozenList subclass that holds an ordered list of async callback references tied to an owner object.
  • Two-phase lifecycle - Callbacks are registered freely via standard list methods, then locked with freeze() so dispatch-time state can’t be mutated mid-flight.
  • Async dispatch via send() - Awaits every registered callback in registration order, passing the same positional and keyword arguments through to each.
  • Decorator registration - Signal instances are callable, so @signal can register a coroutine function directly as a receiver.
  • Full static typing - Ships a py.typed marker and uses PEP 646 variadic generics (TypeVarTuple) so callback argument types are checked end-to-end.

Common Use Cases

  • Framework lifecycle hooks - Web frameworks like aiohttp use Signal to implement on_startup, on_cleanup, and on_shutdown events that plugins can hook into.
  • Plugin/extension systems - Libraries expose a Signal as a public extension point so third-party packages can subscribe callbacks without modifying core code.
  • Decoupled event notification - Application code fires a frozen signal to notify multiple independent async listeners about a state change, in place of a hand-rolled callback list.
  • Middleware-style processing chains - Ordered async callbacks registered on a signal run in sequence, useful for request/response pipeline steps.

Under The Hood

Architecture aiosignal has almost no architecture to speak of by design: its entire public surface is the Signal class in aiosignal/__init__.py, which subclasses frozenlist.FrozenList and adds an _owner slot, an async send() method, and a __call__ decorator helper. There is no internal layering, no module boundary to cross, and no hidden state beyond the inherited frozen-list buffer and the owner reference stored for __repr__ output. The only meaningful control flow is the freeze/append/send lifecycle enforced by the parent FrozenList (which raises on mutation once frozen) and by send()’s own explicit RuntimeError guard when called on a non-frozen signal. Because the class owns no resources and holds no additional collaborators, changing this one abstraction is a breaking change for every downstream consumer (aiohttp foremost) rather than an internal refactor risk.

Tech Stack The package targets Python 3.10+ and depends on exactly one runtime library, frozenlist>=1.1.0, plus a conditional typing-extensions>=4.4 backport for TypeVarTuple/Unpack on Python versions below 3.11/3.13. It builds with a plain setuptools>=84 backend declared in pyproject.toml, with metadata (including version = attr: aiosignal.__version__) still living in setup.cfg. There are no web, database, or CLI frameworks involved — this is a pure language-level utility with no I/O and no external service integrations.

Code Quality Tests live in tests/test_signals.py and run under pytest with pytest-asyncio-style coroutine tests, covering positional/keyword dispatch, decorator registration, frozen-state mutation guards (append/setitem/delitem all raise RuntimeError once frozen), non-coroutine callback handling, and __repr__ formatting — a comprehensive suite relative to the module’s small surface area, run across the full supported Python matrix via tox. Type checking is strict: .mypy.ini enables disallow_untyped_defs, disallow_any_generics, warn_return_any, strict_equality, and several extra error codes, and the package ships a py.typed marker. CI (.github/workflows/ci-cd.yml) runs the test matrix plus a CodeQL security scan, and dependabot keeps dependencies current with an auto-merge workflow.

What Makes It Unique aiosignal doesn’t aim to be novel — it deliberately does one narrow thing (an ordered, freeze-then-dispatch list of async callbacks) and does it as a thin, auditable wrapper over an existing data structure rather than building a general event-bus or pub/sub system with topics, priorities, or error isolation. That restraint is its value: because it started as an internal implementation detail extracted from aiohttp’s own signal system, its API is shaped by a real, battle-tested framework use case, and its near-zero dependency footprint and readable single-file implementation make it a safe, low-risk transitive dependency for any async Python project that needs a similar extension-point primitive.

Used by 7 apps in this directory

Python
100%
Apache 2.0

Agno

AI Development · Automation · Devops

42,358

Build, run, and manage agent platforms with a full production stack — SDK, runtime, and control plane included.

View details
93
Repo Health
87
Technical
66
Dependency
Built with
Python 100%
Updated 1 weeks ago
Python
70%
Apache 2.0

GPT Researcher

AI Assistants · Productivity

29,650

The pioneering open-source autonomous AI agent that conducts deep, multi-source research and produces citation-backed reports exceeding 2,000 words — faster and more reliably than any human researcher.

View details
91
Repo Health
91
Technical
63
Dependency
Built with
Python 70%
TypeScript 18%
Updated 2 weeks ago
TypeScript
91%
Apache 2.0

Helicone

AI Development · Analytics · Monitoring

6,182

An open-source AI gateway and LLM observability platform that routes requests to 100+ models while logging cost, latency, and full traces for every call.

View details
70
Repo Health
81
Technical
65
Dependency
Built with
TypeScript 91%
Updated 3 weeks ago
Python
86%
Apache 2.0

knowhere

AI Development · AI Memory · Developer Tools

3,541

Transform messy, unstructured documents into persistent, navigable memory that AI agents can actually use.

View details
82
Repo Health
75
Technical
66
Dependency
Built with
Python 86%
HTML 14%
Updated 2 weeks ago
Python
62%
Apache 2.0

marimo

Data Engineering · Developer Tools

22,918

A reactive Python notebook that eliminates hidden state, runs reproducibly, and deploys as a web app or script — stored as pure Python, built for the AI era.

View details
89
Repo Health
91
Technical
65
Dependency
Built with
Python 62%
TypeScript 37%
Updated 1 weeks ago
Rust
63%
MIT

PostgresML

AI Development · Databases

6,825

Run ML training and LLM inference natively inside PostgreSQL with GPU acceleration — no data movement required.

View details
51
Repo Health
76
Technical
64
Dependency
Built with
Rust 63%
JavaScript 11%
Updated 1 years ago
Python
94%
Apache 2.0

SWIRL

Data Engineering · Databases · Search

3,047

Federated AI search and RAG across 100+ enterprise sources—no data extraction, no vector database required.

View details
62
Repo Health
83
Technical
65
Dependency
Built with
Python 94%
Updated 2 weeks ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers