mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-10-31 16:07:51 +03:00 
			
		
		
		
	Merge branch 'release/3.40.0' into master
This commit is contained in:
		
						commit
						e257fd9cb0
					
				|  | @ -1,74 +0,0 @@ | ||||||
| Bundles mini application example |  | ||||||
| -------------------------------- |  | ||||||
| 
 |  | ||||||
| .. currentmodule:: dependency_injector.containers |  | ||||||
| 
 |  | ||||||
| "Bundles" is an example mini application that is intended to demonstrate the |  | ||||||
| power of dependency injection for creation of re-usable application components |  | ||||||
| ("bundles") with 100% transparency of their dependencies. |  | ||||||
| 
 |  | ||||||
| Example application |  | ||||||
| ~~~~~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
| "Bundles" mini application has next structure: |  | ||||||
| 
 |  | ||||||
| .. code-block:: bash |  | ||||||
| 
 |  | ||||||
|     bundles/ |  | ||||||
|         bundles/               <-- Bundles package |  | ||||||
|             photos/            <-- Photos bundle |  | ||||||
|                 __init__.py    <-- Photos bundle dependency injection container |  | ||||||
|                 entities.py |  | ||||||
|                 repositories.py |  | ||||||
|             users/             <-- Users bundle |  | ||||||
|                 __init__.py    <-- Users bundle dependency injection container |  | ||||||
|                 entities.py |  | ||||||
|                 repositories.py |  | ||||||
|         run.py                 <-- Entrypoint |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| IoC containers |  | ||||||
| ~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
| Next two listings show :py:class:`DeclarativeContainer`'s for "users" and  |  | ||||||
| "photos" bundles. |  | ||||||
| 
 |  | ||||||
| Listing of ``bundles/users/__init__.py``: |  | ||||||
| 
 |  | ||||||
| .. literalinclude:: ../../examples/miniapps/bundles/bundles/users/__init__.py |  | ||||||
|    :language: python |  | ||||||
| 
 |  | ||||||
| .. note:: |  | ||||||
| 
 |  | ||||||
|     - ``Users`` container has dependency on database. |  | ||||||
| 
 |  | ||||||
| Listing of ``bundles/photos/__init__.py``: |  | ||||||
| 
 |  | ||||||
| .. literalinclude:: ../../examples/miniapps/bundles/bundles/photos/__init__.py |  | ||||||
|    :language: python |  | ||||||
| 
 |  | ||||||
| .. note:: |  | ||||||
| 
 |  | ||||||
|     - ``Photos`` container has dependencies on database and file storage. |  | ||||||
| 
 |  | ||||||
| Run application |  | ||||||
| ~~~~~~~~~~~~~~~ |  | ||||||
| 
 |  | ||||||
| Finally, both "bundles" are initialized by providing needed dependencies. |  | ||||||
| Initialization of dependencies happens right in the runtime, not earlier. |  | ||||||
| Generally, it means, that any part of any bundle could be overridden on the |  | ||||||
| fly. |  | ||||||
| 
 |  | ||||||
| Listing of ``run.py``: |  | ||||||
| 
 |  | ||||||
| .. literalinclude:: ../../examples/miniapps/bundles/run.py |  | ||||||
|    :language: python |  | ||||||
| 
 |  | ||||||
| Links |  | ||||||
| ~~~~~ |  | ||||||
| 
 |  | ||||||
| + `Dependency Injector <https://github.com/ets-labs/python-dependency-injector/>`_ |  | ||||||
| + `Full example sources <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/bundles>`_ |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| .. disqus:: |  | ||||||
|  | @ -8,14 +8,11 @@ Other examples | ||||||
|                  of inversion of control principle and powered by  |                  of inversion of control principle and powered by  | ||||||
|                  "Dependency Injector" framework. |                  "Dependency Injector" framework. | ||||||
| 
 | 
 | ||||||
| Current section of documentation is designed to provide several example mini  | This sections contains assorted ``Dependency Injector`` examples. | ||||||
| applications that are built according to the inversion of control principle  |  | ||||||
| and powered by *Dependency Injector* framework. |  | ||||||
| 
 | 
 | ||||||
| ..  toctree:: | ..  toctree:: | ||||||
|     :maxdepth: 2 |     :maxdepth: 2 | ||||||
| 
 | 
 | ||||||
|     bundles_miniapp |  | ||||||
|     use_cases_miniapp |     use_cases_miniapp | ||||||
|     password_hashing_miniapp |     password_hashing_miniapp | ||||||
|     chained_factories |     chained_factories | ||||||
|  |  | ||||||
							
								
								
									
										130
									
								
								docs/examples/decoupled-packages.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										130
									
								
								docs/examples/decoupled-packages.rst
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,130 @@ | ||||||
|  | Decoupled packages example (multiple containers) | ||||||
|  | ================================================ | ||||||
|  | 
 | ||||||
|  | .. meta:: | ||||||
|  |    :keywords: Python,Dependency Injection,Inversion of Control,Container,Example,Application, | ||||||
|  |               Framework,AWS,boto3,client | ||||||
|  |    :description: This example shows how to use Dependency Injector to create Python decoupled packages. | ||||||
|  |                  To achieve a decoupling each package has a container with the components. When | ||||||
|  |                  a component needs a dependency from the outside of the package scope we use the | ||||||
|  |                  Dependency provider. The package container has no knowledge on where the | ||||||
|  |                  dependencies come from. It states a need that the dependencies must be provided. | ||||||
|  |                  This helps to decouple a package from the 3rd party dependencies and other | ||||||
|  |                  packages. | ||||||
|  | 
 | ||||||
|  | This example shows how to use ``Dependency Injector`` to create decoupled packages. | ||||||
|  | 
 | ||||||
|  | To achieve a decoupling each package has a container with the components. When a component needs a | ||||||
|  | dependency from the outside of the package scope we use the ``Dependency`` provider. The package | ||||||
|  | container has no knowledge on where the dependencies come from. It states a need that the | ||||||
|  | dependencies must be provided. This helps to decouple a package from the 3rd party dependencies | ||||||
|  | and other packages. | ||||||
|  | 
 | ||||||
|  | To wire the packages we use an application container. Application container has all 3rd party | ||||||
|  | dependencies and package containers. It wires the packages and dependencies to create a | ||||||
|  | complete application. | ||||||
|  | 
 | ||||||
|  | We build an example micro application that consists of 3 packages: | ||||||
|  | 
 | ||||||
|  | - ``user`` - a package with user domain logic, depends on a database | ||||||
|  | - ``photo`` - a package with photo domain logic, depends on a database and AWS S3 | ||||||
|  | - ``analytics`` - a package with analytics domain logic, depends on the  ``user`` and ``photo`` | ||||||
|  |   package components | ||||||
|  | 
 | ||||||
|  | .. image:: images/decoupled-packages.png | ||||||
|  |     :width: 100% | ||||||
|  |     :align: center | ||||||
|  | 
 | ||||||
|  | Start from the scratch or jump to the section: | ||||||
|  | 
 | ||||||
|  | .. contents:: | ||||||
|  |    :local: | ||||||
|  |    :backlinks: none | ||||||
|  | 
 | ||||||
