or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

component-system.mdcontainer-management.mdframework-integrations.mdindex.mdprovider-system.mdscope-lifecycle.mdtype-markers.mdvalidation-configuration.md
tile.json

tessl/pypi-dishka

Cute DI framework with scopes and agreeable API for Python dependency injection

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
pypipkg:pypi/dishka@1.6.x

To install, run

npx @tessl/cli install tessl/pypi-dishka@1.6.0

index.mddocs/

Dishka

A comprehensive Python dependency injection framework designed for applications that need sophisticated object lifecycle management and clean dependency handling. Dishka provides advanced scoping capabilities, automatic finalization for resources, modular provider architecture, and seamless integration with popular Python frameworks.

Package Information

  • Package Name: dishka
  • Language: Python
  • Installation: pip install dishka
  • Requirements: Python >=3.10

Core Imports

import dishka

Common usage imports:

from dishka import Container, Provider, Scope, make_container
from dishka import provide, alias, decorate, from_context
from dishka import FromDishka, FromComponent

Framework integration imports:

from dishka.integrations.fastapi import setup_dishka, inject, FromDishka
from dishka.integrations.flask import setup_dishka, inject, FromDishka
from dishka.integrations.aiohttp import setup_dishka, inject, FromDishka

Basic Usage

from dishka import Provider, Scope, make_container, provide
from typing import Protocol

# Define your interfaces and classes
class Database(Protocol):
    def execute(self, query: str) -> list: ...

class PostgreSQLDatabase:
    def __init__(self, connection_string: str):
        self.connection_string = connection_string
    
    def execute(self, query: str) -> list:
        # Implementation here
        return []

class UserService:
    def __init__(self, db: Database):
        self.db = db
    
    def get_users(self) -> list:
        return self.db.execute("SELECT * FROM users")

# Create provider
provider = Provider()
provider.provide(PostgreSQLDatabase, provides=Database, scope=Scope.APP)
provider.provide(UserService, scope=Scope.REQUEST)

@provider.provide(scope=Scope.APP)
def get_connection_string() -> str:
    return "postgresql://localhost/mydb"

# Create container
container = make_container(provider)

# Use dependencies
with container() as request_container:
    user_service = request_container.get(UserService)
    users = user_service.get_users()

container.close()

Architecture

Dishka's architecture is built around several key concepts:

  • Container: Central registry that manages dependency creation and lifecycle, with support for both sync and async operations
  • Provider: Modular units that define how dependencies are created, allowing clean separation of factory logic
  • Scope: Hierarchical lifecycle management (APP → REQUEST → ACTION → STEP) with automatic cleanup
  • Component: Isolation system that allows multiple implementations of the same interface to coexist
  • Registry: Internal dependency graph that validates and optimizes dependency resolution at startup

This design enables complex applications to maintain clean dependency boundaries while providing high performance and comprehensive lifecycle management.

Capabilities

Container Management

Core container functionality for creating, configuring, and managing dependency injection containers with lifecycle management and scope handling.

def make_container(*providers, scopes=Scope, context=None, skip_validation=False) -> Container: ...
def make_async_container(*providers, scopes=Scope, context=None, skip_validation=False) -> AsyncContainer: ...
class Container:
    def get(self, dependency_type: type[T], component: str = "") -> T: ...
    def __call__(self, context=None, scope=None) -> ContextManager[Container]: ...
    def close(self, exception=None) -> None: ...

class AsyncContainer:
    async def get(self, dependency_type: type[T], component: str = "") -> T: ...
    def __call__(self, context=None, scope=None) -> AsyncContextManager[AsyncContainer]: ...
    async def close(self, exception=None) -> None: ...

Container Management

Provider System

Modular provider classes and dependency registration functions for creating reusable dependency factories with flexible configuration options.

class Provider:
    def __init__(self, scope: BaseScope = None, component: str = None): ...
    def provide(self, source, *, scope=None, provides=None, cache=True) -> None: ...
    def alias(self, source, *, provides=None, cache=True, component=None) -> None: ...

def provide(*, scope=None, provides=None, cache=True, recursive=False, override=False): ...
def alias(source, *, provides=None, cache=True, component=None, override=False): ...
def decorate(*, provides=None): ...
def from_context(provides, *, scope=None, override=False): ...

Provider System

Scope and Lifecycle Management

Hierarchical scope system for managing dependency lifetimes from application-wide to per-request or custom granular levels.

class Scope(BaseScope):
    RUNTIME: ClassVar[Scope]
    APP: ClassVar[Scope] 
    SESSION: ClassVar[Scope]
    REQUEST: ClassVar[Scope]
    ACTION: ClassVar[Scope]
    STEP: ClassVar[Scope]

class BaseScope:
    name: str
    skip: bool

def new_scope(value: str, *, skip: bool = False) -> BaseScope: ...

Scope and Lifecycle Management

Type Markers and Injection

Type annotation markers and dependency key system for clean type-safe dependency injection without polluting business logic code.

class FromDishka[T]:
    """Type marker for dependency injection"""
    pass

class FromComponent:
    def __call__(self, component: str = "") -> FromComponent: ...

class AnyOf[*Args]:
    """Marker for multiple possible dependency types"""
    pass

class WithParents[T]:
    """Automatically provide all parent classes/interfaces"""
    pass

class DependencyKey:
    type_hint: Any
    component: str | None
    def with_component(self, component: str) -> DependencyKey: ...

Type Markers and Injection

Framework Integrations

Ready-to-use integrations for popular Python frameworks with automatic dependency injection setup and middleware configuration.

# Common pattern across integrations
def setup_dishka(container: Container, app: Any) -> None: ...
def inject(func: Callable) -> Callable: ...

Available integrations: FastAPI, Flask, Starlette, AIOhttp, Sanic, Litestar, gRPCio, Celery, Aiogram, Click, TaskIQ, FastStream, Telebot, ARQ

Framework Integrations

Component System

Multi-component dependency isolation system allowing different implementations of the same interface to coexist within a single container.

Component = str
DEFAULT_COMPONENT: str = ""

Component System

Validation and Configuration

Comprehensive validation system for dependency graphs with configurable validation rules and error detection.

class ValidationSettings:
    nothing_overridden: bool = False
    implicit_override: bool = False
    nothing_decorated: bool = True

STRICT_VALIDATION: ValidationSettings

Validation and Configuration

Types

T = TypeVar('T')
Component = str
DEFAULT_COMPONENT: str = ""

class DependencyKey(NamedTuple):
    type_hint: Any
    component: Component | None
    
    def with_component(self, component: Component) -> DependencyKey: ...
    def __str__(self) -> str: ...

class ValidationSettings:
    nothing_overridden: bool
    implicit_override: bool  
    nothing_decorated: bool

STRICT_VALIDATION: ValidationSettings
DEFAULT_VALIDATION: ValidationSettings

class BaseScope:
    name: str
    skip: bool