Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Type based python dependency injection framework.
There are many out there, including some that comes directly with (web) frameworks. I wanted one that was explicitly contextualized in the different layers of the application and that did not leak in the domain layer. In many cases, dependencies are simply parameters that are passed to constructors, and ideally, the domain layer should not know anything how they are injected.
Container
: a singleton containing all dependencies and the links between themDependency
can be either:
Context
: contexts in which dependencies will live:
APPLICATION
: equivalent to singletons across the app lifetime -- must be thread and async safeTHREAD
: singleton per thread -- must be async safeTASK
: one instance will be provided for the entire task -- could be async safeFACTORY
: one instance will be provided every time it is requestedContextualizedDependency
: enriched dependency with context related attributesContextualizedContainer
: one per context, handles their dependencies lifecycleProvider
: wraps injection for different interfaces (classes, functions, methods)Package
: provides for more dependency declaration and add grouped dependencies to the containerThe container should be initialized somewhere near the entrypoint of the application.
from imbue import Container, Context, ContextualizedDependency
from myapp import APkg, ADep, BDep
container = Container(
APkg(...), # Packages would typically be passed config.
ContextualizedDependency(ADep, Context.THREAD, eager=True),
)
...
# The application context should be entered through the framework initialization.
async with container.application_context() as app_container:
a_dep = await app_container.get(ADep)
...
# The task context should be entered in each request.
async with app_container.task_context() as task_container:
b_dep = await task_container.get(BDep)
💡 A dependency can require other dependencies, the container will resolve the graph and raise errors if circular dependencies are found.
The packages provide the dependencies for the container, there are two ways of doing that.
This might be because dependencies depend on config and other reasons.
You can use the Package
class:
from typing import AsyncIterator
from imbue import Package, application_context
from myapp import LoggingConfig, MyLoggerTransport, LoggerTransport, MyLogger, Logger
class LoggingPackage(Package):
def __init__(self, config: LoggingConfig):
self._config = config
@application_context(eager=True) # You can autoload dependencies.
# The method should expose the interface as the type and return the implementation.
def logger_transport(self) -> LoggerTransport:
return MyLoggerTransport(self._config.transport)
@application_context
# Sub dependencies should be required through their interface.
async def logger(self, transport: LoggerTransport) -> AsyncIterator[Logger]:
# Package methods also allow you to handle context managers.
async with MyLogger(transport, self._config.logger) as logger:
# Using generators allow cleaning up resources when the context closes.
yield logger
It's done via methods that can be:
To declare the method returns a dependency, you simply choose the appropriate context and add the context decorator on the method.
💡 Eager dependencies are instantiated as soon as we enter their context. This is useful if we want to make sure a dependency will use the main thread's event loop.
When you need to close resources you can do so via a generator. The generator should yield the dependency.
💡 You should watch out for errors, if the context is closed handling an error, it will be raised in the generator.
You can directly pass them to the container:
Container(
# Directly expose the implementation.
ARepo,
# Or interfaced implementations.
Interfaced(BRepoInterface, BRepoImplementation),
# You can also this to control context and eagerness.
ContextualizedDependency(CDep, Context.THREAD, eager=True),
...,
)
or if you want to include them in a Package
, add them in EXTRA_DEPENDENCIES
.
💡 Whatever the method of adding dependencies, non-contextualized ones will have the context automatically set based on sub-dependencies. The lowest possible context will be used.
FAQs
Type based python dependency injection framework.
We found that imbue 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.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.