|  | You can find the source code and instructions for running on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/decoupled-packages>`_. | ||||||
|  | 
 | ||||||
|  | Application structure | ||||||
|  | --------------------- | ||||||
|  | 
 | ||||||
|  | Application consists of an ``example`` package, a configuration file and a ``requirements.txt`` | ||||||
|  | file. | ||||||
|  | 
 | ||||||
|  | .. code-block:: bash | ||||||
|  | 
 | ||||||
|  |    ./ | ||||||
|  |    ├── example/ | ||||||
|  |    │   ├── analytics/ | ||||||
|  |    │   │   ├── __init__.py | ||||||
|  |    │   │   ├── containers.py | ||||||
|  |    │   │   └── services.py | ||||||
|  |    │   ├── photo/ | ||||||
|  |    │   │   ├── __init__.py | ||||||
|  |    │   │   ├── containers.py | ||||||
|  |    │   │   ├── entities.py | ||||||
|  |    │   │   └── repositories.py | ||||||
|  |    │   ├── user/ | ||||||
|  |    │   │   ├── __init__.py | ||||||
|  |    │   │   ├── containers.py | ||||||
|  |    │   │   ├── entities.py | ||||||
|  |    │   │   └── repositories.py | ||||||
|  |    │   ├── __init__.py | ||||||
|  |    │   ├── __main__.py | ||||||
|  |    │   └── containers.py | ||||||
|  |    ├── config.ini | ||||||
|  |    └── requirements.txt | ||||||
|  | 
 | ||||||
|  | Package containers | ||||||
|  | ------------------ | ||||||
|  | 
 | ||||||
|  | Listing of the ``example/user/containers.py``: | ||||||
|  | 
 | ||||||
|  | .. literalinclude:: ../../examples/miniapps/decoupled-packages/example/user/containers.py | ||||||
|  |    :language: python | ||||||
|  | 
 | ||||||
|  | Listing of the ``example/photo/containers.py``: | ||||||
|  | 
 | ||||||
|  | .. literalinclude:: ../../examples/miniapps/decoupled-packages/example/photo/containers.py | ||||||
|  |    :language: python | ||||||
|  | 
 | ||||||
|  | Listing of the ``example/analytics/containers.py``: | ||||||
|  | 
 | ||||||
|  | .. literalinclude:: ../../examples/miniapps/decoupled-packages/example/analytics/containers.py | ||||||
|  |    :language: python | ||||||
|  | 
 | ||||||
|  | Application container | ||||||
|  | --------------------- | ||||||
|  | 
 | ||||||
|  | Application container consists of all packages and 3rd party dependencies. Its role is to wire | ||||||
|  | everything together in a complete application. | ||||||
|  | 
 | ||||||
|  | Listing of the ``example/containers.py``: | ||||||
|  | 
 | ||||||
|  | .. literalinclude:: ../../examples/miniapps/decoupled-packages/example/containers.py | ||||||
|  |    :language: python | ||||||
|  | 
 | ||||||
|  | .. note:: | ||||||
|  |    Package ``analytics`` has dependencies on the repositories from the ``user`` and | ||||||
|  |    ``photo`` packages. This is an example of how you can pass the dependencies from one package | ||||||
|  |    to another. | ||||||
|  | 
 | ||||||
|  | Main module | ||||||
|  | ----------- | ||||||
|  | Listing of the ``example/__main__.py``: | ||||||
|  | 
 | ||||||
|  | .. literalinclude:: ../../examples/miniapps/decoupled-packages/example/__main__.py | ||||||
|  |    :language: python | ||||||
|  | 
 | ||||||
|  | Configuration | ||||||
|  | ------------- | ||||||
|  | 
 | ||||||
|  | Listing of the ``config.ini``: | ||||||
|  | 
 | ||||||
|  | .. literalinclude:: ../../examples/miniapps/decoupled-packages/config.ini | ||||||
|  |    :language: ini | ||||||
|  | 
 | ||||||
|  | Run the application | ||||||
|  | ------------------- | ||||||
|  | 
 | ||||||
|  | You can find the source code and instructions for running on the `Github <https://github.com/ets-labs/python-dependency-injector/tree/master/examples/miniapps/decoupled-packages>`_. | ||||||
|  | 
 | ||||||
|  | .. disqus:: | ||||||
							
								
								
									
										
											BIN
										
									
								
								docs/examples/images/decoupled-packages.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/examples/images/decoupled-packages.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 182 KiB | 
|  | @ -12,5 +12,6 @@ Explore the examples to see the ``Dependency Injector`` in action. | ||||||
| 
 | 
 | ||||||
|     application-single-container |     application-single-container | ||||||
|     application-multiple-containers |     application-multiple-containers | ||||||
|  |     decoupled-packages | ||||||
| 
 | 
 | ||||||
| .. disqus:: | .. disqus:: | ||||||
|  |  | ||||||
|  | @ -7,6 +7,11 @@ that were made in every particular version. | ||||||
| From version 0.7.6 *Dependency Injector* framework strictly  | From version 0.7.6 *Dependency Injector* framework strictly  | ||||||
| follows `Semantic versioning`_ | follows `Semantic versioning`_ | ||||||
| 
 | 
 | ||||||
