Skip to main content

A lightweight dependency injection library for Python

Project description

Simple Inject

中文 README

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:

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

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

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:

@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.

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:

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:

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 file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_simple_inject-0.8.0.tar.gz (12.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_simple_inject-0.8.0-py3-none-any.whl (8.2 kB view details)

Uploaded Python 3

File details

Details for the file py_simple_inject-0.8.0.tar.gz.

File metadata

  • Download URL: py_simple_inject-0.8.0.tar.gz
  • Upload date:
  • Size: 12.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.21.0 CPython/3.10.0 Windows/10

File hashes

Hashes for py_simple_inject-0.8.0.tar.gz
Algorithm Hash digest
SHA256 33f061141b6fcec2bc7a52e42f18a39fc3b8b175e6d36d6bec102ea32ae85c29
MD5 6a90e8338e1c1e92701b775f8ff3e125
BLAKE2b-256 1da3b793b97de8a31cfc061aa06fda179ff938196e7c8ce0c5ade5f17730f406

See more details on using hashes here.

File details

Details for the file py_simple_inject-0.8.0-py3-none-any.whl.

File metadata

  • Download URL: py_simple_inject-0.8.0-py3-none-any.whl
  • Upload date:
  • Size: 8.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: pdm/2.21.0 CPython/3.10.0 Windows/10

File hashes

Hashes for py_simple_inject-0.8.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6f724d13d25097ed9055b22476707622d5029daeea959d560448a8747d592fb8
MD5 7e76576023526d00cbb4d967356bbe6e
BLAKE2b-256 c672734d24ec160c6aee60e75c954952ec649546d72dc926b4f66b072c56ab40

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page