Skip to content

antonrh/anydi

Repository files navigation

AnyDI

Modern, lightweight Dependency Injection library using type annotations.

CI Coverage Documentation


Documentation

http://anydi.readthedocs.io/


AnyDI is a modern, lightweight Dependency Injection library suitable for any synchronous or asynchronous applications with Python 3.8+, based on type annotations (PEP 484).

The key features are:

  • Type-safe: Resolves dependencies using type annotations.
  • Async Support: Compatible with both synchronous and asynchronous providers and injections.
  • Scoping: Supports singleton, transient, and request scopes.
  • Easy to Use: Designed for simplicity and minimal boilerplate.
  • Named Dependencies: Supports named dependencies using Annotated type.
  • Resource Management: Manages resources using context managers.
  • Modular: Facilitates a modular design with support for multiple modules.
  • Scanning: Automatically scans for injectable functions and classes.
  • Integrations: Provides easy integration with popular frameworks and libraries.
  • Testing: Simplifies testing by allowing provider overrides.

Installation

pip install anydi

Quick Example

app.py

from anydi import auto, Container

container = Container()


@container.provider(scope="singleton")
def message() -> str:
    return "Hello, world!"


@container.inject
def say_hello(message: str = auto) -> None:
    print(message)


if __name__ == "__main__":
    say_hello()

FastAPI Example

app.py

from fastapi import FastAPI

import anydi.ext.fastapi
from anydi import Container
from anydi.ext.fastapi import Inject

container = Container()


@container.provider(scope="singleton")
def message() -> str:
    return "Hello, World!"


app = FastAPI()


@app.get("/hello")
def say_hello(message: str = Inject()) -> dict[str, str]:
    return {"message": message}


# Install the container into the FastAPI app
anydi.ext.fastapi.install(app, container)

Django Ninja Example

container.py

from anydi import Container


def get_container() -> Container:
    container = Container()

    @container.provider(scope="singleton")
    def message() -> str:
        return "Hello, World!"

    return container

settings.py

INSTALLED_APPS = [
    ...
    "anydi.ext.django",
]

ANYDI = {
    "CONTAINER_FACTORY": "myapp.container.get_container",
    "PATCH_NINJA": True,
}

urls.py

from django.http import HttpRequest
from django.urls import path
from ninja import NinjaAPI

from anydi import auto

api = NinjaAPI()


@api.get("/hello")
def say_hello(request: HttpRequest, message: str = auto) -> dict[str, str]:
    return {"message": message}


urlpatterns = [
    path("api/", api.urls),
]