Skip to main content

Canary Framework — lightweight decorator-driven Python service framework

Project description

Canary Framework

Lightweight Python Service Framework — Decorator-Driven, Zero Boilerplate

License Python


Canary Framework is a decorator-driven service framework. Core philosophy: Services are the minimum unit. Modules compose services. Modules themselves are also services.

Features

  • Decorator API@service / @module, no base class inheritance needed
  • Topological Startup — Kahn's algorithm ensures dependencies start first
  • Dependency Injectiondeps=[DBService] auto-injected as self.db_service
  • Config Management — pydantic-settings + app.config(config=...), auto-reads .env and env vars
  • Lifecycle Hooks@on_config / @on_init / @on_start / @on_end, sync/async adaptive
  • Web IntegrationWebCanary for one-click FastAPI + Uvicorn
  • Log Sanitization — sensitive config fields (password, secret, token) automatically masked

Installation

pip install canary-framework          # core library
pip install canary-framework[web]     # with FastAPI support

Quick Start

import asyncio
from canary_framework import service, module, on_start, Canary

@service(name="hello")
class HelloService:
    @on_start
    def start(self) -> None:
        print("Hello from Canary!")

@module(name="App", services=[HelloService])
class App:
    pass

async def main() -> None:
    app = Canary(App)
    await app.config()
    await app.init()
    await app.start()

asyncio.run(main())

Web Example

import asyncio
from pydantic import BaseModel
from canary_framework import service, module, on_config, on_start, Canary
from canary_framework.web.fastapi import router, get, WebCanary

class DBConfig(BaseModel):
    connection_string: str = "postgresql://localhost/mydb"
    pool_size: int = 10

class AppConfig(BaseModel):
    uvicorn_host: str = "127.0.0.1"
    uvicorn_port: int = 8000
    fastapi_title: str = "My API"
    dbservice: DBConfig = DBConfig()

@service(name="dbservice")
class DBService:
    @on_config
    def setup(self) -> None:
        print(f"DB ready at {self.connection_string}")

@router(prefix="/api", tags=["api"])
class APIRouter:
    @get("/hello")
    async def hello(self) -> dict:
        return {"message": "Hello, world!"}

@module(name="AppModule", services=[APIRouter, DBService])
class AppModule:
    pass

async def main() -> None:
    app = WebCanary(AppModule)
    await app.config(config=AppConfig())
    await app.init()
    await app.start()

asyncio.run(main())

Documentation

📖 Full documentation: Canary Framework Docs

中文文档: docs/zh/ · English: docs/en/

Architecture

src/canary_framework/
├── common/                  # Shared types, enums, exceptions, logging
├── core/
│   ├── decorators/          # @service, @module, lifecycle hooks
│   ├── conductor/           # Canary engine (lifecycle orchestrator)
│   ├── container/           # Registry (service storage/lookup)
│   └── algorithms/          # Topological sort, DI injector, naming
└── web/
    └── fastapi/             # WebCanary engine, @router, @get/@post/...
Canary.config()
  ├── _collect()            recursively discover @service/@module
  ├── _validate()           validate dependency integrity
  ├── topological_sort()    Kahn topological sort
  ├── instantiate()         create all service instances
  ├── _wire_entry()         DI + config injection + sub-service injection
  └── on_config hooks       (topological order)
Canary.init()
  └── per topology: on_init()
Canary.start()
  └── per topology: on_start()
Canary.stop()
  └── reverse order: on_end()

Community

Contributing

See CONTRIBUTING.md.

License

Apache 2.0 · Copyright 2026 张文博 (Canary)

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

canary_framework-0.4.0.tar.gz (59.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

canary_framework-0.4.0-py3-none-any.whl (33.0 kB view details)

Uploaded Python 3

File details

Details for the file canary_framework-0.4.0.tar.gz.

File metadata

  • Download URL: canary_framework-0.4.0.tar.gz
  • Upload date:
  • Size: 59.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for canary_framework-0.4.0.tar.gz
Algorithm Hash digest
SHA256 213a15c6283defa8b06cb23e0649a28c32241194bca2d03202a8a0afab3298e2
MD5 6db3c8649d8acfaa37b822fbd489aaaf
BLAKE2b-256 36cff15178cf5d6e6423965804b9364a10137b92f9ba61b1e0e5b157cc1a4194

See more details on using hashes here.

Provenance

The following attestation bundles were made for canary_framework-0.4.0.tar.gz:

Publisher: publish.yml on HotcocoaCanary/Canary-Framework

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file canary_framework-0.4.0-py3-none-any.whl.

File metadata

File hashes

Hashes for canary_framework-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 de71aafbabb71d6752aec9b1aa617c4f1ccf4ef9d05ba648a29bc8c68ee2fd37
MD5 8ece08c464ef83e27812158b12541e49
BLAKE2b-256 13197cd0e1b270995914f478e7a572e436a55e27c2d57d715adfb3c2f22e9f9e

See more details on using hashes here.

Provenance

The following attestation bundles were made for canary_framework-0.4.0-py3-none-any.whl:

Publisher: publish.yml on HotcocoaCanary/Canary-Framework

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page