|  | 3.40.0 | ||||||
|  | ------ | ||||||
|  | - Add "Decoupled packages" example. | ||||||
|  | - Delete "Bundles" examples mini application. | ||||||
|  | 
 | ||||||
| 3.39.0 | 3.39.0 | ||||||
| ------ | ------ | ||||||
| - Add application examples with single and multiple containers. | - Add application examples with single and multiple containers. | ||||||
|  |  | ||||||
|  | @ -1,8 +0,0 @@ | ||||||
| Dependency Injector Bundles example |  | ||||||
| =================================== |  | ||||||
| 
 |  | ||||||
| Instructions for running |  | ||||||
| 
 |  | ||||||
| .. code-block:: bash |  | ||||||
| 
 |  | ||||||
|     python run.py |  | ||||||
|  | @ -1 +0,0 @@ | ||||||
| """Bundles package.""" |  | ||||||
|  | @ -1,20 +0,0 @@ | ||||||
| """Photos bundle.""" |  | ||||||
| 
 |  | ||||||
| from dependency_injector import containers |  | ||||||
| from dependency_injector import providers |  | ||||||
| 
 |  | ||||||
| from . import entities |  | ||||||
| from . import repositories |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class Photos(containers.DeclarativeContainer): |  | ||||||
|     """Photos bundle container.""" |  | ||||||
| 
 |  | ||||||
|     database = providers.Dependency() |  | ||||||
|     file_storage = providers.Dependency() |  | ||||||
| 
 |  | ||||||
|     photo = providers.Factory(entities.Photo) |  | ||||||
|     photo_repository = providers.Singleton(repositories.PhotoRepository, |  | ||||||
|                                            object_factory=photo.provider, |  | ||||||
|                                            fs=file_storage, |  | ||||||
|                                            db=database) |  | ||||||
|  | @ -1,5 +0,0 @@ | ||||||
| """Photos bundle entities module.""" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class Photo: |  | ||||||
|     """Photo entity.""" |  | ||||||
|  | @ -1,11 +0,0 @@ | ||||||
| """Photos bundle entity repositories module.""" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class PhotoRepository: |  | ||||||
|     """Photo entity repository.""" |  | ||||||
| 
 |  | ||||||
|     def __init__(self, object_factory, fs, db): |  | ||||||
|         """Initialize instance.""" |  | ||||||
|         self.object_factory = object_factory |  | ||||||
|         self.fs = fs |  | ||||||
|         self.db = db |  | ||||||
|  | @ -1,18 +0,0 @@ | ||||||
| """Users bundle.""" |  | ||||||
| 
 |  | ||||||
| from dependency_injector import containers |  | ||||||
| from dependency_injector import providers |  | ||||||
| 
 |  | ||||||
| from . import entities |  | ||||||
| from . import repositories |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class Users(containers.DeclarativeContainer): |  | ||||||
|     """Users bundle container.""" |  | ||||||
| 
 |  | ||||||
|     database = providers.Dependency() |  | ||||||
| 
 |  | ||||||
|     user = providers.Factory(entities.User) |  | ||||||
|     user_repository = providers.Singleton(repositories.UserRepository, |  | ||||||
|                                           object_factory=user.provider, |  | ||||||
|                                           db=database) |  | ||||||
|  | @ -1,9 +0,0 @@ | ||||||
| """Users bundle entities module.""" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class User: |  | ||||||
|     """User entity.""" |  | ||||||
| 
 |  | ||||||
|     def __init__(self, id): |  | ||||||
|         """Initialize instance.""" |  | ||||||
|         self.id = id |  | ||||||
|  | @ -1,14 +0,0 @@ | ||||||
| """Users bundle entity repositories module.""" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class UserRepository: |  | ||||||
|     """User entity repository.""" |  | ||||||
| 
 |  | ||||||
|     def __init__(self, object_factory, db): |  | ||||||
|         """Initialize instance.""" |  | ||||||
|         self.object_factory = object_factory |  | ||||||
|         self.db = db |  | ||||||
| 
 |  | ||||||
|     def get(self, id): |  | ||||||
|         """Return user entity with given identifier.""" |  | ||||||
|         return self.object_factory(id=id) |  | ||||||
|  | @ -1,40 +0,0 @@ | ||||||
| """Run 'Bundles' example application.""" |  | ||||||
| 
 |  | ||||||
