Skip to main content

..a tiny but powerful DI library for Python.

Project description

hazrakah on PyPI hazrakah on readthedocs

hazrakah (הזרקה) is a tiny but powerful DI implementation for Python.

This README is only a high-level introduction to hazrakah. For more detailed documentation, please view the official docs at https://hazrakah.readthedocs.io.

Features

  • Supports Transient, Scoped, Singleton and Instance registrations.
  • Registration targets can be a concrete type or a factories.
  • Scopes are hierarchical.
  • Container is mutable byd efault, but can be frozen.

Installation

You can install hazrakah from PyPI through usual means, such as pip:

   pip install hazrakah

Usage

To use hazrakah simply create a Container instance and create one or more type registrations. Afterward, the container can be used to resolve instances for the types you have registered:

    from hazrakah import Container

    # assume you have three classes, Fizz, Buzz, and FizzBuzz,
    # and also assume you have Protocols (interfaces) for each.

    container = Container()
    scoped_container = container.create_scope()

    # TRANSIENT == a new instance of `Foo` is created
    # for every resolve of `IFoo`.
    container.register_transient(IFizz, Fizz)
    #
    fizz1 = container.resolve(IFizz)
    fizz2 = container.resolve(IFizz)
    assert fizz1 is not fizz2, 'transients reg, every resolve is a new instance.'


    # SCOPED == within a given "scope" a single instance is returned
    # for every resolve of `IBuzz`. new scopes == new instances.
    container.register_scoped(IBuzz, Buzz)
    #
    buzz1 = container.resolve(IBuzz)
    buzz2 = container.resolve(IBuzz)
    buzz3 = scoped_container.resolve(IBuzz)
    assert buzz1 is buzz2, 'scoped resolves are singleton-like WITHIN a container scope.'
    assert buzz1 is not buzz3, 'scoped resolves are NOT shared between container scopes, new scope? new singleton.'

    # INSTANCE == the provided instance is returned
    # for every resolve of `FizzBuzz`.
    container.register_instance(FizzBuzz, FizzBuzz())
    #
    fizzbuzz1 = container.resolve(FizzBuzz)
    fizzbuzz2 = scoped_container.resolve(FizzBuzz)
    assert fizzbuzz1 is fizzbuzz2, 'instance resolves always yield the provided instance'
    # NOTE: "scopes" resolve hierarchically any "non-scoped" type registration,
    #       this is why `scoped_container`` resolved the same instance as `container`.
    #       if this were a scoped registration a NEW instance would have been created.
    #       this scoping logic is true for INSTANCE, SINGLETON, and TRANSIENT regs.

    # SINGLETON == a SINGLE instance will be created
    # for ALL resolves of `IFizzBuzz`.
    container.register_singleton(IFizzBuzz, lambda c: c.resolve(FizzBuzz))
    fizzbuzz3 = container.resolve(IFizzBuzz)
    fizzbuzz4 = container.resolve(IFizzBuzz)
    assert fizzbuzz3 is fizzbuzz4, 'singleton resolves always yield a single instance.'

    # for completeness, concrete types can self-regsiter without a target spec.
    container.register_transient(Fizz)
    fizz3 = container.resolve(Fizz)
    assert fizz3 is not None

    # and last, but not least, containers can be frozen,
    # making them immutable (also freezing any scopes
    # created after being frozen.)  once frozen, they
    # cannot be unfrozen.
    try:
        container.freeze()
        container.register_instance(Fizz, Fizz())
    except RegistrationError:
        pass
    else:
        assert False, 'Frozen containers should be immutable.'

    try:
        scoped_container.register_instance(Fizz, Fizz())
    except:
        assert False, 'Scopes created BEFORE freezing are NOT frozen.'

    try:
        scope2 = container.create_scope()
        scope2.register_instance(Fizz, Fizz())
    except RegistrationError:
        pass
    else:
        assert False, 'Scopes created AFETR freezing are also frozen.'

    try:
        setattr(container, '__frozen', False)
    except AttributeError:
        pass
    else:
        assert False, 'Attempts to modify Container directly will fail.'

Contact

You can reach me on Discord or open an Issue on Github.

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

hazrakah-0.0.1.tar.gz (8.4 kB view details)

Uploaded Source

Built Distribution

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

hazrakah-0.0.1-py3-none-any.whl (7.5 kB view details)

Uploaded Python 3

File details

Details for the file hazrakah-0.0.1.tar.gz.

File metadata

  • Download URL: hazrakah-0.0.1.tar.gz
  • Upload date:
  • Size: 8.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15+

File hashes

Hashes for hazrakah-0.0.1.tar.gz
Algorithm Hash digest
SHA256 802f2630c20918098de4c62d4c6efac00d8aadb0703d648baa8311be179a229e
MD5 6ce38536298262d8d3e67faa4293f790
BLAKE2b-256 6934c1379bfd2e1919779fec047924acb3ef44c0e73e6aafcb5513c44474f9ac

See more details on using hashes here.

File details

Details for the file hazrakah-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: hazrakah-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 7.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.15+

File hashes

Hashes for hazrakah-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 3e176210de4a300db9bb84ac05424f69bbc346336e1d0338585165ff8caf6924
MD5 2000985aecad4810ce1e4c5e7c7a362d
BLAKE2b-256 a47ea1a8d500d3917be8300f0a288c5f80760a57ad60a8e07bd9f84995c28677

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