dinjections


Namedinjections JSON
Version 1.1.1 PyPI version JSON
download
home_page
SummaryDependency injection framework based on uber.fx for python
upload_time2024-02-14 13:46:51
maintainer
docs_urlNone
author
requires_python>=3.6
licenseMIT License Copyright (c) 2023 Francisco Escher Guimarães da Silva Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
keywords di dependency injeciton fx framework dinjections
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # DInjections

This project implements a dependency injection framework in Python, based on uber's fx package.

It works as a modular dependency injection framework, where you can define provision of dependencies, using options pattern and hints to define which dependencies should be provided.

It also implements lifecycle management, where you can define hooks to be executed on start and stop.

Dependencies are only initialized when they are needed, even if provided.


## Installation

```bash
pip install dinjections
```

## Usage

```python
from dinjections import App, Provide, Invoke, Hook, Lifecycle, Provider, Annotated, Annotations


# Define a class that will be injected
class Dependency0:
  pass

# Define a class that will be injected and has dependencies of the same type
class Dependency1:
  def __init__(self, d0_1: Annotated[Dependency0, Annotations(name="d0_1")], d0_2: Annotated[Dependency0, Annotations(name="d0_2")]):
    self.d0_1 = d0_1
    self.d0_2 = d0_2

  def run(self):
    print("Dependency1 running")

# Define another class that will be injected
class Dependency2:
    def __init__(self, d1: Dependency1):
        self.d1 = d1

    def run(self):
        self.d1.run()

# Function that returns a dependency
def new_dep_2(d1: Dependency1) -> Dependency2:
    return Dependency2()

# function that will be invoked
def register_hooks(l: Lifecycle, d: Dependency2):
    l.append_hook(Hook(
        on_start=lambda: {
            d.run()
        },
    ))

app = App(
    Provide(
        # dependency can be initiliazed passing it's class
        Dependency1,
        # and also with a function that returns the object
        new_dep_2,
        # you can also define a name for the dependency, in case there is more than one dependency of the same type
        Provider(Dependency0, name="d0_1"),
        Provider(Dependency0, name="d0_2"),
    ),
    Invoke(
        register_hooks,
    ))

app.run()
```


## Dependencies of the same type

If you have dependencies of the same type, you can use the `Provider` class to define a name for the dependency with the name argument, and then use it to inject the dependency (as shown above).

If this is not done, a dependency will override the previous.

## Dependency inheritance

If you have a dependency that inherits from another, you can use the `Provider` class to define the dependency with a name argument, and then use it to inject the dependency (as shown below).

```python
# Define a class that will be injected
class TestClass4(TestClass3):
    pass

# expects a dependency of type TestClass3, but will accept TestClass4 named "t1"
def register_hooks(l: Lifecycle, t: TestClass3):
    l.append_hook(Hook(
        on_start=lambda: {
            t.run()
        },
    ))

app = App(
    Provide(
        # provides names dependency that inherites from expected class TestClass3
        Provider(TestClass4, name=TestClass3),
    ),
    Invoke(
        register_hooks,
    ))

app.run()
```


## Grouped dependencies

You can group dependencies setting the `group` parameters to `True` in a `Provider`. This will make the dependency be injected as a list of dependencies, with all the dependencies that were provided with the same name.

```python
class MyDependency:
    def __init__(self):

    def run(self):
        print("MyDependency running")

def register_hooks(l: Lifecycle, d: Annotated[MyDependency, Annotations(group=True)]):
    # d is now a list of MyDependency, with all the dependencies named "md" that were provided
    for t in d:
        l.append_hook(Hook(
            on_start=lambda: {
                t.run()
            },
        ))

app = App(
    Provide(
        Provider(MyDependency, group=True),
        Provider(MyDependency, group=True),
    ),
    Invoke(
        register_hooks,
    ))
app.run()
```


## Lifecycle

You can define hooks to be executed on start and stop of the application.

Currently hooks are executed in the order they are defined, with no support for concurrency.

