thinking-injection
Part of thinking family.
Pythonic DI for AI, as funny as it sounds.
Requires python 3.12. Is properly typed.
Better docs pending. For now, see "long story short" and an example
Long story short
- put your code in a root package (let's call it
root) with any number and depth of subpackages - mark the types that should be picked up by framework with
@discoverfrom thinking_injection.discovery import discover
- mark your protocols and ABCs with
@interfacefrom thinking_injection.interfaces import interface
- make the classes that should be managed extend
Injectable- in Java you'd call these "beans", but I wanted to avoid that kind of copycating
from thinking_injection.injectable import Injectable
- implement
inject_requirements(self, ...)and make sure to annotate the argumentsclass X(Injectable): def inject_requirements(self, a: A, b: list[B], c: C | None: ...- in that case, instance of
Xwill be created for you, and that method will be called with auto-created instances ofA, list of all known instances ofBand instance ofCif there is one Ais aSIMPLEdependency,B- aCOLLECTIVEone,C- an optional one- there is a notion of
primaryimplementation, which works as you'd expect it (the type itself for non-interface types, the subclass if there is only one subclass, but you can also force one, e.g. with decorator)- see 'Implementations.build(...)'
from thinking_injection.discovery import PrimaryImplementation- use@PrimaryImplementation(Supertype)on the subtype
- simple dependencies will use the primary implementation
- optional dependencies can be phrased any way you like:
C | None,Optional[C]orUnion[C, None], etc- if there is no primary implementation,
Nonewill be injected, even if there are multiple implementations
- if there is no primary implementation,
- collective dependencies can only be phrased as lists of supertype (interface or not)
- framework will only call that method for you with proper args, you should store them in
selfon your own - or act on them in any way you'd like
- make a
ContextScopeusingoffactory method:from thinking_injection.scope import ContextScopeContextScope.of(*from_package("root"))- more readable factory methods pending
- generally, it's
ContextScope.of(Type1, Type2, ...) - you can also define which implementations should be primary with
defaultsandforcedkw-only args-
todo document this
-
- there is also
from_module("root.some.submodule")function, as well astypes(Type1, Type2, ...) - see
thinking_injection.typeset
The entrypoint to your program should boil down to:
if __name__=="__main__":
scope = ContextScope.of(...)
ctx = BasicContext.build(scope)
with ctx.lifecycle():
instance = ctx.instance(SomeType)
instance.foo(...)
An example
There is an example app in this repo. It's short, but showcases most of the basic features.
See the ./calculator directory.
Local development
There are 2 useful scripts in this repo. They both work based on ./thinking-dependencies.txt
file, which lists other thinking projects used by this one.
install_develop.sh- will install all the
thinkingdependencies from theirdevelopbranches
- will install all the
./install_local_thinking.sh- aligned to my personal layout of home directory
- assumes you clone repositories to
~/repos - expects all the
thinkingdependencies to be cloned there - will create venv for you if missing or use an existing one
- will remove currently installed
thinkingdependencies - and will install them again from the cloned repos
- useful when you're making complimentary changes across repos
Metadata
Release files for thinking-injection 0.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| thinking_injection-0.0.1.tar.gz | 16.7 kB | Without provenance | Details for thinking_injection-0.0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| thinking_injection-0.0.1-py3-none-any.whl | Python 3 | none | any | Details for thinking_injection-0.0.1-py3-none-any.whl |
Total release size: 36.3 kB
Release files / thinking_injection-0.0.1.tar.gz
| Download URL | thinking_injection-0.0.1.tar.gz |
|---|---|
| Size | 16.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b54864f6e155c9541c8ca3085dfa4ab9587dd0880fc6e685896c11b1e58519de
|
|
BLAKE2b-256 checksum How to use checksums |
e24a245bb1a49d96afcde5f10ffdb45df7558e9b19d25cb0da7bc40f2f40533a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/5.1.1 CPython/3.12.5
|
Release files / thinking_injection-0.0.1-py3-none-any.whl
| Download URL | thinking_injection-0.0.1-py3-none-any.whl |
|---|---|
| Size | 19.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0de444a031ec1d399b766da9f863244275633394397c0df299c57cb3aeb23cc2
|
|
BLAKE2b-256 checksum How to use checksums |
68fef82fef969e7d7ab3cacc6ae0ca7a43f2ad0bec77fdcf5b7f4fdc352029d1
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/5.1.1 CPython/3.12.5
|
Security for thinking-injection 0.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.