{"id":23790232,"url":"https://github.com/pilagod/deppy","last_synced_at":"2025-09-06T08:31:29.665Z","repository":{"id":62567729,"uuid":"343616390","full_name":"pilagod/deppy","owner":"pilagod","description":"Dependency injection framework for Python","archived":false,"fork":false,"pushed_at":"2021-03-08T08:17:52.000Z","size":18,"stargazers_count":7,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-12-05T13:07:57.963Z","etag":null,"topics":["dependency-injection","di","di-container","di-framework","inversion-of-control","ioc","ioc-container","ioc-framework","python","python3"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pilagod.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-03-02T02:05:44.000Z","updated_at":"2021-08-29T09:15:27.000Z","dependencies_parsed_at":"2022-11-03T16:30:25.341Z","dependency_job_id":null,"html_url":"https://github.com/pilagod/deppy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pilagod%2Fdeppy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pilagod%2Fdeppy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pilagod%2Fdeppy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pilagod%2Fdeppy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pilagod","download_url":"https://codeload.github.com/pilagod/deppy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232105452,"owners_count":18473304,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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","di","di-container","di-framework","inversion-of-control","ioc","ioc-container","ioc-framework","python","python3"],"created_at":"2025-01-01T17:20:14.064Z","updated_at":"2025-01-01T17:20:15.555Z","avatar_url":"https://github.com/pilagod.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# deppy [![Build Status](https://travis-ci.com/pilagod/deppy.svg?branch=master)](https://travis-ci.com/pilagod/deppy) [![Coverage Status](https://coveralls.io/repos/github/pilagod/deppy/badge.svg?branch=master)](https://coveralls.io/github/pilagod/deppy?branch=master)\n\nDependency injection framework for Python\n\n## Installation\n\n```shell\n$ pip install deppy\n```\n\n## Usage\n\n### Concrete class\n\n```python\nfrom deppy import container, injectable\n\n@injectable()\nclass Greeter:\n    def greet(self) -\u003e str:\n        return \"Hello\"\n\ng = container.get(Greeter)\ng.greet() # Hello\n```\n\n### Implementation for abstract class\n\n```python\nimport abc\n\nfrom deppy import container, injectable\n\n# Should raise NotImplementedError instead of abc.abstractmethod decorator for abstract method due to following mypy issue:\n# https://github.com/python/mypy/issues/5374#issuecomment-582093112\nclass Greeter(abc.ABC):\n    def greeter(self) -\u003e str:\n        raise NotImplementedError()\n\n@injectable(Greeter)\nclass GreeterImpl(Greeter):\n    def greeter(self) -\u003e str:\n        return \"Hello\"\n\ng = container.get(Greeter)\ng.greet() # Hello\n\n# If class is on behalf of abstract class, the class cannot get by itself from container\n# check `Multiple implementations` section for more complex use case.\ncontainer.get(GreeterImpl) # KeyError\n```\n\n### Multiple implementations\n\n```python\nimport abc\n\nfrom enum import Enum\n\nfrom deppy from container, injectable\n\nclass Greeter(abc.ABC):\n    def greet(self) -\u003e str:\n        raise NotImplementedError()\n\nclass GreeterType(Enum):\n    A = \"A\"\n    B = \"B\"\n\n@injectable(Greeter, tag=GreeterType.A)\nclass GreeterA(Greeter):\n    def greet(self) -\u003e str:\n        return \"A\"\n\n@injectable(Greeter, tag=GreeterType.B)\nclass GreeterB(Greeter):\n    def greet(self) -\u003e str:\n        return \"B\"\n\na = container.get(Greeter, tag=GreeterType.A)\na.greet() # A\n\nb = container.get(Greeter, tag=GreeterType.B)\nb.greet() # B\n```\n\n### Dependency injection\n\n```python\nfrom deppy import container, injectable\n\n@injectable()\nclass Greeter:\n    def greet(self) -\u003e str:\n        return \"Hello\"\n\n@injectable()\nclass GreeterWorld:\n    def __init__(self, greeter: Greeter):\n        self._greeter = greeter\n    \n    def greet(self) -\u003e str:\n        return self._greeter.greet() + \" World\"\n\ngw = container.get(GreeterWorld)\ngw.greet() # Hello World\n```\n\n### Dependency injection with selected implementation\n\n```python\nimport abc\n\nfrom enum import Enum\n\nfrom deppy import container, injectable\n\nclass Greeter(abc.ABC):\n    def greet(self) -\u003e str:\n        raise NotImplementedError()\n\nclass GreeterType(Enum):\n    A = \"A\"\n    B = \"B\"\n        \n@injectable(Greeter, tag=GreeterType.A)\nclass GreeterA(Greeter):\n    def greet(self) -\u003e str:\n        return \"A\"\n\n@injectable(Greeter, tag=GreeterType.B)\nclass GreeterB(Greeter):\n    def greet(self) -\u003e str:\n        return \"B\"\n\n@injectable(\n    params={\n        \"a\": GreeterType.A,\n        \"b\": GreeterType.B \n    }\n)\nclass GreeterManager:\n    def __init__(self, a: Greeter, b: Greeter):\n        self._a = a\n        self._b = b\n\n    def greet(self) -\u003e str:\n        return self._a.greet() + self._b.greet()\n\ngm = container.get(GreeterManager)\ngm.greet() # AB\n```\n\n## Caveat\n\nIn order to avoid circular import, it is common to separate interfaces and implementations into different packages.\n\nPackage comsumers usually depend only on interfaces,\nresulting in no one to import implementations and thus `injectable` is never called.\n\nFor me, I usually put implemetations under `impls` directory besides interfaces. Implemetations can be registered into container by an independent composition root, and just import it and initialize it on application startup:\n\n```python\n# composition_root.py\n\nimport glob\nimport importlib\n\ndef init():\n    impls = glob.glob(\"**/impls\", recursive=True)\n    for impl in impls:\n        importlib.import_module(impl.replace(\"/\", \".\").replace(\"\\\\\", \".\"))\n\n```\n\n## License\n\n© Cyan Ho (pilagod), 2021-NOW\n\nReleased under the [MIT License](https://github.com/pilagod/deppy/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpilagod%2Fdeppy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpilagod%2Fdeppy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpilagod%2Fdeppy/lists"}