{"id":13458901,"url":"https://github.com/reagento/dishka","last_synced_at":"2026-02-11T13:01:41.309Z","repository":{"id":217043856,"uuid":"742987819","full_name":"reagento/dishka","owner":"reagento","description":"Cute dependency injection (DI) framework for Python with agreeable API and everything you need","archived":false,"fork":false,"pushed_at":"2026-02-09T23:36:11.000Z","size":2150,"stargazers_count":1032,"open_issues_count":54,"forks_count":104,"subscribers_count":5,"default_branch":"develop","last_synced_at":"2026-02-10T00:06:16.324Z","etag":null,"topics":["dependency-injection","dependency-injector","di","di-container","di-framework","dishka","ioc-container","python"],"latest_commit_sha":null,"homepage":"https://dishka.readthedocs.io","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/reagento.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-01-14T00:42:06.000Z","updated_at":"2026-02-09T20:48:34.000Z","dependencies_parsed_at":"2024-05-02T19:48:44.928Z","dependency_job_id":"356963d9-6e11-4af4-a423-67c10103dba8","html_url":"https://github.com/reagento/dishka","commit_stats":null,"previous_names":["tishka17/dishka"],"tags_count":25,"template":false,"template_full_name":null,"purl":"pkg:github/reagento/dishka","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reagento%2Fdishka","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reagento%2Fdishka/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reagento%2Fdishka/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reagento%2Fdishka/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/reagento","download_url":"https://codeload.github.com/reagento/dishka/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/reagento%2Fdishka/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29333155,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T12:42:24.625Z","status":"ssl_error","status_checked_at":"2026-02-11T12:41:23.344Z","response_time":97,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dependency-injection","dependency-injector","di","di-container","di-framework","dishka","ioc-container","python"],"created_at":"2024-07-31T09:00:59.509Z","updated_at":"2026-02-11T13:01:41.273Z","avatar_url":"https://github.com/reagento.png","language":"Python","readme":"## Dishka (stands for \"cute DI\" in Russian)\n\n[![PyPI version](https://badge.fury.io/py/dishka.svg)](https://pypi.python.org/pypi/dishka)\n[![Supported versions](https://img.shields.io/pypi/pyversions/dishka.svg)](https://pypi.python.org/pypi/dishka)\n[![Downloads](https://img.shields.io/pypi/dm/dishka.svg)](https://pypistats.org/packages/dishka)\n[![License](https://img.shields.io/github/license/reagento/dishka)](https://github.com/reagento/dishka/blob/master/LICENSE)\n[![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/reagento/dishka/setup.yml)](https://github.com/reagento/dishka/actions)\n[![Doc](https://readthedocs.org/projects/dishka/badge/?version=latest\u0026style=flat)](https://dishka.readthedocs.io)\n[![Telegram](https://img.shields.io/badge/💬-Telegram-blue)](https://t.me/reagento_ru)\n\nCute DI framework with scopes and agreeable API.\n\n📚 [Documentation](https://dishka.readthedocs.io)\n\n### Purpose\n\nThis library provides **IoC container** that's genuinely useful.\nIf you're exhausted from endlessly passing objects just to create other objects, only to have those objects create even\nmore — you're not alone, and we have a solution.\nNot every project requires IoC container, but take a look at what we offer.\n\nUnlike other tools, Dishka focuses **only**\non [dependency injection](https://dishka.readthedocs.io/en/latest/di_intro.html) without trying to solve unrelated\ntasks.\nIt keeps DI in place without cluttering your code with global variables and scattered specifiers.\n\nTo see how Dishka **stands out** among other dependency injection tools, check out\nthe [detailed comparison](https://dishka.readthedocs.io/en/latest/alternatives.html).\n\n#### Key features:\n\n* **Scopes**. Any object can have a lifespan for the entire app, a single request, or even more fractionally. Many\n  frameworks either lack scopes completely or offer only two. Here, you can define as many scopes as needed.\n* **Finalization**. Some dependencies, like database connections, need not only to be created but also carefully\n  released. Many frameworks lack this essential feature.\n* **Modular providers**. Instead of creating many separate functions or one large class, you can split factories\n  into smaller classes for easier reuse.\n* **Clean dependencies**. You don't need to add custom markers to dependency code just to make it visible to the\n  library.\n* **Simple API**. Only a few objects are needed to start using the library.\n* **Framework integrations**. Popular frameworks are supported out of the box. You can simply extend it for your needs.\n* **Speed**. The library is fast enough that performance is not a concern. In fact, it outperforms many\n  alternatives.\n\nSee more in [technical requirements.](https://dishka.readthedocs.io/en/latest/requirements/technical.html)\n\n### Quickstart\n\n1. **Install Dishka.**\n\n```shell\npip install dishka\n```\n\n2. **Define your classes with type hints.** Imagine you have two classes: `Service` (business logic) and\n   `DAO` (data access), along with an external API client:\n\n```python\nclass DAO(Protocol):\n    ...\n\n\nclass Service:\n    def __init__(self, dao: DAO):\n        ...\n\n\nclass DAOImpl(DAO):\n    def __init__(self, connection: Connection):\n        ...\n\n\nclass SomeClient:\n    ...\n```\n\n3. **Create `Provider`** instance and specify how to provide dependencies.\n\nProviders are used only to set up factories providing your objects.\n\nUse `scope=Scope.APP` for dependencies created once for the entire application lifetime,\nand `scope=Scope.REQUEST` for those that need to be recreated for each request, event, etc.\nTo learn more about scopes, see [documentation.](https://dishka.readthedocs.io/en/latest/advanced/scopes.html)\n\n```python\nfrom dishka import Provider, Scope\n\n\nservice_provider = Provider(scope=Scope.REQUEST)\nservice_provider.provide(Service)\nservice_provider.provide(DAOImpl, provides=DAO)\nservice_provider.provide(SomeClient, scope=Scope.APP)  # override provider scope\n```\n\nTo provide a connection, you might need some custom code:\n\n```python\nfrom dishka import Provider, provide, Scope\n\n\nclass ConnectionProvider(Provider):\n    @provide(scope=Scope.REQUEST)\n    def new_connection(self) -\u003e Iterable[Connection]:\n        conn = sqlite3.connect(\":memory:\")\n        yield conn\n        conn.close()\n```\n\n4. **Create main `Container`** instance, passing providers, and enter `APP` scope.\n\n```python\nfrom dishka import make_container\n\n\ncontainer = make_container(service_provider, ConnectionProvider())\n```\n\n5. **Access dependencies using container.** Container holds a cache of dependencies and is used to retrieve them.\n   You can use `.get` method to access `APP`-scoped dependencies:\n\n```python\nclient = container.get(SomeClient)  # `SomeClient` has Scope.APP, so it is accessible here\nclient = container.get(SomeClient)  # same instance of `SomeClient`\n```\n\n6. **Enter and exit `REQUEST` scope repeatedly using a context manager**:\n\n```python\n# subcontainer to access shorter-living objects\nwith container() as request_container:\n    service = request_container.get(Service)\n    service = request_container.get(Service)  # same service instance\n# since we exited the context manager, the connection is now closed\n\n# new subcontainer to have a new lifespan for request processing\nwith container() as request_container:\n    service = request_container.get(Service)  # new service instance\n```\n\n7. **Close container** when done:\n\n```python\ncontainer.close()\n```\n\n8. Full code:\n\n```python\nimport sqlite3\nfrom collections.abc import Iterable\nfrom sqlite3 import Connection\nfrom typing import Protocol\n\nfrom dishka import Provider, Scope, make_container, provide\n\n\nclass DAO(Protocol): ...\n\n\nclass Service:\n    def __init__(self, dao: DAO): ...\n\n\nclass DAOImpl(DAO):\n    def __init__(self, connection: Connection): ...\n\n\nclass SomeClient: ...\n\n\nservice_provider = Provider(scope=Scope.REQUEST)\nservice_provider.provide(Service)\nservice_provider.provide(DAOImpl, provides=DAO)\nservice_provider.provide(\n    SomeClient,\n    scope=Scope.APP,\n)  # override provider scope\n\n\nclass ConnectionProvider(Provider):\n    @provide(scope=Scope.REQUEST)\n    def new_connection(self) -\u003e Iterable[Connection]:\n        conn = sqlite3.connect(\":memory:\")\n        yield conn\n        conn.close()\n\n\ncontainer = make_container(service_provider, ConnectionProvider())\n\nclient = container.get(\n    SomeClient,\n)  # `SomeClient` has Scope.APP, so it is accessible here\nclient = container.get(SomeClient)  # same instance of `SomeClient`\n\n# subcontainer to access shorter-living objects\nwith container() as request_container:\n    service = request_container.get(Service)\n    service = request_container.get(Service)  # same service instance\n# since we exited the context manager, the connection is now closed\n\n# new subcontainer to have a new lifespan for request processing\nwith container() as request_container:\n    service = request_container.get(Service)  # new service instance\n\ncontainer.close()\n```\n\n9. **Integrate with your framework.** If you are using a supported framework, add decorators and middleware for it.\n   For more details, see [integrations doc.](https://dishka.readthedocs.io/en/latest/integrations/index.html)\n\n```python\nfrom dishka.integrations.fastapi import (\n    FromDishka, inject, setup_dishka,\n)\n\n\n@router.get(\"/\")\n@inject\nasync def index(service: FromDishka[Service]) -\u003e str:\n    ...\n\n\n...\nsetup_dishka(container, app)\n```\n\n### Concepts\n\n**Dependency** is what you need for some parts of your code to work.\nDependencies are simply objects you don't create directly in place and might want to replace someday, at least for\ntesting purposes.\nSome of them live for the entire application lifetime, while others are created and destroyed with each request.\nDependencies can also rely on other objects, which then become their dependencies.\n\n**Scope** is the lifespan of a dependency. Standard scopes are (with some skipped):\n\n`APP` -\u003e `REQUEST` -\u003e `ACTION` -\u003e `STEP`.\n\nYou decide when to enter and exit each scope, but this is done one by one.\nYou set a scope for each dependency when you configure how it is created.\nIf the same dependency is requested multiple times within a single scope without leaving it, then by default the same\ninstance is returned.\n\nFor a web application, enter `APP` scope on startup and `REQUEST` scope for each HTTP request.\n\nYou can create a custom scope by defining your own `Scope` class if the standard scope flow doesn't fit your needs.\n\n**Container** is what you use to get your dependencies.\nYou simply call `.get(SomeType)` and it finds a way to provide you with an instance of that type.\nContainer itself doesn't create objects but manages their lifecycle and caches.\nIt delegates object creation to providers that are passed during creation.\n\n**Provider** is a collection of functions that provide concrete objects.\n`Provider` is a class with attributes and methods, each being the result of `provide`, `alias`, `from_context`, or\n`decorate`.\nThey can be used as provider methods, functions to assign attributes, or method decorators.\n\n`@provide` can be used as a decorator for a method.\nThis method will be called when the corresponding dependency has to be created.\nName doesn't matter: just make sure it's different from other `Provider` attributes.\nType hints do matter: they indicate what this method creates and what it requires.\nAll method parameters are treated as dependencies and are created using the container.\n\nIf `provide` is applied to a class, that class itself is treated as a factory (its `__init__` parameters are analyzed).\nRemember to assign this call to an attribute; otherwise, it will be ignored.\n\n**Component** is an isolated group of providers within the same container, identified by a unique string.\nWhen a dependency is requested, it is only searched within the same component as its direct dependant, unless explicitly\nspecified otherwise.\n\nThis structure allows you to build different parts of the application separately without worrying about using the same\ntypes.\n","funding_links":[],"categories":["Software","Python","Third-Party Extensions"],"sub_categories":["DI Frameworks / Containers","General"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freagento%2Fdishka","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Freagento%2Fdishka","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Freagento%2Fdishka/lists"}