Skip to main content

Canary Framework

Dependency injection and lifecycle for plain Python classes — standard library only, zero dependencies.

CI PyPI Python License

中文 · Documentation · Changelog

Install

pip install canary-framework

Requires Python 3.12 or newer. Installing pulls in no third-party packages.

The model

Subclass Canary and you have a unit: it declares what it depends on with dep(), and what it does in each phase with @init / @start / @stop. Start one unit and its dependencies come up in dependency order; leaving reclaims them in reverse.

import asyncio

from canary_framework import Canary, dep, init, start, stop


class Config(Canary):
    @init
    def load(self) -> None:
        self.dsn = "postgresql://localhost/dev"


class Database(Canary):
    config = dep(Config)

    @start
    async def connect(self) -> None:
        print(f"connecting to {self.config.dsn}")

    @stop
    async def close(self) -> None:
        print("disconnected")


class UserService(Canary):
    database = dep(Database)


async def main() -> None:
    async with UserService() as service:
        print(service.database.config.dsn)


asyncio.run(main())
connecting to postgresql://localhost/dev
postgresql://localhost/dev
disconnected

Two rules

Entering runs dependencies first: a unit enters a phase only after its dependencies have completed it. One unit runs one phase exactly once no matter how many units depend on it, and independent units enter concurrently.

Releasing runs the unit first: stopping a unit stops it — unless something still uses it — then tries its dependencies the same way, so what nothing else uses goes down with it. A failed start() releases what it brought up before it raises.

Both run on the dependency graph, built before any hook runs — which is also where cycles are caught.

init / start / stop are three names for these two rules. Adding a fourth phase is one line: Phase("migrate", after=init).

Highlights

  • Typed end to end. self.config is a Config, async with service yields your type, and dep(SomethingElse) is a type error. No plugin required.
  • Plain classes. Decorators only mark methods; units stay subclassable, mixable, nestable, and lifecycle methods can be overridden with super().
  • Failure paths are part of the design. A failing start() releases what it started; stop() is the single reclamation path, shared by success and failure, and is idempotent. A stopped graph starts again; a failed enter can be retried.
  • Test doubles without mocks. scope_of(service).provide(Database, FakeDatabase()) swaps a dependency across the whole graph, and the double runs its own lifecycle.
  • Concurrent by default. Independent units start together and stop together, scheduled by the dependency graph.
  • Zero dependencies. A test asserts that a full lifecycle imports nothing from site-packages.

Hosting

The framework knows nothing about shells — HTTP, CLI, schedulers and consumers are all yours:

@asynccontextmanager
async def lifespan(_app: FastAPI):
    async with service:
        yield


app = FastAPI(lifespan=lifespan)

Stability

1.0 is the first stable release. The public API follows Semantic Versioning: no breaking changes before 2.0, and removals are deprecated for at least one minor release first.

Documentation

Community

Questions and ideas go to Discussions, bugs to Issues. See CONTRIBUTING, GOVERNANCE and SECURITY.

License

Apache-2.0. See LICENSE.

Release files for canary-framework 1.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 canary-framework 1.1.0
File Size Uploaded
canary_framework-1.1.0.tar.gz 52.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for canary-framework 1.1.0
File Interpreter ABI Platform
canary_framework-1.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 84.1 kB

Release files / canary_framework-1.1.0.tar.gz

Download URL canary_framework-1.1.0.tar.gz
Size 52.1 kB
Tags Source
SHA-256 checksum
How to use checksums
05fa3872416d633770fbbd2177124377ca418dbb9decf96cab82eb847b459db5
BLAKE2b-256 checksum
How to use checksums
ea11802b88f397a48b01bafd8287f650d60cf1078a2a261f06c4524b42691249
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 Sep 23, 2026.

Transparency log

Release files / canary_framework-1.1.0-py3-none-any.whl

Download URL canary_framework-1.1.0-py3-none-any.whl
Size 32.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0797b7a5cac7d7219ee787b05e12ed41076fabcb0e6b8569b4d7d50bf7429e82
BLAKE2b-256 checksum
How to use checksums
48f8c44efda88d54d94df830248f383845e7a91d0df9b7adf5da7608981632b8
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 Sep 23, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.0 This release

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.10.0

2 release files

0.9.2

2 release files

0.9.1

2 release files

0.9.0

2 release files

0.6.1

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.13

2 release files

0.4.9

2 release files

0.4.8

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

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