| import sqlite3 |  | ||||||
| import boto3 |  | ||||||
| 
 |  | ||||||
| from dependency_injector import containers |  | ||||||
| from dependency_injector import providers |  | ||||||
| 
 |  | ||||||
| from bundles.users import Users |  | ||||||
| from bundles.photos import Photos |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| class Core(containers.DeclarativeContainer): |  | ||||||
|     """Core container.""" |  | ||||||
| 
 |  | ||||||
|     config = providers.Configuration('config') |  | ||||||
|     sqlite = providers.Singleton(sqlite3.connect, config.database.dsn) |  | ||||||
|     s3 = providers.Singleton( |  | ||||||
|         boto3.client, 's3', |  | ||||||
|         aws_access_key_id=config.aws.access_key_id, |  | ||||||
|         aws_secret_access_key=config.aws.secret_access_key) |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| if __name__ == '__main__': |  | ||||||
|     # Initializing containers |  | ||||||
|     core = Core(config={'database': {'dsn': ':memory:'}, |  | ||||||
|                         'aws': {'access_key_id': 'KEY', |  | ||||||
|                                 'secret_access_key': 'SECRET'}}) |  | ||||||
|     users = Users(database=core.sqlite) |  | ||||||
|     photos = Photos(database=core.sqlite, file_storage=core.s3) |  | ||||||
| 
 |  | ||||||
|     # Fetching few users |  | ||||||
|     user_repository = users.user_repository() |  | ||||||
|     user1 = user_repository.get(id=1) |  | ||||||
|     user2 = user_repository.get(id=2) |  | ||||||
| 
 |  | ||||||
|     # Making some checks |  | ||||||
|     assert user1.id == 1 |  | ||||||
|     assert user2.id == 2 |  | ||||||
|     assert user_repository.db is core.sqlite() |  | ||||||
							
								
								
									
										29
									
								
								examples/miniapps/decoupled-packages/README.rst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								examples/miniapps/decoupled-packages/README.rst
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,29 @@ | ||||||
|  | Decoupled packages example | ||||||
|  | ========================== | ||||||
|  | 
 | ||||||
|  | Create virtual env: | ||||||
|  | 
 | ||||||
|  | .. code-block:: bash | ||||||
|  | 
 | ||||||
|  |    python3 -m venv venv | ||||||
|  |    . venv/bin/activate | ||||||
|  | 
 | ||||||
|  | Install requirements: | ||||||
|  | 
 | ||||||
|  | .. code-block:: bash | ||||||
|  | 
 | ||||||
|  |    pip install -r requirements.txt | ||||||
|  | 
 | ||||||
|  | Run: | ||||||
|  | 
 | ||||||
|  | .. code-block:: bash | ||||||
|  | 
 | ||||||
|  |    python -m example | ||||||
|  | 
 | ||||||
|  | You should see: | ||||||
|  | 
 | ||||||
|  | .. code-block:: bash | ||||||
|  | 
 | ||||||
|  |    Retrieve user id=1, photos count=5 | ||||||
|  |    Retrieve user id=2, photos count=10 | ||||||
|  |    Aggregate analytics from user and photo bundles | ||||||
							
								
								
									
										6
									
								
								examples/miniapps/decoupled-packages/config.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								examples/miniapps/decoupled-packages/config.ini
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,6 @@ | ||||||
|  | [database] | ||||||
|  | dsn=:memory: | ||||||
|  | 
 | ||||||
|  | [aws] | ||||||
|  | access_key_id=KEY | ||||||
|  | secret_access_key=SECRET | ||||||
							
								
								
									
										1
									
								
								examples/miniapps/decoupled-packages/example/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								examples/miniapps/decoupled-packages/example/__init__.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | """Top-level package.""" | ||||||
							
								
								
									
										24
									
								
								examples/miniapps/decoupled-packages/example/__main__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								examples/miniapps/decoupled-packages/example/__main__.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,24 @@ | ||||||
|  | """Main module.""" | ||||||
|  | 
 | ||||||
