Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

kanata

Package Overview
Dependencies
Maintainers
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

kanata

A simple dependency injection framework for Python 3 applications.

  • 4.0.0.0
  • PyPI
  • Socket score

Maintainers
1

Welcome

PyPI version CodeFactor Shilds

Kanata is a very simple dependency injection framework used for decoupling the services of your Python application's services from their dependencies. This may help with maintainability, testability and readability.

Currently, the following lifetime scopes are supported:

  • Transient: On each request, a new instance of the specific dependency is created. Typically, a transient injectable maintains its own state.
  • Scoped: On the first request, a new instance is created for a particular lifetime scope and this same instance is returned on further requests. Typically, a scoped injectable is used for separating instances between incoming web requests.
  • Singleton: On the first request, a new instance is created and this same instance is returned on further requests to any of the lifetime scopes in a tree.

Requirements

The project currently targets Python version 3.11 or higher. Compatibility with older versions may be possible but isn't tested.

Getting started

First of all, make sure that you install the library in your project. Using a default Python installation, the following will work:

# Unix/MacOS
python3 -m pip install kanata

# Windows
py -m pip install kanata

Using the library is as simple as building a catalog of our injectables and resolving a root injectable:

from kanata import InjectableCatalog, LifetimeScope, find_injectables

# Find all types from a specific module that have been marked as injectables:
registrations = find_injectables("my.module")

# Construct a new catalog for these types:
catalog = InjectableCatalog(registrations)

# Create a scope that manages the resolved instances:
scope = LifetimeScope(catalog)

# And finally, resolve the injectable type you need:
instance = scope.resolve(MyClass)

For the above code to work, you need to mark the types you need as injectables. You can currently achieve this by using the @injectable(...) decorator as follows:

from kanata.decorators import injectable

# Typically, you'll want to create an interface to be used as the contract:
class IMyInterface:
    pass

# And then register your type as an injectable with its contract:
@injectable(IMyInterface):
class MyClass(IMyInterface):
    ...

As constructor (or __init__(...) in Python) injection is used, you need to define the required dependencies in this method:

from kanata.decorators import injectable

@injectable(IMyInterface):
class MyClass(IMyInterface):
    # Type hints are required for the framework to identify the dependencies.
    # Where multiple dependencies are allowed, you can use a Tuple to specify it.
    def __init__(
        self,
        dependency1: IDependency1,
        dependency2: IDependency2,
        multiple_dependencies: tuple[IDependency3, ...]):
        ...

The framework will then take care of resolving these dependencies.

Below are some of the dependency resolution rules:

  • If a single dependency is required but there is no matching registration, an exception is raised.
  • If a single dependency is required and there are multiple candidates, it's unspecified which one will be injected. This is mainly because hash tables are used during dependency resolution.
  • If multiple dependencies are required but there are no matching registrations, an empty tuple is injected. Otherwise, a tuple with all matching injectables is injected.

For the ability to customize logging, the structlog library is used instead of the built-in logging module of Python. Please, refer to the project's documentation for details.

Samples

In case you would like to see more samples, clone the repository and run one of the bundled samples.

First, make sure that Kanata is installed, preferably in editable mode (while standing in the root directory):

# Unix/MacOS
python3 -m pip install -e .

# Windows
py -m pip install -e .

Then, while standing in the root directory, execute the samples.py script and follow the on-screen instructions:

# Unix/MacOS
python3 ./samples.py

# Windows
py .\samples.py

The samples are full of comments to better explain what is happening.

Contribution

Contributions to the project are welcome in the form of creating an issue or forking the repository and creating a pull request.

FAQs


Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc