strappy-di


Namestrappy-di JSON
Version 0.2.0 PyPI version JSON
download
home_pageNone
SummaryLight, flexible, and pythonic dependency injection framework
upload_time2024-10-22 02:28:37
maintainerNone
docs_urlNone
authorNone
requires_python>=3.11
licenseMIT License Copyright (c) 2024 Caroline Matson 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 dependency injection bootstrap
VCS
bugtrack_url
requirements annotated-types anyio certifi charset-normalizer click fastapi h11 idna pydantic pydantic-core requests sniffio starlette typing-extensions urllib3 uvicorn
Travis-CI No Travis.
coveralls test coverage No coveralls.
            
# Project Description

Strappy is a light, flexible, and pythonic dependency injection framework.  
It combines an intuitive API with robust and convenient features:
- No external dependencies
- Integrates with FastAPI out of the box
- Helpful and accurate type annotations
- Default functionality that covers the vast majority of use cases, and easy customization for the rest

# Installing

Strappy is available on [PyPI](https://pypi.org/project/strappy-di/0.1.0/).
```
python -m pip install strappy-di
```

# Quick Start

Strappy makes it easy to bootstrap your application by 
recursively resolving dependencies for any callable.
```
import strappy

class Client:
    ...

class Service:
    def __init__(self, client: Client) -> None:
        self.client = client

service = strappy.base.resolve(Service)
```
Strappy works by using _strategies_ to look up _providers_ within the context of a given _container_.
Providers fulfill your dependencies either by returning a registered instance or by 
calling a factory, which can itself recursivley resolve dependencies from the container's context.

# Using Containers

Strappy provides a global base container `strappy.base` that can be used to register and resolve shared needs.
This base container can also be extended to define
different contexts for different use cases, such as
having one for your deployed service and another for unit tests.
```
import strappy

deployment_container = strappy.base.extend()
test_container = strappy.base.extend()
```
Any changes to the base container will be reflected in its 
children unless explicitly overridden, but changes
to child containers do not affect their parents or siblings.

# Registering Providers

A `Provider` can fulfill a dependency either by returning 
an instance or by returning the result of calling
a factory.
```
from strappy import Provider

class Foo:
    ...

# Provider with an instance
Provider(instance=Foo(...))

# Provider with a factory class
Provider(Foo)

# Provider with a factory function
Provider(lambda: Foo(...))
```
Providers that use factories can also be configured with 
arguments and a scope that allows you to cache and reuse the result.

The return type of a provider determines how it is looked
up in a container's registry. This type can usually be 
inferred from its factory or instance, but in some cases
it can be useful to set this explicitly. 
This value can be used by type checkers to ensure that the 
provider's factory or instance is of the expected type.
```
from typing import Protocol

class FooLike(Protocol):
    ...

provider_1 = Provider[FooLike](...)
provider_2 = Provider(..., provides=FooLike)
```

These providers can be added to a container and will then be available in its registry.
```
container.add(provider_1)

container.registry # {FooLike: [provider_1]}
```
Strappy also exposes a decorator syntax for registering factories.
```
@container.register
class Service:
    ...

@container.register
def get_service() -> Service:
    ...
```

# Customizing Strategies

Strappy gives you full control over your container's strategies and their precedence.
It comes with a number of pre-defined strategies for common use cases, 
such as using a FastAPI-style dependency, looking 
up a registered provider by type, and using a type annotation as a factory class. 
But it is also easy to use custom strategies by passing in any callable
that accepts a parameter and a container and optionally returns a provider.
```
def my_custom_strategy(param: inspect.Parameter, container: ContainerLike) -> Provider | None:
    ...
```

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "strappy-di",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.11",
    "maintainer_email": null,
    "keywords": "dependency, injection, bootstrap",
    "author": null,
    "author_email": "Caroline Matson <carlymatson21@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/3c/71/db8255500d5aa19c9bdffe76fc7a6e222e24ea453e9b039489adf31e8805/strappy_di-0.2.0.tar.gz",
    "platform": null,
    "description": "\n# Project Description\n\nStrappy is a light, flexible, and pythonic dependency injection framework.  \nIt combines an intuitive API with robust and convenient features:\n- No external dependencies\n- Integrates with FastAPI out of the box\n- Helpful and accurate type annotations\n- Default functionality that covers the vast majority of use cases, and easy customization for the rest\n\n# Installing\n\nStrappy is available on [PyPI](https://pypi.org/project/strappy-di/0.1.0/).\n```\npython -m pip install strappy-di\n```\n\n# Quick Start\n\nStrappy makes it easy to bootstrap your application by \nrecursively resolving dependencies for any callable.\n```\nimport strappy\n\nclass Client:\n    ...\n\nclass Service:\n    def __init__(self, client: Client) -> None:\n        self.client = client\n\nservice = strappy.base.resolve(Service)\n```\nStrappy works by using _strategies_ to look up _providers_ within the context of a given _container_.\nProviders fulfill your dependencies either by returning a registered instance or by \ncalling a factory, which can itself recursivley resolve dependencies from the container's context.\n\n# Using Containers\n\nStrappy provides a global base container `strappy.base` that can be used to register and resolve shared needs.\nThis base container can also be extended to define\ndifferent contexts for different use cases, such as\nhaving one for your deployed service and another for unit tests.\n```\nimport strappy\n\ndeployment_container = strappy.base.extend()\ntest_container = strappy.base.extend()\n```\nAny changes to the base container will be reflected in its \nchildren unless explicitly overridden, but changes\nto child containers do not affect their parents or siblings.\n\n# Registering Providers\n\nA `Provider` can fulfill a dependency either by returning \nan instance or by returning the result of calling\na factory.\n```\nfrom strappy import Provider\n\nclass Foo:\n    ...\n\n# Provider with an instance\nProvider(instance=Foo(...))\n\n# Provider with a factory class\nProvider(Foo)\n\n# Provider with a factory function\nProvider(lambda: Foo(...))\n```\nProviders that use factories can also be configured with \narguments and a scope that allows you to cache and reuse the result.\n\nThe return type of a provider determines how it is looked\nup in a container's registry. This type can usually be \ninferred from its factory or instance, but in some cases\nit can be useful to set this explicitly. \nThis value can be used by type checkers to ensure that the \nprovider's factory or instance is of the expected type.\n```\nfrom typing import Protocol\n\nclass FooLike(Protocol):\n    ...\n\nprovider_1 = Provider[FooLike](...)\nprovider_2 = Provider(..., provides=FooLike)\n```\n\nThese providers can be added to a container and will then be available in its registry.\n```\ncontainer.add(provider_1)\n\ncontainer.registry # {FooLike: [provider_1]}\n```\nStrappy also exposes a decorator syntax for registering factories.\n```\n@container.register\nclass Service:\n    ...\n\n@container.register\ndef get_service() -> Service:\n    ...\n```\n\n# Customizing Strategies\n\nStrappy gives you full control over your container's strategies and their precedence.\nIt comes with a number of pre-defined strategies for common use cases, \nsuch as using a FastAPI-style dependency, looking \nup a registered provider by type, and using a type annotation as a factory class. \nBut it is also easy to use custom strategies by passing in any callable\nthat accepts a parameter and a container and optionally returns a provider.\n```\ndef my_custom_strategy(param: inspect.Parameter, container: ContainerLike) -> Provider | None:\n    ...\n```\n",
    "bugtrack_url": null,
    "license": "MIT License  Copyright (c) 2024 Caroline Matson  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": "Light, flexible, and pythonic dependency injection framework",
    "version": "0.2.0",
    "project_urls": {
        "homepage": "https://github.com/carlymatson/strappy-di"
    },
    "split_keywords": [
        "dependency",
        " injection",
        " bootstrap"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "867a25e9083479bea4944818bfcbaad27c5b044316eca429c30cc5a41655cb21",
                "md5": "1b3d15315bfa74decbbd431b58d58473",
                "sha256": "36c29a064e698228223626793256a115b9cd051616afe0d7c8851306a941c769"
            },
            "downloads": -1,
            "filename": "strappy_di-0.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "1b3d15315bfa74decbbd431b58d58473",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.11",
            "size": 10787,
            "upload_time": "2024-10-22T02:28:36",
            "upload_time_iso_8601": "2024-10-22T02:28:36.237687Z",
            "url": "https://files.pythonhosted.org/packages/86/7a/25e9083479bea4944818bfcbaad27c5b044316eca429c30cc5a41655cb21/strappy_di-0.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3c71db8255500d5aa19c9bdffe76fc7a6e222e24ea453e9b039489adf31e8805",
                "md5": "861d898475765eeee0fbb96ee2c5fcaa",
                "sha256": "721ed25e5b40602e2520836e575b5bb9aead92233fdca5d2ec86892ab347ea34"
            },
            "downloads": -1,
            "filename": "strappy_di-0.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "861d898475765eeee0fbb96ee2c5fcaa",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.11",
            "size": 10488,
            "upload_time": "2024-10-22T02:28:37",
            "upload_time_iso_8601": "2024-10-22T02:28:37.725921Z",
            "url": "https://files.pythonhosted.org/packages/3c/71/db8255500d5aa19c9bdffe76fc7a6e222e24ea453e9b039489adf31e8805/strappy_di-0.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-22 02:28:37",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "carlymatson",
    "github_project": "strappy-di",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "annotated-types",
            "specs": [
                [
                    "==",
                    "0.7.0"
                ]
            ]
        },
        {
            "name": "anyio",
            "specs": [
                [
                    "==",
                    "4.4.0"
                ]
            ]
        },
        {
            "name": "certifi",
            "specs": [
                [
                    "==",
                    "2024.8.30"
                ]
            ]
        },
        {
            "name": "charset-normalizer",
            "specs": [
                [
                    "==",
                    "3.3.2"
                ]
            ]
        },
        {
            "name": "click",
            "specs": [
                [
                    "==",
                    "8.1.7"
                ]
            ]
        },
        {
            "name": "fastapi",
            "specs": [
                [
                    "==",
                    "0.112.2"
                ]
            ]
        },
        {
            "name": "h11",
            "specs": [
                [
                    "==",
                    "0.14.0"
                ]
            ]
        },
        {
            "name": "idna",
            "specs": [
                [
                    "==",
                    "3.8"
                ]
            ]
        },
        {
            "name": "pydantic",
            "specs": [
                [
                    "==",
                    "2.8.2"
                ]
            ]
        },
        {
            "name": "pydantic-core",
            "specs": [
                [
                    "==",
                    "2.20.1"
                ]
            ]
        },
        {
            "name": "requests",
            "specs": [
                [
                    "==",
                    "2.32.3"
                ]
            ]
        },
        {
            "name": "sniffio",
            "specs": [
                [
                    "==",
                    "1.3.1"
                ]
            ]
        },
        {
            "name": "starlette",
            "specs": [
                [
                    "==",
                    "0.38.2"
                ]
            ]
        },
        {
            "name": "typing-extensions",
            "specs": [
                [
                    "==",
                    "4.12.2"
                ]
            ]
        },
        {
            "name": "urllib3",
            "specs": [
                [
                    "==",
                    "2.2.2"
                ]
            ]
        },
        {
            "name": "uvicorn",
            "specs": [
                [
                    "==",
                    "0.30.6"
                ]
            ]
        }
    ],
    "lcname": "strappy-di"
}
        
Elapsed time: 4.53782s