Skip to main content

dipin

dipin provides a dependency injection container, that primarily aims to work well with FastAPI.

Motivation

FastAPI's dependency container works well, but can be messy to scale. Out of the box, you can end up with many Annotated[X, Depends()]. Some projects I've worked on have a sprawling di.py, and references to Depends in non-FastAPI code.

dipin aims to:

  1. Remove the need to annotate types in non-FastAPI code with Depends,
  2. Provide a simple API to access dependencies in route-handlers, e.g.:
    from dipin import DI
    
    @app.get("/")
    async def homepage(request: Request, user: DI[AuthenticatedUser]):
        ...
    
    vs
    from .auth import get_authenticated_user
    
    @app.get("/")
    async def homepage(request: Request, user: Annotated[User, Depends(get_authenticated_user)]):
        ...
    

Architecture

TODO

Usage (alpha, buggy, will change)

# di.py

from dipin import DI

# Register a singleton across all requests
from .settings import Settings  # e.g. a pydantic-settings model
DI.register_instance(Settings())

# Register a factory (lazy singleton), called once across all requests
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.ext.asyncio.engine import AsyncEngine

def create_engine(settings: DI[Settings]) -> AsyncEngine:
    return create_async_engine(str(settings.database_dsn))

DI.register_factory(AsyncEngine, get_db_engine, create_once=True)

# Register a factory called per-request
from sqlmodel.ext.asyncio.session import AsyncSession
from sqlalchemy.ext.asyncio import async_sessionmaker

async def create_session(engine: DI[AsyncEngine]) -> AsyncSession:
    sessionmaker = async_sessionmaker(
        bind=engine, class_=AsyncSession, expire_on_commit=False
    )
    async with sessionmaker() as session:
        yield session

DI.register_factory(AsyncSession, create_session)
# app.py

from fastapi import FastAPI
from sqlmodel.ext.asyncio.session import AsyncSession

from dipin import DI

app = FastAPI()

@app.get("/")
async def list_orders(session: DI[AsyncSession]):
    qry = "SELECT * FROM orders"
    res = await session.exec(qry)
    orders = res.all()

    return {"orders": orders}

Roadmap

  • Support default arguments in factories
    • e.g. class A: def __init__(self, foo: str = "bar") should be instantiable.
  • Named dependencies
    • e.g. DI["PrivateOpenAIClient"]
    • Out of the box, it seems to lookup the class name (as a deferred annotation), but typing.Literal supports this.
  • Full typing support
    • Currently DI[Class] does not resolve to an instance of Class.
  • Support many types of dependencies
    • Including named (but we won't be able to use DI[...]), and some of those described in python-dependency-injector.
    • Providing our own fastapi.Depends is likely needed.

Metadata

Release files for dipin 0.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for dipin 0.0.3
File Size Uploaded Provenance
dipin-0.0.3.tar.gz 9.8 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for dipin 0.0.3
File Interpreter ABI Platform
dipin-0.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 17.4 kB

Release files / dipin-0.0.3.tar.gz

Download URL dipin-0.0.3.tar.gz
Size 9.8 kB
Tags Source
SHA-256 checksum
How to use checksums
85e0bc8ec7b509aa43ad53457543fb056e524d26fd290ade633f9067d7741578
BLAKE2b-256 checksum
How to use checksums
99d1e939eef6dd59033073191320c3cfed6a8b41da83ea359d579d1e56d1f802
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.0.0 CPython/3.12.4

Release files / dipin-0.0.3-py3-none-any.whl

Download URL dipin-0.0.3-py3-none-any.whl
Size 7.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
97c23d7b4cdd5eb2fcb34ee29313dfe9006018bc2a9a42b3ddb17136ed9f7236
BLAKE2b-256 checksum
How to use checksums
78eaee76432367d9432bcb997f26da1fcd07aa6f2bdb9d7a0619133c2350c087
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.0.0 CPython/3.12.4

Security for dipin 0.0.3

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

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