mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 09:57:37 +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 
 | 
			
		||||
                 "Dependency Injector" framework.
 | 
			
		||||
 | 
			
		||||
Current section of documentation is designed to provide several example mini 
 | 
			
		||||
applications that are built according to the inversion of control principle 
 | 
			
		||||
and powered by *Dependency Injector* framework.
 | 
			
		||||
This sections contains assorted ``Dependency Injector`` examples.
 | 
			
		||||
 | 
			
		||||
..  toctree::
 | 
			
		||||
    :maxdepth: 2
 | 
			
		||||
 | 
			
		||||
    bundles_miniapp
 | 
			
		||||
    use_cases_miniapp
 | 
			
		||||
    password_hashing_miniapp
 | 
			
		||||
    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-multiple-containers
 | 
			
		||||
    decoupled-packages
 | 
			
		||||
 | 
			
		||||
.. disqus::
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,11 @@ that were made in every particular version.
 | 
			
		|||
From version 0.7.6 *Dependency Injector* framework strictly 
 | 
			
		||||
follows `Semantic versioning`_
 | 
			
		||||
 | 
			
		||||
3.40.0
 | 
			
		||||
------
 | 
			
		||||
- Add "Decoupled packages" example.
 | 
			
		||||
- Delete "Bundles" examples mini application.
 | 
			
		||||
 | 
			
		||||
3.39.0
 | 
			
		||||
------
 | 
			
		||||
- 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."""
 | 
			
		||||
 | 
			
		||||
__version__ = '3.39.0'
 | 
			
		||||
__version__ = '3.40.0'
 | 
			
		||||
"""Version number that follows semantic versioning.
 | 
			
		||||
 | 
			
		||||
:type: str
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -59,7 +59,7 @@ class Delegate(Provider):
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
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: ...
 | 
			
		||||
    @property
 | 
			
		||||
    def provided(self) -> ProvidedInstance: ...
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user