# Simple Inject
[中文 README](README_zh.md)
Simple Inject is a lightweight Python dependency injection library. It provides an easy-to-use interface for managing dependencies across different namespaces and scopes.
## Features
- Simple and intuitive dependency injection API
- Supports multiple namespaces to isolate dependencies
- Implements scoped dependencies using context managers or decorators
- Supports nested scopes for fine-grained control
- Supports automatic dependency injection through parameters
- Easy integration with existing projects
- Minimal overhead and dependencies
## Installation
You can install Simple Inject using pip:
```
pip install py-simple-inject
```
## Quick Start
### Basic Usage
Here is a simple example demonstrating basic dependency injection and scope management:
```python
from simple_inject import provide, inject, create_scope
# Provide a dependency
provide('config', {'debug': True})
# Inject a dependency
config = inject('config')
print(config['debug']) # Output: True
```
### Using Namespaces
```py
from simple_inject import provide, inject, create_scope
provide('key', 'value1', namespace='ns1')
provide('key', 'value2', namespace='ns2')
print(inject('key', namespace='ns1')) # Output: value1
print(inject('key', namespace='ns2')) # Output: value2
```
### Using Scopes
```py
provide('config', {'debug': True})
# Use scopes to manage dependencies
with create_scope():
provide('config', {'debug': False})
config = inject('config')
print(config['debug']) # Output: False
# Outside the scope, the original value is preserved
config = inject('config')
print(config['debug']) # Output: True
```
Scopes can also be used with the `scoped` decorator:
```py
@scoped()
def scoped_function():
provide('key', 'scoped_value')
return inject('key')
provide('key', 'outer_value')
print(inject('key')) # Output: outer_value
print(scoped_function()) # Output: scoped_value
print(inject('key')) # Output: outer_value
```
### Nested Scopes
Scoped scopes can be nested, and dependencies in inner scopes will override those in outer scopes.
```python
provide('key', 'outer')
with create_scope():
provide('key', 'inner')
print(inject('key')) # Output: inner
with create_scope() as inner_scope:
provide('key', 'innermost')
print(inject('key')) # Output: innermost
print(inject('key')) # Output: inner
print(inject('key')) # Output: outer
```
### Accessing Scoped State
You can access the state of dependencies within a scope after it exits using the `scoped_state` method:
```python
provide('config', {'debug': True})
with create_scope() as scope:
provide('config', {'debug': False})
provide('new_setting', 'scoped_value')
# Get only the dependencies that were added or modified in the scope
provided_state = scope.scoped_state('Provided') # Default policy
print(provided_state)
# Output: {'default': {'config': {'debug': False}, 'new_setting': 'scoped_value'}}
# Get the complete state within the scope
all_state = scope.scoped_state('All')
print(all_state)
# Output: {'default': {'config': {'debug': False}, 'new_setting': 'scoped_value'}}
# Get state for a specific namespace
with create_scope() as scope:
provide('key1', 'value1', namespace='ns1')
provide('key2', 'value2', namespace='ns2')
ns1_state = scope.scoped_state('Provided', 'ns1')
print(ns1_state) # Output: {'key1': 'value1'}
```
The `scoped_state` method supports two policies:
- `'Provided'` (default): Returns only dependencies that were added or modified within the scope
- `'All'`: Returns the complete state within the scope
### Automatic Injection via Function Parameters
Simple Inject also supports automatic injection via function parameters. The following example demonstrates how to use this advanced feature:
```python
from simple_inject import provide, inject, create_scope, auto_inject, Inject
class Engine:
def start(self):
print("Engine started")
# Provide a dependency
provide('engine', Engine())
# Manually inject a dependency
engine = inject('engine')
engine.start() # Output: Engine started
# Use automatic injection
@auto_inject()
def drive(car: str, engine: Engine = Inject('engine')):
print(f"Driving {car}")
engine.start()
drive("Tesla") # Output: Driving Tesla and Engine started
# Use scopes to manage dependencies
with create_scope():
provide('engine', Engine()) # Provide a new Engine instance
drive("BMW") # Output: Driving BMW and Engine started
# Outside the scope, the original value is preserved
drive("Toyota") # Output: Driving Toyota and Engine started
```
## API Reference
### `provide(key: str, value: Any, namespace: str = 'default')`
Provides a dependency in the current context.
### `inject(key: str, namespace: str = 'default') -> Any`
Injects a dependency from the current context.
### `create_scope()`
Creates a new dependency scope. Used with the `with` statement.
### `scoped()`
Decorator to create a new dependency scope for a function.
### `auto_inject()`
Decorator to automatically inject parameters marked with `Inject`.
### `Inject(key: str, namespace: str = 'default')`
Class to mark a parameter for automatic injection.
### `purge(namespace: Optional[str] = None)`
Clears dependencies, either for a specific namespace or for all namespaces.
## Contributing
Contributions are welcome! Feel free to submit a Pull Request.
## License
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
Raw data
{
"_id": null,
"home_page": null,
"name": "py-simple-inject",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "dependency injection, DI, IoC, inversion of control",
"author": null,
"author_email": "frostime <frostime@foxmail.com>",
"download_url": "https://files.pythonhosted.org/packages/1d/a3/b793b97de8a31cfc061aa06fda179ff938196e7c8ce0c5ade5f17730f406/py_simple_inject-0.8.0.tar.gz",
"platform": null,
"description": "# Simple Inject\n\n[\u4e2d\u6587 README](README_zh.md)\n\nSimple Inject is a lightweight Python dependency injection library. It provides an easy-to-use interface for managing dependencies across different namespaces and scopes.\n\n## Features\n\n- Simple and intuitive dependency injection API\n- Supports multiple namespaces to isolate dependencies\n- Implements scoped dependencies using context managers or decorators\n- Supports nested scopes for fine-grained control\n- Supports automatic dependency injection through parameters\n- Easy integration with existing projects\n- Minimal overhead and dependencies\n\n## Installation\n\nYou can install Simple Inject using pip:\n\n```\npip install py-simple-inject\n```\n\n## Quick Start\n\n### Basic Usage\n\nHere is a simple example demonstrating basic dependency injection and scope management:\n\n```python\nfrom simple_inject import provide, inject, create_scope\n\n# Provide a dependency\nprovide('config', {'debug': True})\n\n# Inject a dependency\nconfig = inject('config')\nprint(config['debug']) # Output: True\n```\n\n### Using Namespaces\n\n```py\nfrom simple_inject import provide, inject, create_scope\n\nprovide('key', 'value1', namespace='ns1')\nprovide('key', 'value2', namespace='ns2')\n\nprint(inject('key', namespace='ns1')) # Output: value1\nprint(inject('key', namespace='ns2')) # Output: value2\n```\n\n### Using Scopes\n\n```py\nprovide('config', {'debug': True})\n\n# Use scopes to manage dependencies\nwith create_scope():\n provide('config', {'debug': False})\n config = inject('config')\n print(config['debug']) # Output: False\n\n# Outside the scope, the original value is preserved\nconfig = inject('config')\nprint(config['debug']) # Output: True\n```\n\nScopes can also be used with the `scoped` decorator:\n\n```py\n@scoped()\ndef scoped_function():\n provide('key', 'scoped_value')\n return inject('key')\n\nprovide('key', 'outer_value')\nprint(inject('key')) # Output: outer_value\nprint(scoped_function()) # Output: scoped_value\nprint(inject('key')) # Output: outer_value\n```\n\n### Nested Scopes\n\nScoped scopes can be nested, and dependencies in inner scopes will override those in outer scopes.\n\n```python\nprovide('key', 'outer')\n\nwith create_scope():\n provide('key', 'inner')\n print(inject('key')) # Output: inner\n\n with create_scope() as inner_scope:\n provide('key', 'innermost')\n print(inject('key')) # Output: innermost\n\n print(inject('key')) # Output: inner\n\nprint(inject('key')) # Output: outer\n```\n\n### Accessing Scoped State\n\nYou can access the state of dependencies within a scope after it exits using the `scoped_state` method:\n\n```python\nprovide('config', {'debug': True})\n\nwith create_scope() as scope:\n provide('config', {'debug': False})\n provide('new_setting', 'scoped_value')\n\n# Get only the dependencies that were added or modified in the scope\nprovided_state = scope.scoped_state('Provided') # Default policy\nprint(provided_state)\n# Output: {'default': {'config': {'debug': False}, 'new_setting': 'scoped_value'}}\n\n# Get the complete state within the scope\nall_state = scope.scoped_state('All')\nprint(all_state)\n# Output: {'default': {'config': {'debug': False}, 'new_setting': 'scoped_value'}}\n\n# Get state for a specific namespace\nwith create_scope() as scope:\n provide('key1', 'value1', namespace='ns1')\n provide('key2', 'value2', namespace='ns2')\n\nns1_state = scope.scoped_state('Provided', 'ns1')\nprint(ns1_state) # Output: {'key1': 'value1'}\n```\n\nThe `scoped_state` method supports two policies:\n- `'Provided'` (default): Returns only dependencies that were added or modified within the scope\n- `'All'`: Returns the complete state within the scope\n\n### Automatic Injection via Function Parameters\n\nSimple Inject also supports automatic injection via function parameters. The following example demonstrates how to use this advanced feature:\n\n```python\nfrom simple_inject import provide, inject, create_scope, auto_inject, Inject\n\nclass Engine:\n def start(self):\n print(\"Engine started\")\n\n# Provide a dependency\nprovide('engine', Engine())\n\n# Manually inject a dependency\nengine = inject('engine')\nengine.start() # Output: Engine started\n\n# Use automatic injection\n@auto_inject()\ndef drive(car: str, engine: Engine = Inject('engine')):\n print(f\"Driving {car}\")\n engine.start()\n\ndrive(\"Tesla\") # Output: Driving Tesla and Engine started\n\n# Use scopes to manage dependencies\nwith create_scope():\n provide('engine', Engine()) # Provide a new Engine instance\n drive(\"BMW\") # Output: Driving BMW and Engine started\n\n# Outside the scope, the original value is preserved\ndrive(\"Toyota\") # Output: Driving Toyota and Engine started\n```\n\n## API Reference\n\n### `provide(key: str, value: Any, namespace: str = 'default')`\n\nProvides a dependency in the current context.\n\n### `inject(key: str, namespace: str = 'default') -> Any`\n\nInjects a dependency from the current context.\n\n### `create_scope()`\n\nCreates a new dependency scope. Used with the `with` statement.\n\n### `scoped()`\n\nDecorator to create a new dependency scope for a function.\n\n### `auto_inject()`\n\nDecorator to automatically inject parameters marked with `Inject`.\n\n### `Inject(key: str, namespace: str = 'default')`\n\nClass to mark a parameter for automatic injection.\n\n### `purge(namespace: Optional[str] = None)`\n\nClears dependencies, either for a specific namespace or for all namespaces.\n\n## Contributing\n\nContributions are welcome! Feel free to submit a Pull Request.\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.",
"bugtrack_url": null,
"license": "MIT",
"summary": "A lightweight dependency injection library for Python",
"version": "0.8.0",
"project_urls": {
"Bug Tracker": "https://github.com/frostime/simple-inject-py/issues",
"Homepage": "https://github.com/frostime/simple-inject-py"
},
"split_keywords": [
"dependency injection",
" di",
" ioc",
" inversion of control"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c672734d24ec160c6aee60e75c954952ec649546d72dc926b4f66b072c56ab40",
"md5": "7e76576023526d00cbb4d967356bbe6e",
"sha256": "6f724d13d25097ed9055b22476707622d5029daeea959d560448a8747d592fb8"
},
"downloads": -1,
"filename": "py_simple_inject-0.8.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "7e76576023526d00cbb4d967356bbe6e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 8231,
"upload_time": "2025-08-12T11:37:30",
"upload_time_iso_8601": "2025-08-12T11:37:30.419603Z",
"url": "https://files.pythonhosted.org/packages/c6/72/734d24ec160c6aee60e75c954952ec649546d72dc926b4f66b072c56ab40/py_simple_inject-0.8.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "1da3b793b97de8a31cfc061aa06fda179ff938196e7c8ce0c5ade5f17730f406",
"md5": "6a90e8338e1c1e92701b775f8ff3e125",
"sha256": "33f061141b6fcec2bc7a52e42f18a39fc3b8b175e6d36d6bec102ea32ae85c29"
},
"downloads": -1,
"filename": "py_simple_inject-0.8.0.tar.gz",
"has_sig": false,
"md5_digest": "6a90e8338e1c1e92701b775f8ff3e125",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 12587,
"upload_time": "2025-08-12T11:37:35",
"upload_time_iso_8601": "2025-08-12T11:37:35.502966Z",
"url": "https://files.pythonhosted.org/packages/1d/a3/b793b97de8a31cfc061aa06fda179ff938196e7c8ce0c5ade5f17730f406/py_simple_inject-0.8.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-12 11:37:35",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "frostime",
"github_project": "simple-inject-py",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "py-simple-inject"
}