|  | from .containers import ApplicationContainer | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == '__main__': | ||||||
|  |     application = ApplicationContainer() | ||||||
|  |     application.config.from_ini('config.ini') | ||||||
|  | 
 | ||||||
|  |     user_repository = application.user_package.user_repository() | ||||||
|  |     photo_repository = application.photo_package.photo_repository() | ||||||
|  | 
 | ||||||
|  |     user1 = user_repository.get(id=1) | ||||||
|  |     user1_photos = photo_repository.get_photos(user1.id) | ||||||
|  |     print(f'Retrieve user id={user1.id}, photos count={len(user1_photos)}') | ||||||
|  | 
 | ||||||
|  |     user2 = user_repository.get(id=2) | ||||||
|  |     user2_photos = photo_repository.get_photos(user2.id) | ||||||
|  |     print(f'Retrieve user id={user2.id}, photos count={len(user2_photos)}') | ||||||
|  | 
 | ||||||
|  |     aggregation_service = application.analytics_package.aggregation_service() | ||||||
|  |     assert aggregation_service.user_repository is user_repository | ||||||
|  |     assert aggregation_service.photo_repository is photo_repository | ||||||
|  |     print('Aggregate analytics from user and photo packages') | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | """Analytics package.""" | ||||||
|  | @ -0,0 +1,17 @@ | ||||||
|  | """Analytics containers module.""" | ||||||
|  | 
 | ||||||
|  | from dependency_injector import containers, providers | ||||||
|  | 
 | ||||||
|  | from . import services | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class AnalyticsContainer(containers.DeclarativeContainer): | ||||||
|  | 
 | ||||||
|  |     user_repository = providers.Dependency() | ||||||
|  |     photo_repository = providers.Dependency() | ||||||
|  | 
 | ||||||
|  |     aggregation_service = providers.Singleton( | ||||||
|  |         services.AggregationService, | ||||||
|  |         user_repository=user_repository, | ||||||
|  |         photo_repository=photo_repository, | ||||||
|  |     ) | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | """Analytics services module.""" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class AggregationService: | ||||||
|  | 
 | ||||||
|  |     def __init__(self, user_repository, photo_repository): | ||||||
|  |         self.user_repository = user_repository | ||||||
|  |         self.photo_repository = photo_repository | ||||||
							
								
								
									
										41
									
								
								examples/miniapps/decoupled-packages/example/containers.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								examples/miniapps/decoupled-packages/example/containers.py
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | ||||||
|  | """Containers module.""" | ||||||
|  | 
 | ||||||
|  | import sqlite3 | ||||||
|  | 
 | ||||||
|  | import boto3 | ||||||
|  | from dependency_injector import containers, providers | ||||||
|  | 
 | ||||||
|  | from .user.containers import UserContainer | ||||||
|  | from .photo.containers import PhotoContainer | ||||||
|  | from .analytics.containers import AnalyticsContainer | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ApplicationContainer(containers.DeclarativeContainer): | ||||||
|  | 
 | ||||||
|  |     config = providers.Configuration() | ||||||
|  | 
 | ||||||
|  |     sqlite = providers.Singleton(sqlite3.connect, config.database.dsn) | ||||||
|  | 
 | ||||||
