Name | strappy-di JSON |
Version |
0.2.0
JSON |
| download |
home_page | None |
Summary | Light, flexible, and pythonic dependency injection framework |
upload_time | 2024-10-22 02:28:37 |
maintainer | None |
docs_url | None |
author | None |
requires_python | >=3.11 |
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. |
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"
}