```python 
from dinjections import App, Hook, Lifecycle


def register_hooks(l: Lifecycle):
    l.append_hook(Hook(
        on_start=lambda: {
            print("Invoking 1")
        },
        on_stop=lambda: {
            print("Stopping 1")
        },
    ))
    l.append_hook(Hook(
        on_start=lambda: {
            print("Invoking 2")
        },
        on_stop=lambda: {
            print("Stopping 2")
        },
    ))

app = App(
    Invoke(
        register_hooks,
    )
)
app.run()
```

            

Raw data

            {
    "_id": null,
    "home_page": "",
    "name": "dinjections",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "di,dependency injeciton,fx,framework,dinjections",
    "author": "",
    "author_email": "Francisco Escher Guimar\u00e3es da Silva <egs.francisco@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/05/65/657b16a7fc0a60ba8f5f877bd5383507a4b1d2c9ce7539dd19770488fa87/dinjections-1.1.1.tar.gz",
    "platform": null,
    "description": "# DInjections\n\nThis project implements a dependency injection framework in Python, based on uber's fx package.\n\nIt works as a modular dependency injection framework, where you can define provision of dependencies, using options pattern and hints to define which dependencies should be provided.\n\nIt also implements lifecycle management, where you can define hooks to be executed on start and stop.\n\nDependencies are only initialized when they are needed, even if provided.\n\n\n## Installation\n\n```bash\npip install dinjections\n```\n\n## Usage\n\n```python\nfrom dinjections import App, Provide, Invoke, Hook, Lifecycle, Provider, Annotated, Annotations\n\n\n# Define a class that will be injected\nclass Dependency0:\n  pass\n\n# Define a class that will be injected and has dependencies of the same type\nclass Dependency1:\n  def __init__(self, d0_1: Annotated[Dependency0, Annotations(name=\"d0_1\")], d0_2: Annotated[Dependency0, Annotations(name=\"d0_2\")]):\n    self.d0_1 = d0_1\n    self.d0_2 = d0_2\n\n  def run(self):\n    print(\"Dependency1 running\")\n\n# Define another class that will be injected\nclass Dependency2:\n    def __init__(self, d1: Dependency1):\n        self.d1 = d1\n\n    def run(self):\n        self.d1.run()\n\n# Function that returns a dependency\ndef new_dep_2(d1: Dependency1) -> Dependency2:\n    return Dependency2()\n\n# function that will be invoked\ndef register_hooks(l: Lifecycle, d: Dependency2):\n    l.append_hook(Hook(\n        on_start=lambda: {\n            d.run()\n        },\n    ))\n\napp = App(\n    Provide(\n        # dependency can be initiliazed passing it's class\n        Dependency1,\n        # and also with a function that returns the object\n        new_dep_2,\n        # you can also define a name for the dependency, in case there is more than one dependency of the same type\n        Provider(Dependency0, name=\"d0_1\"),\n        Provider(Dependency0, name=\"d0_2\"),\n    ),\n    Invoke(\n        register_hooks,\n    ))\n\napp.run()\n```\n\n\n## Dependencies of the same type\n\nIf you have dependencies of the same type, you can use the `Provider` class to define a name for the dependency with the name argument, and then use it to inject the dependency (as shown above).\n\nIf this is not done, a dependency will override the previous.\n\n## Dependency inheritance\n\nIf you have a dependency that inherits from another, you can use the `Provider` class to define the dependency with a name argument, and then use it to inject the dependency (as shown below).\n\n```python\n# Define a class that will be injected\nclass TestClass4(TestClass3):\n    pass\n\n# expects a dependency of type TestClass3, but will accept TestClass4 named \"t1\"\ndef register_hooks(l: Lifecycle, t: TestClass3):\n    l.append_hook(Hook(\n        on_start=lambda: {\n            t.run()\n        },\n    ))\n\napp = App(\n    Provide(\n        # provides names dependency that inherites from expected class TestClass3\n        Provider(TestClass4, name=TestClass3),\n    ),\n    Invoke(\n        register_hooks,\n    ))\n\napp.run()\n```\n\n\n## Grouped dependencies\n\nYou can group dependencies setting the `group` parameters to `True` in a `Provider`. This will make the dependency be injected as a list of dependencies, with all the dependencies that were provided with the same name.\n\n```python\nclass MyDependency:\n    def __init__(self):\n\n    def run(self):\n        print(\"MyDependency running\")\n\ndef register_hooks(l: Lifecycle, d: Annotated[MyDependency, Annotations(group=True)]):\n    # d is now a list of MyDependency, with all the dependencies named \"md\" that were provided\n    for t in d:\n        l.append_hook(Hook(\n            on_start=lambda: {\n                t.run()\n            },\n        ))\n\napp = App(\n    Provide(\n        Provider(MyDependency, group=True),\n        Provider(MyDependency, group=True),\n    ),\n    Invoke(\n        register_hooks,\n    ))\napp.run()\n```\n\n\n## Lifecycle\n\nYou can define hooks to be executed on start and stop of the application.\n\nCurrently hooks are executed in the order they are defined, with no support for concurrency.\n\n```python \nfrom dinjections import App, Hook, Lifecycle\n\n\ndef register_hooks(l: Lifecycle):\n    l.append_hook(Hook(\n        on_start=lambda: {\n            print(\"Invoking 1\")\n        },\n        on_stop=lambda: {\n            print(\"Stopping 1\")\n        },\n    ))\n    l.append_hook(Hook(\n        on_start=lambda: {\n            print(\"Invoking 2\")\n        },\n        on_stop=lambda: {\n            print(\"Stopping 2\")\n        },\n    ))\n\napp = App(\n    Invoke(\n        register_hooks,\n    )\n)\napp.run()\n```\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2023 Francisco Escher Guimar\u00e3es da Silva  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.",
    "summary": "Dependency injection framework based on uber.fx for python",
    "version": "1.1.1",
    "project_urls": {
        "repository": "https://github.com/franciscoescher/dinjections"
    },
    "split_keywords": [
        "di",
        "dependency injeciton",
        "fx",
        "framework",
        "dinjections"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "5a9606238abf1e6a8ffd110942cf3a981fbf3c9fa3e1ba0308a4cee4f1582a32",
                "md5": "f13b00501919fd3044d6a52493aadc4d",
                "sha256": "e78ece1093a129114a35b543fe6abd5b3e0422f7c8c7f6fc5335160fcd246181"
            },
            "downloads": -1,
            "filename": "dinjections-1.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "f13b00501919fd3044d6a52493aadc4d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 8464,
            "upload_time": "2024-02-14T13:46:49",
            "upload_time_iso_8601": "2024-02-14T13:46:49.713008Z",
            "url": "https://files.pythonhosted.org/packages/5a/96/06238abf1e6a8ffd110942cf3a981fbf3c9fa3e1ba0308a4cee4f1582a32/dinjections-1.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "0565657b16a7fc0a60ba8f5f877bd5383507a4b1d2c9ce7539dd19770488fa87",
                "md5": "5a6d0f7c58d7ed4ea4319fd1454071c9",
                "sha256": "cfc8d6826c8fe1530acdda44fd378eca57f957c0ce88f8d1e0b745dab572fa42"
            },
            "downloads": -1,
            "filename": "dinjections-1.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "5a6d0f7c58d7ed4ea4319fd1454071c9",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 9874,
            "upload_time": "2024-02-14T13:46:51",
            "upload_time_iso_8601": "2024-02-14T13:46:51.482509Z",
            "url": "https://files.pythonhosted.org/packages/05/65/657b16a7fc0a60ba8f5f877bd5383507a4b1d2c9ce7539dd19770488fa87/dinjections-1.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-02-14 13:46:51",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "franciscoescher",
    "github_project": "dinjections",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [],
    "lcname": "dinjections"
}
        
Elapsed time: 0.18110s