Skip to main content

oapi-gen-dishka

Inject Dishka dependencies into the async methods called by an oapi-gen router. Generated code stays unchanged. The integration reuses Dishka's native Starlette request container, so operation handlers, security handlers, and ordinary Starlette endpoints share the same Scope.REQUEST instances.

This directory is an independently buildable package. Install it into your application from a local checkout:

uv add /path/to/oapi-gen/integrations/dishka

Usage

The example uses the repository's complete Cats specification. Generate it into your application's package:

oapi-gen generate tests/fixtures/cats.openapi.yaml --output app/http/generated
from contextlib import asynccontextmanager
from uuid import UUID, uuid4

from dishka import FromDishka, Provider, Scope, make_async_container, provide
from starlette.applications import Starlette
from oapi_gen_dishka import inject, setup_dishka

from app.http.generated import Handlers, contracts, create_router, models


class CatsRepository:
    def __init__(self):
        self.cats: dict[UUID, models.Cat] = {}


class CatsController:
    @inject
    async def list_cats(
        self,
        request: contracts.ListCatsRequest,
        *,
        repository: FromDishka[CatsRepository],
    ) -> contracts.ListCatsResponse:
        cats = list(repository.cats.values())
        return contracts.ListCatsResponse200(body=cats[: request.limit])

    @inject
    async def create_cat(
        self,
        request: contracts.CreateCatRequest,
        *,
        repository: FromDishka[CatsRepository],
    ) -> contracts.CreateCatResponse:
        cat = models.Cat(id=uuid4(), name=request.body.name)
        repository.cats[cat.id] = cat
        return contracts.CreateCatResponse201()

    @inject
    async def show_cat_by_id(
        self,
        request: contracts.ShowCatByIdRequest,
        *,
        repository: FromDishka[CatsRepository],
    ) -> contracts.ShowCatByIdResponse:
        cat = repository.cats.get(request.cat_id)
        if cat is None:
            return contracts.ShowCatByIdResponse404(
                body=models.HttpError(message="Cat not found"),
            )
        return contracts.ShowCatByIdResponse200(body=cat)


class AppProvider(Provider):
    # This in-memory example keeps cats between requests in one process.
    repository = provide(CatsRepository, scope=Scope.APP)


container = make_async_container(AppProvider())


@asynccontextmanager
async def lifespan(app: Starlette):
    try:
        yield
    finally:
        await container.close()


router = create_router(Handlers(cats=CatsController()), prefix="/api")
app = Starlette(lifespan=lifespan, routes=router.routes)
setup_dishka(container, app)

Use Scope.REQUEST for services or database sessions that must be recreated for each request. Dishka resolves dependencies from the normal provider graph and finalizes generator providers at the end of the request, including on exceptions. Add Dishka's StarletteProvider() from dishka.integrations.starlette when a provider needs starlette.requests.Request.

@inject also works on generated security handler methods. Use dishka.integrations.starlette.inject on ordinary Starlette endpoints; both decorators resolve from the same container after the single setup call above.

Boundaries

  • Async HTTP handlers only. WebSockets, sync containers, and background work outside the request lifetime are not supported by this decorator.

  • Call this package's setup_dishka once, before startup, instead of calling dishka.integrations.starlette.setup_dishka separately.

  • The controller instance passed to Handlers is shared. Keep request-specific state in local variables and injected dependencies, not on self.

  • Providers must register dependencies; FromDishka[T] selects the registered type and does not register it automatically. Dishka components are supported.

  • Runtime signatures omit injected parameters and retain the remaining annotations. The decorator preserves the static response type but uses Callable[..., ...] for arguments, since Python typing cannot remove arbitrary FromDishka parameters. Annotate controller references with the generated protocol when calling them directly to check request argument types:

    controller: contracts.CatsApi = CatsController()
    

Development

uv sync --project integrations/dishka
uv run --project integrations/dishka pytest integrations/dishka/tests
uv run --project integrations/dishka ruff check integrations/dishka
uv run --project integrations/dishka basedpyright --project integrations/dishka
uv build integrations/dishka --out-dir integrations/dishka/dist

The local development dependency on oapi-gen is used only for integration tests; the published wheel does not depend on the generator at runtime.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

oapi_gen_dishka-0.1.0.tar.gz (8.8 kB view details)

Uploaded Source

Built Distribution

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

oapi_gen_dishka-0.1.0-py3-none-any.whl (4.9 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: oapi_gen_dishka-0.1.0.tar.gz
  • Upload date:
  • Size: 8.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for oapi_gen_dishka-0.1.0.tar.gz
Algorithm Hash digest
SHA256 41843058f3dee15be65de787d97ba5da46e6ab61dc7d01c8f49d578560073a9c
MD5 b9a7ce0e90301d8ccfcdeb887e17e887
BLAKE2b-256 a0f244ae83e64bbfc5b085a13b1e20b78a04cc4ba0d9255a2d3e090e3ae1e355

See more details on using hashes here.

File details

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

File metadata

  • Download URL: oapi_gen_dishka-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 4.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.21 {"installer":{"name":"uv","version":"0.11.21","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for oapi_gen_dishka-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1cde415d5afff1083a9ecaaea1140d8ac5a59dca27d08957a24b99359890ba5b
MD5 036d49c3f4855eefe67e1c892e53155f
BLAKE2b-256 c4292c63e7f6b6fbdc5b2b6f39a61062d16a330a2aab251bf18989730ee3e178

See more details on using hashes here.

Release history Release notifications | RSS feed

0.1.9

2 files

0.1.2

2 files

This release

0.1.0 This release

2 files

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