action0-service

A lightweight service registry and dependency injection framework: register classes, factories, or ready-made instances — by type or by name — and request them back with their constructor dependencies resolved automatically. Scopes (singleton, transient, thread-local, context-local), YAML service definitions, and a test-friendly override mechanism included. The core has zero dependencies.

Requires Python 3.11 or newer.

pip install action0-service          # or: uv add action0-service
pip install "action0-service[yaml]"  # with YAML support (PyYAML)

A taste

from action0.service import Registry, Scope


class Database:
    def __init__(self, dsn: str = "sqlite://"):
        self.dsn = dsn


class UserRepository:
    def __init__(self, db: Database):  # injected from the registry
        self.db = db


registry = Registry()
registry.register(Database, params={"dsn": "postgres://db/app"})
registry.register(UserRepository)

repo = registry.get(UserRepository)
assert repo.db.dsn == "postgres://db/app"
assert registry.get(UserRepository) is repo  # singletons by default

There is no global registry and no import-time magic: a Registry is an ordinary object you create, fill, and pass around (or nest, see parent registries).

Where to go next

  • Registering services — classes, factories, instances, names, and the @registry.service decorator.

  • Looking services up — lookups by type (subclass-aware) and by name, and how ambiguity is resolved.

  • Injection — the exact rules for filling constructor parameters, the Named qualifier, Ref values, and the @registry.inject function decorator.

  • Scopes — singleton, transient, thread, context, and writing custom scopes.

  • Parent registries and overrides — layered wiring for requests and tests.

  • YAML service definitions — the full file format, !ENV and !ref tags.

  • Lifecyclevalidate(), warmup(), close().

  • API reference — every public class and function.

Project

This library is developed with heavy use of AI coding tools: the code, tests, and documentation are largely written by Claude Code, working from the author’s design brief and reviewed by the author. If that changes how much you want to rely on this package, that’s a fair call — read the source, it’s small.