type_dep
type_dep is a dependency injection framework that uses type hints to inject dependencies (much like Angular, Dotnet and the like)
Quick Start
- Install the package
pip install type_dep
- Inherit from the package's
Dependencyclass to create an injectable dependency class. - Use the
dependencyinjecteddecorator to tag functions or methods that require dependency injection through their parameter type annotations.
import os
from type_dep import Dependency, dependencyinjected, Context
counter = 0
class A(Dependency):
def __init__(self, name: str):
self.name = name
@classmethod
def instantiate(cls):
global counter
counter += 1
return A(f"{counter}")
class B(Dependency):
def __init__(self, sex: str):
self.sex = sex
@classmethod
def instantiate(cls):
return B(os.environ.get("SEX", "female"))
@dependencyinjected
def get_detail(self, a: A):
"""
A method which uses dependency injection
`a` will be instantiated and injected into this method at runtime.
By default, these dependencies are stored in a global context.
Subsequent method calls will use the instances of the dependencies that were
instantiated on the first run.
NOTE: The type hints on the parameters are a must
"""
return {"name": a.name, "sex": self.sex}
@dependencyinjected
def scoped_get_detail(self, a: A, context: Context):
"""
When a `Context` argument is passed,
the dependencies are stored in a context that gets destroyed after every method call.
NOTE: The type hints on the parameters are a must
"""
return {"name": a.name, "sex": self.sex}
@dependencyinjected
def run(males: int, females: int, a: A, greeting: str, b: B):
"""
Just some function that is dependency injected.
`a` and `b` will be instantiated and injected into the function at runtime
By default, these dependencies are stored in a global context.
Subsequent method calls will use the instances of the dependencies that were
instantiated on the first run.
NOTE: The type hints on the parameters are a must
"""
print(f"males: {males}, females: {females}, greeting: {greeting}, a.name: {a.name}, b.sex: {b.sex}")
print(f'{b.get_detail()}\n')
@dependencyinjected
def scoped_run(males: int, females: int, a: A, greeting: str, b: B, context: Context):
"""
Just some function that is dependency injected.
`a` and `b` will be instantiated and injected into the function at runtime
When a `Context` argument is passed,
the dependencies are stored in a context that gets destroyed after every function call.
NOTE: The type hints on the parameters are a must
"""
print(f"scoped: males: {males}, females: {females}, greeting: {greeting}, a.name: {a.name}, b.sex: {b.sex}")
print(f'scoped: {b.scoped_get_detail()}\n')
if __name__ == '__main__':
counter = 0
for _ in range(3):
run(6, 56, greeting="hey")
# males: 6, females: 56, greeting: hey, a.name: 1, b.sex: female
# {'name': '2', 'sex': 'female'}
#
# males: 6, females: 56, greeting: hey, a.name: 1, b.sex: female
# {'name': '2', 'sex': 'female'}
#
# males: 6, females: 56, greeting: hey, a.name: 1, b.sex: female
# {'name': '2', 'sex': 'female'}
for _ in range(3):
scoped_run(6, 56, greeting="hey")
# scoped: males: 6, females: 56, greeting: hey, a.name: 3, b.sex: female
# scoped: {'name': '4', 'sex': 'female'}
#
# scoped: males: 6, females: 56, greeting: hey, a.name: 5, b.sex: female
# scoped: {'name': '6', 'sex': 'female'}
#
# scoped: males: 6, females: 56, greeting: hey, a.name: 7, b.sex: female
# scoped: {'name': '8', 'sex': 'female'}
Why use type hints
Python type hints have matured alot. It is high time we used them to the maximum. Apart from helping us avoid some logical errors, wouldn't be nice if type hints helped inject dependencies.
- Very little extra code is needed if you are already using types
- It is intuitive
How to test
- Clone the repository
git clone git@github.com:sopherapps/type_dep.git
cd type_dep
- Create and activate the virtual environment
python3 -m venv env
source env/bin/activate
- Run the test command
python -m unittest
License
Copyright (c) 2022 Martin Ahindura Licensed under the MIT License
Metadata
Release files for type-dep 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| type_dep-0.0.2.tar.gz | 5.7 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| type_dep-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 10.9 kB
Release files / type_dep-0.0.2.tar.gz
| Download URL | type_dep-0.0.2.tar.gz |
|---|---|
| Size | 5.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
dc05b01db7268bd90395c99b6b427b80efd6a86e8817000ac98a9f05b83787e1
|
|
BLAKE2b-256 checksum How to use checksums |
078fa8fa6e8e62e1dac7ce841be296d97c84c401518ff510c5339e2eae80888d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.0 CPython/3.9.17
|
Release files / type_dep-0.0.2-py3-none-any.whl
| Download URL | type_dep-0.0.2-py3-none-any.whl |
|---|---|
| Size | 5.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b0bf9b4cd77bad882e94c374957b5c626c8f4e76d38d2220540f9ee8ab45c826
|
|
BLAKE2b-256 checksum How to use checksums |
7933d975301c4a4385b8c5a86569b12ba9fff24d45d272406a8903b044903c43
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.0 CPython/3.9.17
|
Security for type-dep 0.0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.