|  |     s3 = providers.Singleton( | ||||||
|  |         boto3.client, | ||||||
|  |         service_name='s3', | ||||||
|  |         aws_access_key_id=config.aws.access_key_id, | ||||||
|  |         aws_secret_access_key=config.aws.secret_access_key, | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     user_package = providers.Container( | ||||||
|  |         UserContainer, | ||||||
|  |         database=sqlite, | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     photo_package = providers.Container( | ||||||
|  |         PhotoContainer, | ||||||
|  |         database=sqlite, | ||||||
|  |         file_storage=s3, | ||||||
|  |     ) | ||||||
|  | 
 | ||||||
|  |     analytics_package = providers.Container( | ||||||
|  |         AnalyticsContainer, | ||||||
|  |         user_repository=user_package.user_repository, | ||||||
|  |         photo_repository=photo_package.photo_repository, | ||||||
|  |     ) | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | """Photo package.""" | ||||||
|  | @ -0,0 +1,20 @@ | ||||||
|  | """Photo containers module.""" | ||||||
|  | 
 | ||||||
|  | from dependency_injector import containers, providers | ||||||
|  | 
 | ||||||
|  | from . import entities, repositories | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class PhotoContainer(containers.DeclarativeContainer): | ||||||
|  | 
 | ||||||
|  |     database = providers.Dependency() | ||||||
|  |     file_storage = providers.Dependency() | ||||||
|  | 
 | ||||||
|  |     photo = providers.Factory(entities.Photo) | ||||||
|  | 
 | ||||||
|  |     photo_repository = providers.Singleton( | ||||||
|  |         repositories.PhotoRepository, | ||||||
|  |         entity_factory=photo.provider, | ||||||
|  |         fs=file_storage, | ||||||
|  |         db=database, | ||||||
|  |     ) | ||||||
|  | @ -0,0 +1,5 @@ | ||||||
|  | """Photo entities module.""" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Photo: | ||||||
|  |     ... | ||||||
|  | @ -0,0 +1,12 @@ | ||||||
|  | """Photo repositories module.""" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class PhotoRepository: | ||||||
|  | 
 | ||||||
|  |     def __init__(self, entity_factory, fs, db): | ||||||
|  |         self.entity_factory = entity_factory | ||||||
|  |         self.fs = fs | ||||||
|  |         self.db = db | ||||||
|  | 
 | ||||||
|  |     def get_photos(self, user_id): | ||||||
|  |         return [self.entity_factory() for _ in range(user_id*5)] | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | """User package.""" | ||||||
|  | @ -0,0 +1,18 @@ | ||||||
|  | """User containers module.""" | ||||||
|  | 
 | ||||||
|  | from dependency_injector import containers, providers | ||||||
|  | 
 | ||||||
|  | from . import entities, repositories | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class UserContainer(containers.DeclarativeContainer): | ||||||
|  | 
 | ||||||
|  |     database = providers.Dependency() | ||||||
|  | 
 | ||||||
|  |     user = providers.Factory(entities.User) | ||||||
|  | 
 | ||||||
|  |     user_repository = providers.Singleton( | ||||||
|  |         repositories.UserRepository, | ||||||
|  |         entity_factory=user.provider, | ||||||
|  |         db=database, | ||||||
|  |     ) | ||||||
|  | @ -0,0 +1,7 @@ | ||||||
|  | """User entities module.""" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class User: | ||||||
|  | 
 | ||||||
|  |     def __init__(self, id): | ||||||
|  |         self.id = id | ||||||
|  | @ -0,0 +1,11 @@ | ||||||
|  | """User repositories module.""" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class UserRepository: | ||||||
|  | 
 | ||||||
|  |     def __init__(self, entity_factory, db): | ||||||
|  |         self.entity_factory = entity_factory | ||||||
|  |         self.db = db | ||||||
|  | 
 | ||||||
|  |     def get(self, id): | ||||||
|  |         return self.entity_factory(id=id) | ||||||
							
								
								
									
										2
									
								
								examples/miniapps/decoupled-packages/requirements.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								examples/miniapps/decoupled-packages/requirements.txt
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | dependency-injector | ||||||
|  | boto3 | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| """Dependency injector top-level package.""" | """Dependency injector top-level package.""" | ||||||
| 
 | 
 | ||||||
| __version__ = '3.39.0' | __version__ = '3.40.0' | ||||||
| """Version number that follows semantic versioning. | """Version number that follows semantic versioning. | ||||||
| 
 | 
 | ||||||
| :type: str | :type: str | ||||||
|  |  | ||||||
|  | @ -59,7 +59,7 @@ class Delegate(Provider): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class Dependency(Provider, Generic[T]): | class Dependency(Provider, Generic[T]): | ||||||
|     def __init__(self, instance_of: Type[T]) -> None: ... |     def __init__(self, instance_of: Type[T] = object) -> None: ... | ||||||
|     def __call__(self, *args: Injection, **kwargs: Injection) -> T: ... |     def __call__(self, *args: Injection, **kwargs: Injection) -> T: ... | ||||||
|     @property |     @property | ||||||
|     def provided(self) -> ProvidedInstance: ... |     def provided(self) -> ProvidedInstance: ... | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user