Skip to main content
Python Software Foundation 20th Year Anniversary Fundraiser  Donate today!

Dependency injection library for Python.

Project description


Cargo is a dependency injection library for Python.

Cargo is simple to use, typed, flexible, extensible and easy to debug.

Getting started

Step 1: Install cargo

With pip:

$ pip install cargo

With pipenv:

$ pipenv install cargo

With poetry:

$ poetry add cargo

Step 2: Use cargo


import cargo

# 1. Define your components

class A:
    def __str__(self):
        return "A"

class B:
    def __init__(self, a: A):
        self.a = a

# 2. Create a cargo container

container = cargo.containers.Standard()

# 3. Register your components

container[A] = A
container[B] = B

# 4. Use cargo to initialize your components

b = container[B]

# 5. Use your components



All the examples are located in the examples directory.

Cargo is typed

Cargo uses the argument types to inject the dependencies; not their names.


import cargo

class A:

class B:

class Hello:
    def __init__(self, foo: A, bar: B):
        print(f"Hello {foo} and {bar}")

container = cargo.containers.Standard()

container[A] = A
container[B] = B
container[Hello] = Hello

# Prints: Hello <__main__.A object at 0x7f863b0fd450> and <__main__.B object at 0x7f863b09b810>

Cargo is flexible

Functions and methods can be used as factories; and objects as values.



DatabaseURL = typing.NewType("DatabaseURL", str)

def database_client_factory(db_url: DatabaseURL) -> DatabaseClient:
    if db_url.startswith("mysql://"):
        return MysqlClient(db_url)

    if db_url.startswith("postgres://"):
        return PostgresClient(db_url)

    raise Exception(f"Invalid database url: {db_url}")

container = cargo.containers.Standard()

# Registers a factory
container[DatabaseClient] = database_client_factory

# Registers a value
container[DatabaseURL] = "mysql://user:password@host:3306/db"

db_client = container[DatabaseClient]

print(db_client)  # Prints: <__main__.MysqlClient object at 0x7f681975b390>

Cargo is extensible

Cargo composes middlewares to create containers. The Standard container is just a stack of opiniated middlewares. You can create your own types of containers with the middlewares you want, or even create your own middlewares.


import cargo

class LoggerMiddleware(cargo.types.Middleware):
    def execute(
        dependency_type: cargo.types.DependencyType,
        next_middleware: cargo.types.NextMiddleware,
        print(f"Start resolving {dependency_type}")
        dependency_value = next_middleware()
        print(f"End resolving {dependency_type}")
        return dependency_value

middleware_factories = [
container = cargo.containers.create(middleware_factories)

class A:

class B:
    def __init__(self, a: A):

container[A] = A
container[B] = B

# Prints:
# Start resolving <class '__main__.B'>
# Start resolving <class '__main__.A'>
# End resolving <class '__main__.A'>
# End resolving <class '__main__.B'>

Cargo is easy to debug

Dependency not found

Cargo raises a DependencyNotFound exception with the missing dependency type when a dependency is not found.



class A:
    def __init__(self, b: B):

class B:

container = cargo.containers.Standard()
container[A] = A
# Note: B has not been registered

# Raises cargo.exceptions.DependencyNotFound: <class '__main__.B'>

Circular dependency

Cargo raises a CircularDependency exception with the dependency cycle when a circular dependency is detected.



# Dependencies:
#   - A depends on B
#   - B depends on C
#   - C depends on D
#   - D depends on B
# Circular dependency cycle is: B -> C -> D -> B


container = cargo.containers.Standard()
container[A] = A
container[B] = B
container[C] = C
container[D] = D

# Raises cargo.exceptions.CircularDependency:
#   [<class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class '__main__.B'>]



Cargo is licensed under the terms of the MIT license.


Project details

Release history Release notifications | RSS feed

This version


Download files

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

Files for cargo, version 0.3
Filename, size File type Python version Upload date Hashes
Filename, size cargo-0.3-py3-none-any.whl (7.2 kB) File type Wheel Python version py3 Upload date Hashes View
Filename, size cargo-0.3.tar.gz (7.4 kB) File type Source Python version None Upload date Hashes View

Supported by

AWS AWS Cloud computing Datadog Datadog Monitoring DigiCert DigiCert EV certificate Facebook / Instagram Facebook / Instagram PSF Sponsor Fastly Fastly CDN Google Google Object Storage and Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Salesforce Salesforce PSF Sponsor Sentry Sentry Error logging StatusPage StatusPage Status page