
Security News
The Changelog Podcast: Practical Steps to Stay Safe on npm
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.
.. image:: https://codecov.io/gh/bobthemighty/punq/branch/master/graph/badge.svg?token=52hQhaggnk :target: https://codecov.io/gh/bobthemighty/punq
.. image:: https://readthedocs.org/projects/punq/badge/?version=latest :target: https://punq.readthedocs.io/en/latest/?badge=latest :alt: Documentation Status
An unintrusive library for dependency injection in modern Python.
Inspired by Funq_, Punq is a dependency injection library you can understand.
Punq is available on the cheese shop_.
.. code:: bash
pip install punq
Documentation is available on Read the docs_.
Punq avoids global state, so you must explicitly create a container in the entrypoint of your application:
.. code:: python
import punq
container = punq.Container()
Once you have a container, you can register your application's dependencies. In the simplest case, we can register any arbitrary object with some key:
.. code:: python
container.register("connection_string", instance="postgresql://...")
We can then request that object back from the container:
.. code:: python
conn_str = container.resolve("connection_string")
Usually, though, we want to register some object that implements a useful service.:
.. code:: python
class ConfigReader: def get_config(self): pass
class EnvironmentConfigReader(ConfigReader): def get_config(self): return { "logging": { "level": os.env.get("LOGGING_LEVEL", "debug") }, "greeting": os.env.get("GREETING", "Hello world") }
container.register(ConfigReader, EnvironmentConfigReader)
Now we can resolve the ConfigReader service, and receive a concrete implementation:
.. code:: python
config = container.resolve(ConfigReader).get_config()
If our application's dependencies have their own dependencies, Punq will inject those, too:
.. code:: python
class Greeter: def greet(self): pass
class ConsoleGreeter(Greeter): def init(self, config_reader: ConfigReader): self.config = config_reader.get_config()
def greet(self):
print(self.config['greeting'])
container.register(Greeter, ConsoleGreeter) container.resolve(Greeter).greet()
If you just want to resolve an object without having any base class, that's okay:
.. code:: python
class Greeter: def init(self, config_reader: ConfigReader): self.config = config_reader.get_config()
def greet(self):
print(self.config['greeting'])
container.register(Greeter) container.resolve(Greeter).greet()
And if you need to have a singleton object for some reason, we can tell punq to register a specific instance of an object:
.. code:: python
class FileWritingGreeter: def init(self, path, greeting): self.path = path self.message = greeting self.file = open(self.path, 'w')
def greet(self):
self.file.write(self.message)
one_true_greeter = FileWritingGreeter("/tmp/greetings", "Hello world") container.register(Greeter, instance=one_true_greeter)
You might not know all of your arguments at registration time, but you can provide them later:
.. code:: python
container.register(Greeter, FileWritingGreeter) greeter = container.resolve(Greeter, path="/tmp/foo", greeting="Hello world")
Conversely, you might want to provide arguments at registration time, without adding them to the container:
.. code:: python
container.register(Greeter, FileWritingGreeter, path="/tmp/foo", greeting="Hello world")
Fuller documentation is available on Read the docs_.
Github workflows, nox configuration, and linting gratefully stolen from Hypermodern Python_
.. _cheese shop: https://pypi.org/project/punq/ .. _Read the docs: http://punq.readthedocs.io/en/latest/ .. _Funq: https://github.com/jlyonsmith/Funq .. _Hypermodern Python: https://github.com/cjolowicz/cookiecutter-hypermodern-python
FAQs
An IOC Container for Python 3.8+
We found that punq demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

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.

Security News
Learn the essential steps every developer should take to stay secure on npm and reduce exposure to supply chain attacks.

Security News
Experts push back on new claims about AI-driven ransomware, warning that hype and sponsored research are distorting how the threat is understood.

Security News
Ruby's creator Matz assumes control of RubyGems and Bundler repositories while former maintainers agree to step back and transfer all rights to end the dispute.