Skip to main content

Modern Async DI Container for Python 3.14+

Project description

🎧 dijay

dijay is a high-performance, asynchronous Dependency Injection (DI) library for Python 3.14+, heavily inspired by the NestJS ecosystem. Built for strict typing and speed, it leverages the latest Python features (PEP 649, 695) and is optimized for uv.

🚀 Features

  • Constructor Injection: Clean, testable injection via __init__ and Annotated.
  • Flexible Scopes: Support for SINGLETON, TRANSIENT, and REQUEST.
  • Async Native: First-class support for asynchronous factories and lifecycle hooks.
  • Scope Bubbling: Intelligent lifetime management to prevent stale references.
  • Lifecycle Hooks: Simple @on_bootstrap and @on_shutdown decorators.
  • Zero Config: Powerful autowiring based on Type Hints.

📦 Installation

uv add dijay

⚡ Quick Start

from typing import Annotated
from dijay import inject, resolve, Inject

class Base: pass

@inject(Base)
class Implementation(Base):
    pass

@inject()
class Controller:
    def __init__(self, service: Base):
        self.service = service

async def main():
    app = await resolve(Controller)

🫧 Scope Bubbling

dijay implements automatic scope elevation (bubbling). If a provider with a wider lifetime (e.g., SINGLETON) depends on a provider with a narrower lifetime (e.g., REQUEST), the container automatically treats the dependent as having the narrower scope.

This prevents Scope Leaks, ensuring that a Singleton never captures and holds onto a stale Request-scoped instance.

🌐 FastAPI Integration

To integrate dijay with FastAPI, use a dependency to manage request-scoped resolution:

from fastapi import FastAPI, Request, Depends
from dijay import resolve, instance

app = FastAPI()
container = instance()

async def get_service[T](token: type[T]):
    async def _resolve(request: Request) -> T:
        return await container.resolve(token, id=str(id(request)))
    return _resolve

@app.get("/")
async def root(service: Annotated[MyService, Depends(get_service(MyService))]):
    return await service.do_something()

💉 Advanced Constructor Injection

The library leverages Annotated to decouple type hints from injection tokens, similar to the NestJS @Inject() decorator.

from typing import Annotated
from dijay import Inject, inject

@inject()
class Persistence:
    def __init__(
        self, 
        conn_string: Annotated[str, Inject("DB_CONNECTION")]
    ):
        self.conn = conn_string

🛠️ Development

  1. Sync Environment: uv sync
  2. Run Tests: uv run pytest
  3. Build Package: uv build

🔄 Circular Dependency Detection

dijay actively monitors the resolution stack. If a cycle is detected (e.g., A -> B -> A), a RuntimeError is raised immediately to prevent stack overflow.

📄 License

MIT

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

dijay-0.1.0.tar.gz (19.1 kB view details)

Uploaded Source

Built Distribution

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

dijay-0.1.0-py3-none-any.whl (7.3 kB view details)

Uploaded Python 3

File details

Details for the file dijay-0.1.0.tar.gz.

File metadata

  • Download URL: dijay-0.1.0.tar.gz
  • Upload date:
  • Size: 19.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dijay-0.1.0.tar.gz
Algorithm Hash digest
SHA256 01c072da37e6cc23f6bd986a508f8dc56bc75935fa4ddff623a137de3dacf17c
MD5 b5963584fa287ac61bb7f8da4e90946b
BLAKE2b-256 354b8ab2e5860d88775e7a1b76d20510c8abd30c183802592cfc928241b87078

See more details on using hashes here.

File details

Details for the file dijay-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: dijay-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 7.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for dijay-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 67c1ce7ba2e07d78bb95ecbc95ed5579040ad1b987ff4dfcdd4fd6eedd209684
MD5 3e1ccb7ebed7e3d82c655bcadd0550c6
BLAKE2b-256 23ff86ffce005eaeb8c2788160608a2f2a0b7f6523a440fbe6ea2113f4c71f43

See more details on using hashes here.

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