mirror of
				https://github.com/ets-labs/python-dependency-injector.git
				synced 2025-11-04 01:47:36 +03:00 
			
		
		
		
	Update examples and docs
This commit is contained in:
		
							parent
							
								
									bd5ea87ef7
								
							
						
					
					
						commit
						4cf3bdb1fb
					
				
							
								
								
									
										273
									
								
								README.rst
									
									
									
									
									
								
							
							
						
						
									
										273
									
								
								README.rst
									
									
									
									
									
								
							| 
						 | 
					@ -55,259 +55,66 @@ Installation
 | 
				
			||||||
Examples
 | 
					Examples
 | 
				
			||||||
--------
 | 
					--------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
API client example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code-block:: python
 | 
					.. code-block:: python
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    """Pythonic way for Dependency Injection - API Client."""
 | 
					    """Dependency Injector initial example."""
 | 
				
			||||||
 | 
					 | 
				
			||||||
    from dependency_injector import providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    from mock import Mock
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class ApiClient(object):
 | 
					 | 
				
			||||||
        """Some API client."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def __init__(self, host, api_key):
 | 
					 | 
				
			||||||
            """Initializer."""
 | 
					 | 
				
			||||||
            self.host = host
 | 
					 | 
				
			||||||
            self.api_key = api_key
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def call(self, operation, data):
 | 
					 | 
				
			||||||
            """Make some network operations."""
 | 
					 | 
				
			||||||
            print 'API call [{0}:{1}], method - {2}, data - {3}'.format(
 | 
					 | 
				
			||||||
                self.host, self.api_key, operation, repr(data))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class User(object):
 | 
					 | 
				
			||||||
        """User model."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def __init__(self, id, api_client):
 | 
					 | 
				
			||||||
            """Initializer."""
 | 
					 | 
				
			||||||
            self.id = id
 | 
					 | 
				
			||||||
            self.api_client = api_client
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def register(self):
 | 
					 | 
				
			||||||
            """Register user."""
 | 
					 | 
				
			||||||
            self.api_client.call('register', {'id': self.id})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Creating ApiClient and User providers:
 | 
					 | 
				
			||||||
    api_client = providers.Singleton(ApiClient,
 | 
					 | 
				
			||||||
                                     host='production.com',
 | 
					 | 
				
			||||||
                                     api_key='PROD_API_KEY')
 | 
					 | 
				
			||||||
    user_factory = providers.Factory(User,
 | 
					 | 
				
			||||||
                                     api_client=api_client)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Creating several users and register them:
 | 
					 | 
				
			||||||
    user1 = user_factory(1)
 | 
					 | 
				
			||||||
    user1.register()
 | 
					 | 
				
			||||||
    # API call [production.com:PROD_API_KEY], method - register, data - {'id': 1}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    user2 = user_factory(2)
 | 
					 | 
				
			||||||
    user2.register()
 | 
					 | 
				
			||||||
    # API call [production.com:PROD_API_KEY], method - register, data - {'id': 2}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Mock ApiClient for testing:
 | 
					 | 
				
			||||||
    with api_client.override(Mock(ApiClient)) as api_client_mock:
 | 
					 | 
				
			||||||
        user = user_factory('test')
 | 
					 | 
				
			||||||
        user.register()
 | 
					 | 
				
			||||||
        api_client_mock().call.assert_called_with('register', {'id': 'test'})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Overriding of ApiClient on dev environment:
 | 
					 | 
				
			||||||
    api_client.override(providers.Singleton(ApiClient,
 | 
					 | 
				
			||||||
                                            host='localhost',
 | 
					 | 
				
			||||||
                                            api_key='DEV_API_KEY'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    user3 = user_factory(3)
 | 
					 | 
				
			||||||
    user3.register()
 | 
					 | 
				
			||||||
    # API call [localhost:DEV_API_KEY], method - register, data - {'id': 3}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Auth system example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    """Pythonic way for Dependency Injection - Auth System."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    from dependency_injector import providers
 | 
					 | 
				
			||||||
    from dependency_injector import injections
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @providers.DelegatedCallable
 | 
					 | 
				
			||||||
    def get_user_info(user_id):
 | 
					 | 
				
			||||||
        """Return user info."""
 | 
					 | 
				
			||||||
        raise NotImplementedError()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @providers.Factory
 | 
					 | 
				
			||||||
    @injections.inject(get_user_info=get_user_info)
 | 
					 | 
				
			||||||
    class AuthComponent(object):
 | 
					 | 
				
			||||||
        """Some authentication component."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def __init__(self, get_user_info):
 | 
					 | 
				
			||||||
            """Initializer."""
 | 
					 | 
				
			||||||
            self.get_user_info = get_user_info
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def authenticate_user(self, token):
 | 
					 | 
				
			||||||
            """Authenticate user by token."""
 | 
					 | 
				
			||||||
            user_info = self.get_user_info(user_id=token + '1')
 | 
					 | 
				
			||||||
            return user_info
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    print AuthComponent
 | 
					 | 
				
			||||||
    print get_user_info
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @providers.override(get_user_info)
 | 
					 | 
				
			||||||
    @providers.DelegatedCallable
 | 
					 | 
				
			||||||
    def get_user_info(user_id):
 | 
					 | 
				
			||||||
        """Return user info."""
 | 
					 | 
				
			||||||
        return {'user_id': user_id}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    print AuthComponent().authenticate_user(token='abc')
 | 
					 | 
				
			||||||
    # {'user_id': 'abc1'}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Service providers catalog example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    """Pythonic way for Dependency Injection - Service Providers Catalog."""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    import sys
 | 
				
			||||||
    import sqlite3
 | 
					    import sqlite3
 | 
				
			||||||
 | 
					    import boto.s3.connection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    import services
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    from dependency_injector import catalogs
 | 
					    from dependency_injector import catalogs
 | 
				
			||||||
    from dependency_injector import providers
 | 
					    from dependency_injector import providers
 | 
				
			||||||
    from dependency_injector import injections
 | 
					    from dependency_injector import injections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class UsersService(object):
 | 
					    class Platform(catalogs.DeclarativeCatalog):
 | 
				
			||||||
        """Users service, that has dependency on database."""
 | 
					        """Catalog of platform service providers."""
 | 
				
			||||||
 | 
					 | 
				
			||||||
        def __init__(self, db):
 | 
					 | 
				
			||||||
            """Initializer."""
 | 
					 | 
				
			||||||
            self.db = db
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class AuthService(object):
 | 
					 | 
				
			||||||
        """Auth service, that has dependencies on users service and database."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def __init__(self, db, users_service):
 | 
					 | 
				
			||||||
            """Initializer."""
 | 
					 | 
				
			||||||
            self.db = db
 | 
					 | 
				
			||||||
            self.users_service = users_service
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class Services(catalogs.DeclarativeCatalog):
 | 
					 | 
				
			||||||
        """Catalog of service providers."""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
					        database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        users = providers.Factory(UsersService,
 | 
					        s3 = providers.Singleton(boto.s3.connection.S3Connection,
 | 
				
			||||||
                                  db=database)
 | 
					                                 aws_access_key_id='KEY',
 | 
				
			||||||
 | 
					                                 aws_secret_access_key='SECRET')
 | 
				
			||||||
        auth = providers.Factory(AuthService,
 | 
					 | 
				
			||||||
                                 db=database,
 | 
					 | 
				
			||||||
                                 users_service=users)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Retrieving catalog providers:
 | 
					 | 
				
			||||||
    users_service = Services.users()
 | 
					 | 
				
			||||||
    auth_service = Services.auth()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Making some asserts:
 | 
					 | 
				
			||||||
    assert users_service.db is auth_service.db is Services.database()
 | 
					 | 
				
			||||||
    assert isinstance(auth_service.users_service, UsersService)
 | 
					 | 
				
			||||||
    assert users_service is not Services.users()
 | 
					 | 
				
			||||||
    assert auth_service is not Services.auth()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Making some "inline" injections:
 | 
					 | 
				
			||||||
    @injections.inject(users_service=Services.users)
 | 
					 | 
				
			||||||
    @injections.inject(auth_service=Services.auth)
 | 
					 | 
				
			||||||
    @injections.inject(database=Services.database)
 | 
					 | 
				
			||||||
    def example(users_service, auth_service, database):
 | 
					 | 
				
			||||||
        """Example callback."""
 | 
					 | 
				
			||||||
        assert users_service.db is auth_service.db
 | 
					 | 
				
			||||||
        assert auth_service.db is database
 | 
					 | 
				
			||||||
        assert database is Services.database()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # Making a call of decorated callback:
 | 
					 | 
				
			||||||
    example()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Providing callbacks catalog example:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.. code-block:: python
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    """Pythonic way for Dependency Injection - Providing Callbacks Catalog."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    import sqlite3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    from dependency_injector import catalogs
 | 
					 | 
				
			||||||
    from dependency_injector import providers
 | 
					 | 
				
			||||||
    from dependency_injector import injections
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class UsersService(object):
 | 
					 | 
				
			||||||
        """Users service, that has dependency on database."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def __init__(self, db):
 | 
					 | 
				
			||||||
            """Initializer."""
 | 
					 | 
				
			||||||
            self.db = db
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class AuthService(object):
 | 
					 | 
				
			||||||
        """Auth service, that has dependencies on users service and database."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        def __init__(self, db, users_service):
 | 
					 | 
				
			||||||
            """Initializer."""
 | 
					 | 
				
			||||||
            self.db = db
 | 
					 | 
				
			||||||
            self.users_service = users_service
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Services(catalogs.DeclarativeCatalog):
 | 
					    class Services(catalogs.DeclarativeCatalog):
 | 
				
			||||||
        """Catalog of service providers."""
 | 
					        """Catalog of business service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @providers.Singleton
 | 
					        users = providers.Factory(services.Users,
 | 
				
			||||||
        def database():
 | 
					                                  db=Platform.database)
 | 
				
			||||||
            """Provide database connection.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            :rtype: providers.Provider -> sqlite3.Connection
 | 
					        photos = providers.Factory(services.Photos,
 | 
				
			||||||
            """
 | 
					                                   db=Platform.database,
 | 
				
			||||||
            return sqlite3.connect(':memory:')
 | 
					                                   s3=Platform.s3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        @providers.Factory
 | 
					        auth = providers.Factory(services.Auth,
 | 
				
			||||||
        @injections.inject(db=database)
 | 
					                                 db=Platform.database,
 | 
				
			||||||
        def users(**kwargs):
 | 
					                                 token_ttl=3600)
 | 
				
			||||||
            """Provide users service.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            :rtype: providers.Provider -> UsersService
 | 
					 | 
				
			||||||
            """
 | 
					 | 
				
			||||||
            return UsersService(**kwargs)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @providers.Factory
 | 
					 | 
				
			||||||
        @injections.inject(db=database)
 | 
					 | 
				
			||||||
        @injections.inject(users_service=users)
 | 
					 | 
				
			||||||
        def auth(**kwargs):
 | 
					 | 
				
			||||||
            """Provide users service.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            :rtype: providers.Provider -> AuthService
 | 
					 | 
				
			||||||
            """
 | 
					 | 
				
			||||||
            return AuthService(**kwargs)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Retrieving catalog providers:
 | 
					    @injections.inject(users_service=Services.users)
 | 
				
			||||||
    users_service = Services.users()
 | 
					    @injections.inject(auth_service=Services.auth)
 | 
				
			||||||
    auth_service = Services.auth()
 | 
					    def main(argv, users_service, auth_service):
 | 
				
			||||||
 | 
					        """Main function."""
 | 
				
			||||||
 | 
					        login, password, photo_path = argv[1:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Making some asserts:
 | 
					        user = users_service.get_user(login)
 | 
				
			||||||
    assert users_service.db is auth_service.db is Services.database()
 | 
					        auth_service.authenticate(user, password)
 | 
				
			||||||
    assert isinstance(auth_service.users_service, UsersService)
 | 
					
 | 
				
			||||||
    assert users_service is not Services.users()
 | 
					        upload_photo(user, photo_path)
 | 
				
			||||||
    assert auth_service is not Services.auth()
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @injections.inject(photos_service=Services.photos)
 | 
				
			||||||
 | 
					    def upload_photo(user, photo_path, photos_service):
 | 
				
			||||||
 | 
					        """Upload photo."""
 | 
				
			||||||
 | 
					        photos_service.upload_photo(user['id'], photo_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if __name__ == '__main__':
 | 
				
			||||||
 | 
					        main(sys.argv)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
You can get more *Dependency Injector* examples in ``/examples`` directory on
 | 
					You can get more *Dependency Injector* examples in ``/examples`` directory on
 | 
				
			||||||
GitHub:
 | 
					GitHub:
 | 
				
			||||||
| 
						 | 
					@ -334,8 +141,8 @@ Your feedback is quite important!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. _PyPi: https://pypi.python.org/pypi/dependency_injector
 | 
					.. _PyPi: https://pypi.python.org/pypi/dependency_injector
 | 
				
			||||||
.. _User's guide: http://dependency_injector.readthedocs.org/en/stable/
 | 
					.. _User's guide: http://dependency-injector.ets-labs.org/en/stable/
 | 
				
			||||||
.. _API docs: http://dependency-injector.readthedocs.org/en/stable/api/
 | 
					.. _API docs: http://dependency-injector.ets-labs.org/en/stable/api/
 | 
				
			||||||
.. _SLOC: http://en.wikipedia.org/wiki/Source_lines_of_code
 | 
					.. _SLOC: http://en.wikipedia.org/wiki/Source_lines_of_code
 | 
				
			||||||
.. _SOLID: http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29
 | 
					.. _SOLID: http://en.wikipedia.org/wiki/SOLID_%28object-oriented_design%29
 | 
				
			||||||
.. _IoC: http://en.wikipedia.org/wiki/Inversion_of_control
 | 
					.. _IoC: http://en.wikipedia.org/wiki/Inversion_of_control
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,18 @@
 | 
				
			||||||
 | 
					Examples
 | 
				
			||||||
 | 
					========
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. meta::
 | 
				
			||||||
 | 
					   :keywords: Python,DI,Dependency injection,IoC,Inversion of Control
 | 
				
			||||||
 | 
					   :description: Current section of documentation is designed to provide 
 | 
				
			||||||
 | 
					                 several example mini applications that are built on the top 
 | 
				
			||||||
 | 
					                 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 on the top of inversion of control principle and 
 | 
				
			||||||
 | 
					powered by *Dependency Injector* framework.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					..  toctree::
 | 
				
			||||||
 | 
					    :maxdepth: 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    movie_lister
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,104 @@
 | 
				
			||||||
 | 
					Movie lister naive example
 | 
				
			||||||
 | 
					--------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. meta::
 | 
				
			||||||
 | 
					   :description: Dependency Injector is a Python dependency injection 
 | 
				
			||||||
 | 
					                 framework. It was designed to be unified, developer's 
 | 
				
			||||||
 | 
					                 friendly tool for managing any kind of Python objects and 
 | 
				
			||||||
 | 
					                 their dependencies in formal, pretty way.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This naive example was taken from Martin Fowler's article about dependency 
 | 
				
			||||||
 | 
					injection and inversion of control: http://www.martinfowler.com/articles/injection.html
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Like Martin says:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. pull-quote::
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    *Like all of my examples it's one of those super-simple examples; 
 | 
				
			||||||
 | 
					    small enough to be unreal, but hopefully enough for you to visualize 
 | 
				
			||||||
 | 
					    what's going on without falling into the bog of a real example.*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					While original Martin's MovieLister example was a bit modified here, it 
 | 
				
			||||||
 | 
					makes sense to provide some description. So, the idea of this example is to 
 | 
				
			||||||
 | 
					create ``movies`` library that can be configurable to work with different 
 | 
				
			||||||
 | 
					movie databases (csv, sqlite) and provide 2 main features:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. List all movies that were directed by certain person.
 | 
				
			||||||
 | 
					2. List all movies that were released in certain year.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Also this example contains 3 mini applications that are based on ``movies`` 
 | 
				
			||||||
 | 
					library :
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. ``app_csv.py`` - list movies by certain criteria from csv file database.
 | 
				
			||||||
 | 
					2. ``app_db.py`` - list movies by certain criteria from sqlite database.
 | 
				
			||||||
 | 
					3. ``app_db_csv.py`` - list movies by certain criteria from csv file and 
 | 
				
			||||||
 | 
					   sqlite databases.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Instructions for running:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    python create_db.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    python app_csv.py
 | 
				
			||||||
 | 
					    python app_db.py
 | 
				
			||||||
 | 
					    python app_db_csv.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Full code of example could be found on GitHub_. 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Movies library
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Classes diagram:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. image:: /images/miniapps/movie_lister/classes.png
 | 
				
			||||||
 | 
					    :width: 100%
 | 
				
			||||||
 | 
					    :align: center
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Movies library structure:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. code-block:: bash
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /movies
 | 
				
			||||||
 | 
					        /__init__.py
 | 
				
			||||||
 | 
					        /finders.py
 | 
				
			||||||
 | 
					        /listers.py
 | 
				
			||||||
 | 
					        /models.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Listing of ``movies/__init__.py``:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/miniapps/movie_lister/movies/__init__.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Csv application
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Listing of ``app_csv.py``:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/miniapps/movie_lister/app_csv.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Database application
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Listing of ``app_db.py``:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/miniapps/movie_lister/app_db.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Csv and database application
 | 
				
			||||||
 | 
					~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Listing of ``app_db_csv.py``:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. literalinclude:: ../../examples/miniapps/movie_lister/app_db_csv.py
 | 
				
			||||||
 | 
					   :language: python
 | 
				
			||||||
 | 
					   :linenos:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.. _GitHub: https://github.com/ets-labs/dependency_injector/tree/master/examples/miniapps/movie_lister
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								docs/images/miniapps/movie_lister/classes.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								docs/images/miniapps/movie_lister/classes.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 34 KiB  | 
| 
						 | 
					@ -2,8 +2,7 @@ Dependency Injector --- Python dependency injection framework
 | 
				
			||||||
=============================================================
 | 
					=============================================================
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. meta::
 | 
					.. meta::
 | 
				
			||||||
   :keywords: Python,DI,Dependency injection,IoC,Inversion of Control
 | 
					   :google-site-verification: 6it89zX0_wccKEhAqbAiYQooS95f0BA8YfesHk6bsNA
 | 
				
			||||||
   :google-site-verification: mPdgVBidFHVWRNh0lhxj7q9zi-CpwIU970jINTBKLYQ
 | 
					 | 
				
			||||||
   :description: Dependency Injector is a Python dependency injection 
 | 
					   :description: Dependency Injector is a Python dependency injection 
 | 
				
			||||||
                 framework. It was designed to be unified, developer's 
 | 
					                 framework. It was designed to be unified, developer's 
 | 
				
			||||||
                 friendly tool for managing any kind of Python objects and 
 | 
					                 friendly tool for managing any kind of Python objects and 
 | 
				
			||||||
| 
						 | 
					@ -63,6 +62,7 @@ Contents
 | 
				
			||||||
    providers/index
 | 
					    providers/index
 | 
				
			||||||
    catalogs/index
 | 
					    catalogs/index
 | 
				
			||||||
    advanced_usage/index
 | 
					    advanced_usage/index
 | 
				
			||||||
 | 
					    examples/index
 | 
				
			||||||
    api/index
 | 
					    api/index
 | 
				
			||||||
    main/feedback
 | 
					    main/feedback
 | 
				
			||||||
    main/changelog
 | 
					    main/changelog
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@ Dependency injection and inversion of control in Python
 | 
				
			||||||
-------------------------------------------------------
 | 
					-------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. meta::
 | 
					.. meta::
 | 
				
			||||||
   :keywords: Python,DI,Dependency injection,IoC,Inversion of Control
 | 
					 | 
				
			||||||
   :description: This article describes benefits of dependency injection and 
 | 
					   :description: This article describes benefits of dependency injection and 
 | 
				
			||||||
                 inversion of control for Python applications. Also it 
 | 
					                 inversion of control for Python applications. Also it 
 | 
				
			||||||
                 contains some Python examples that show how dependency 
 | 
					                 contains some Python examples that show how dependency 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@ Introduction
 | 
				
			||||||
============
 | 
					============
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. meta::
 | 
					.. meta::
 | 
				
			||||||
   :keywords: Python,DI,Dependency injection,IoC,Inversion of Control
 | 
					 | 
				
			||||||
   :description: Current section of documentation is designed to give some 
 | 
					   :description: Current section of documentation is designed to give some 
 | 
				
			||||||
                 overview about dependency injection pattern, inversion of 
 | 
					                 overview about dependency injection pattern, inversion of 
 | 
				
			||||||
                 control principle and "Dependency Injector" framework.
 | 
					                 control principle and "Dependency Injector" framework.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@ Key features of Dependency Injector
 | 
				
			||||||
-----------------------------------
 | 
					-----------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. meta::
 | 
					.. meta::
 | 
				
			||||||
   :keywords: Python,DI,Dependency injection,IoC,Inversion of Control
 | 
					 | 
				
			||||||
   :description: This article describes key features of "Dependency Injector" 
 | 
					   :description: This article describes key features of "Dependency Injector" 
 | 
				
			||||||
                 framework. It also provides some cases and recommendations 
 | 
					                 framework. It also provides some cases and recommendations 
 | 
				
			||||||
                 about usage of "Dependency Injector" framework.
 | 
					                 about usage of "Dependency Injector" framework.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@ Structure of Dependency Injector
 | 
				
			||||||
--------------------------------
 | 
					--------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. meta::
 | 
					.. meta::
 | 
				
			||||||
   :keywords: Python,DI,Dependency injection,IoC,Inversion of Control
 | 
					 | 
				
			||||||
   :description: This article describes "Dependency Injector" framework 
 | 
					   :description: This article describes "Dependency Injector" framework 
 | 
				
			||||||
                 components and their interaction between each other. 
 | 
					                 components and their interaction between each other. 
 | 
				
			||||||
                 Catalogs, providers and injections are the former 
 | 
					                 Catalogs, providers and injections are the former 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,6 @@ What is dependency injection and inversion of control?
 | 
				
			||||||
------------------------------------------------------
 | 
					------------------------------------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.. meta::
 | 
					.. meta::
 | 
				
			||||||
   :keywords: Python,DI,Dependency injection,IoC,Inversion of Control
 | 
					 | 
				
			||||||
   :description: This article provides definition of dependency injection, 
 | 
					   :description: This article provides definition of dependency injection, 
 | 
				
			||||||
                 inversion of control and dependency inversion. It contains 
 | 
					                 inversion of control and dependency inversion. It contains 
 | 
				
			||||||
                 example code in Python that is refactored to be following 
 | 
					                 example code in Python that is refactored to be following 
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,8 @@ Development version
 | 
				
			||||||
-------------------
 | 
					-------------------
 | 
				
			||||||
- Add ``@copy`` decorator for copying declarative catalog providers.
 | 
					- Add ``@copy`` decorator for copying declarative catalog providers.
 | 
				
			||||||
- Add line numbers for all code samples in documentation.
 | 
					- Add line numbers for all code samples in documentation.
 | 
				
			||||||
 | 
					- Move project documentation into organisation's domain 
 | 
				
			||||||
 | 
					  (dependency-injector.ets-labs.org).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1.15.2
 | 
					1.15.2
 | 
				
			||||||
------
 | 
					------
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +24,6 @@ class Catalog(catalogs.DeclarativeCatalog):
 | 
				
			||||||
                                 fee=config.FEE,
 | 
					                                 fee=config.FEE,
 | 
				
			||||||
                                 price=config.PRICE,
 | 
					                                 price=config.PRICE,
 | 
				
			||||||
                                 timezone=config.GLOBAL.TIMEZONE)
 | 
					                                 timezone=config.GLOBAL.TIMEZONE)
 | 
				
			||||||
    """:type: providers.Provider -> ObjectA"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Setting config value and making some tests.
 | 
					# Setting config value and making some tests.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,65 +0,0 @@
 | 
				
			||||||
"""Pythonic way for Dependency Injection - API Client."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import providers
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from mock import Mock
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class ApiClient(object):
 | 
					 | 
				
			||||||
    """Some API client."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, host, api_key):
 | 
					 | 
				
			||||||
        """Initializer."""
 | 
					 | 
				
			||||||
        self.host = host
 | 
					 | 
				
			||||||
        self.api_key = api_key
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def call(self, operation, data):
 | 
					 | 
				
			||||||
        """Make some network operations."""
 | 
					 | 
				
			||||||
        print 'API call [{0}:{1}], method - {2}, data - {3}'.format(
 | 
					 | 
				
			||||||
            self.host, self.api_key, operation, repr(data))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class User(object):
 | 
					 | 
				
			||||||
    """User model."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, id, api_client):
 | 
					 | 
				
			||||||
        """Initializer."""
 | 
					 | 
				
			||||||
        self.id = id
 | 
					 | 
				
			||||||
        self.api_client = api_client
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def register(self):
 | 
					 | 
				
			||||||
        """Register user."""
 | 
					 | 
				
			||||||
        self.api_client.call('register', {'id': self.id})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Creating ApiClient and User providers:
 | 
					 | 
				
			||||||
api_client = providers.Singleton(ApiClient,
 | 
					 | 
				
			||||||
                                 host='production.com',
 | 
					 | 
				
			||||||
                                 api_key='PROD_API_KEY')
 | 
					 | 
				
			||||||
user_factory = providers.Factory(User,
 | 
					 | 
				
			||||||
                                 api_client=api_client)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Creating several users and register them:
 | 
					 | 
				
			||||||
user1 = user_factory(1)
 | 
					 | 
				
			||||||
user1.register()
 | 
					 | 
				
			||||||
# API call [production.com:PROD_API_KEY], method - register, data - {'id': 1}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
user2 = user_factory(2)
 | 
					 | 
				
			||||||
user2.register()
 | 
					 | 
				
			||||||
# API call [production.com:PROD_API_KEY], method - register, data - {'id': 2}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Mock ApiClient for testing:
 | 
					 | 
				
			||||||
with api_client.override(Mock(ApiClient)) as api_client_mock:
 | 
					 | 
				
			||||||
    user = user_factory('test')
 | 
					 | 
				
			||||||
    user.register()
 | 
					 | 
				
			||||||
    api_client_mock().call.assert_called_with('register', {'id': 'test'})
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Overriding of ApiClient on dev environment:
 | 
					 | 
				
			||||||
api_client.override(providers.Singleton(ApiClient,
 | 
					 | 
				
			||||||
                                        host='localhost',
 | 
					 | 
				
			||||||
                                        api_key='DEV_API_KEY'))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
user3 = user_factory(3)
 | 
					 | 
				
			||||||
user3.register()
 | 
					 | 
				
			||||||
# API call [localhost:DEV_API_KEY], method - register, data - {'id': 3}
 | 
					 | 
				
			||||||
| 
						 | 
					@ -1,63 +0,0 @@
 | 
				
			||||||
"""Pythonic way for Dependency Injection - Service Providers Catalog."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import sqlite3
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
from dependency_injector import catalogs
 | 
					 | 
				
			||||||
from dependency_injector import providers
 | 
					 | 
				
			||||||
from dependency_injector import injections
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class UsersService(object):
 | 
					 | 
				
			||||||
    """Users service, that has dependency on database."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, db):
 | 
					 | 
				
			||||||
        """Initializer."""
 | 
					 | 
				
			||||||
        self.db = db
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class AuthService(object):
 | 
					 | 
				
			||||||
    """Auth service, that has dependencies on users service and database."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    def __init__(self, db, users_service):
 | 
					 | 
				
			||||||
        """Initializer."""
 | 
					 | 
				
			||||||
        self.db = db
 | 
					 | 
				
			||||||
        self.users_service = users_service
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class Services(catalogs.DeclarativeCatalog):
 | 
					 | 
				
			||||||
    """Catalog of service providers."""
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    users = providers.Factory(UsersService,
 | 
					 | 
				
			||||||
                              db=database)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    auth = providers.Factory(AuthService,
 | 
					 | 
				
			||||||
                             db=database,
 | 
					 | 
				
			||||||
                             users_service=users)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Retrieving catalog providers:
 | 
					 | 
				
			||||||
users_service = Services.users()
 | 
					 | 
				
			||||||
auth_service = Services.auth()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Making some asserts:
 | 
					 | 
				
			||||||
assert users_service.db is auth_service.db is Services.database()
 | 
					 | 
				
			||||||
assert isinstance(auth_service.users_service, UsersService)
 | 
					 | 
				
			||||||
assert users_service is not Services.users()
 | 
					 | 
				
			||||||
assert auth_service is not Services.auth()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Making some "inline" injections:
 | 
					 | 
				
			||||||
@injections.inject(users_service=Services.users)
 | 
					 | 
				
			||||||
@injections.inject(auth_service=Services.auth)
 | 
					 | 
				
			||||||
@injections.inject(database=Services.database)
 | 
					 | 
				
			||||||
def example(users_service, auth_service, database):
 | 
					 | 
				
			||||||
    """Example callback."""
 | 
					 | 
				
			||||||
    assert users_service.db is auth_service.db
 | 
					 | 
				
			||||||
    assert auth_service.db is database
 | 
					 | 
				
			||||||
    assert database is Services.database()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Making a call of decorated callback:
 | 
					 | 
				
			||||||
example()
 | 
					 | 
				
			||||||
| 
						 | 
					@ -13,13 +13,10 @@ class Services(catalogs.DeclarativeCatalog):
 | 
				
			||||||
    """Example catalog of service providers."""
 | 
					    """Example catalog of service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    users = providers.Factory(services.Users)
 | 
					    users = providers.Factory(services.Users)
 | 
				
			||||||
    """:type: providers.Provider -> services.Users"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auth = providers.Factory(services.Auth)
 | 
					    auth = providers.Factory(services.Auth)
 | 
				
			||||||
    """:type: providers.Provider -> services.Auth"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    photos = providers.Factory(services.Photos)
 | 
					    photos = providers.Factory(services.Photos)
 | 
				
			||||||
    """:type: providers.Provider -> services.Photos"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Declaring views catalog:
 | 
					# Declaring views catalog:
 | 
				
			||||||
| 
						 | 
					@ -29,12 +26,10 @@ class Views(catalogs.DeclarativeCatalog):
 | 
				
			||||||
    auth = providers.Factory(views.Auth,
 | 
					    auth = providers.Factory(views.Auth,
 | 
				
			||||||
                             services=Services.Bundle(Services.users,
 | 
					                             services=Services.Bundle(Services.users,
 | 
				
			||||||
                                                      Services.auth))
 | 
					                                                      Services.auth))
 | 
				
			||||||
    """:type: providers.Provider -> views.Auth"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    photos = providers.Factory(views.Photos,
 | 
					    photos = providers.Factory(views.Photos,
 | 
				
			||||||
                               services=Services.Bundle(Services.users,
 | 
					                               services=Services.Bundle(Services.users,
 | 
				
			||||||
                                                        Services.photos))
 | 
					                                                        Services.photos))
 | 
				
			||||||
    """:type: providers.Provider -> views.Photos"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Creating example views:
 | 
					# Creating example views:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -9,10 +9,8 @@ class Catalog(catalogs.DeclarativeCatalog):
 | 
				
			||||||
    """Providers catalog."""
 | 
					    """Providers catalog."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    factory1 = providers.Factory(object)
 | 
					    factory1 = providers.Factory(object)
 | 
				
			||||||
    """:type: providers.Provider -> object"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    factory2 = providers.Factory(object)
 | 
					    factory2 = providers.Factory(object)
 | 
				
			||||||
    """:type: providers.Provider -> object"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Creating some objects:
 | 
					# Creating some objects:
 | 
				
			||||||
object1 = Catalog.factory1()
 | 
					object1 = Catalog.factory1()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,14 +8,12 @@ class CatalogA(catalogs.DeclarativeCatalog):
 | 
				
			||||||
    """Example catalog A."""
 | 
					    """Example catalog A."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    provider1 = providers.Factory(object)
 | 
					    provider1 = providers.Factory(object)
 | 
				
			||||||
    """:type: providers.Provider -> object"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CatalogB(CatalogA):
 | 
					class CatalogB(CatalogA):
 | 
				
			||||||
    """Example catalog B."""
 | 
					    """Example catalog B."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    provider2 = providers.Singleton(object)
 | 
					    provider2 = providers.Singleton(object)
 | 
				
			||||||
    """:type: providers.Provider -> object"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Making some asserts for `providers` attribute:
 | 
					# Making some asserts for `providers` attribute:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,16 +27,13 @@ class Services(catalogs.DeclarativeCatalog):
 | 
				
			||||||
    """Catalog of service providers."""
 | 
					    """Catalog of service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
					    database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
				
			||||||
    """:type: providers.Provider -> sqlite3.Connection"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    users = providers.Factory(UsersService,
 | 
					    users = providers.Factory(UsersService,
 | 
				
			||||||
                              db=database)
 | 
					                              db=database)
 | 
				
			||||||
    """:type: providers.Provider -> UsersService"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auth = providers.Factory(AuthService,
 | 
					    auth = providers.Factory(AuthService,
 | 
				
			||||||
                             db=database,
 | 
					                             db=database,
 | 
				
			||||||
                             users_service=users)
 | 
					                             users_service=users)
 | 
				
			||||||
    """:type: providers.Provider -> AuthService"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Retrieving service providers from catalog:
 | 
					# Retrieving service providers from catalog:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,13 +31,11 @@ class Services(services.Catalog):
 | 
				
			||||||
    users = services.Provider(UsersService,
 | 
					    users = services.Provider(UsersService,
 | 
				
			||||||
                              config={'option1': '111',
 | 
					                              config={'option1': '111',
 | 
				
			||||||
                                      'option2': '222'})
 | 
					                                      'option2': '222'})
 | 
				
			||||||
    """:type: services.Provider -> UsersService"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    auth = services.Provider(AuthService,
 | 
					    auth = services.Provider(AuthService,
 | 
				
			||||||
                             config={'option3': '333',
 | 
					                             config={'option3': '333',
 | 
				
			||||||
                                     'option4': '444'},
 | 
					                                     'option4': '444'},
 | 
				
			||||||
                             users_service=users)
 | 
					                             users_service=users)
 | 
				
			||||||
    """:type: services.Provider -> AuthService"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Creating users & auth services:
 | 
					# Creating users & auth services:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,18 +18,15 @@ class Catalog(catalogs.DeclarativeCatalog):
 | 
				
			||||||
    object1_factory = providers.Factory(Object1,
 | 
					    object1_factory = providers.Factory(Object1,
 | 
				
			||||||
                                        arg1=1,
 | 
					                                        arg1=1,
 | 
				
			||||||
                                        arg2=2)
 | 
					                                        arg2=2)
 | 
				
			||||||
    """:type: providers.Provider -> Object1"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    object2_factory = providers.Factory(Object2,
 | 
					    object2_factory = providers.Factory(Object2,
 | 
				
			||||||
                                        object1=object1_factory)
 | 
					                                        object1=object1_factory)
 | 
				
			||||||
    """:type: providers.Provider -> Object2"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AnotherCatalog(catalogs.DeclarativeCatalog):
 | 
					class AnotherCatalog(catalogs.DeclarativeCatalog):
 | 
				
			||||||
    """Overriding catalog."""
 | 
					    """Overriding catalog."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    object2_factory = providers.Factory(ExtendedObject2)
 | 
					    object2_factory = providers.Factory(ExtendedObject2)
 | 
				
			||||||
    """:type: providers.Provider -> ExtendedObject2"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Overriding `Catalog` with `AnotherCatalog`:
 | 
					# Overriding `Catalog` with `AnotherCatalog`:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,11 +18,9 @@ class Catalog(catalogs.DeclarativeCatalog):
 | 
				
			||||||
    object1_factory = providers.Factory(Object1,
 | 
					    object1_factory = providers.Factory(Object1,
 | 
				
			||||||
                                        arg1=1,
 | 
					                                        arg1=1,
 | 
				
			||||||
                                        arg2=2)
 | 
					                                        arg2=2)
 | 
				
			||||||
    """:type: providers.Provider -> Object1"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    object2_factory = providers.Factory(Object2,
 | 
					    object2_factory = providers.Factory(Object2,
 | 
				
			||||||
                                        object1=object1_factory)
 | 
					                                        object1=object1_factory)
 | 
				
			||||||
    """:type: providers.Provider -> Object2"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Overriding `Catalog` with some `DynamicCatalog` instance:
 | 
					# Overriding `Catalog` with some `DynamicCatalog` instance:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -17,11 +17,9 @@ class Catalog(catalogs.DeclarativeCatalog):
 | 
				
			||||||
    object1_factory = providers.Factory(Object1,
 | 
					    object1_factory = providers.Factory(Object1,
 | 
				
			||||||
                                        arg1=1,
 | 
					                                        arg1=1,
 | 
				
			||||||
                                        arg2=2)
 | 
					                                        arg2=2)
 | 
				
			||||||
    """:type: providers.Provider -> Object1"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    object2_factory = providers.Factory(Object2,
 | 
					    object2_factory = providers.Factory(Object2,
 | 
				
			||||||
                                        object1=object1_factory)
 | 
					                                        object1=object1_factory)
 | 
				
			||||||
    """:type: providers.Provider -> Object2"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Overriding `Catalog` with `AnotherCatalog`:
 | 
					# Overriding `Catalog` with `AnotherCatalog`:
 | 
				
			||||||
| 
						 | 
					@ -30,7 +28,6 @@ class AnotherCatalog(catalogs.DeclarativeCatalog):
 | 
				
			||||||
    """Overriding catalog."""
 | 
					    """Overriding catalog."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    object2_factory = providers.Factory(ExtendedObject2)
 | 
					    object2_factory = providers.Factory(ExtendedObject2)
 | 
				
			||||||
    """:type: providers.Provider -> ExtendedObject2"""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Creating some objects using overridden catalog:
 | 
					# Creating some objects using overridden catalog:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										58
									
								
								examples/initial.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								examples/initial.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,58 @@
 | 
				
			||||||
 | 
					"""Dependency Injector initial example."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import sqlite3
 | 
				
			||||||
 | 
					import boto.s3.connection
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import services
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import catalogs
 | 
				
			||||||
 | 
					from dependency_injector import providers
 | 
				
			||||||
 | 
					from dependency_injector import injections
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Platform(catalogs.DeclarativeCatalog):
 | 
				
			||||||
 | 
					    """Catalog of platform service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    database = providers.Singleton(sqlite3.connect, ':memory:')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    s3 = providers.Singleton(boto.s3.connection.S3Connection,
 | 
				
			||||||
 | 
					                             aws_access_key_id='KEY',
 | 
				
			||||||
 | 
					                             aws_secret_access_key='SECRET')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Services(catalogs.DeclarativeCatalog):
 | 
				
			||||||
 | 
					    """Catalog of business service providers."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    users = providers.Factory(services.Users,
 | 
				
			||||||
 | 
					                              db=Platform.database)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    photos = providers.Factory(services.Photos,
 | 
				
			||||||
 | 
					                               db=Platform.database,
 | 
				
			||||||
 | 
					                               s3=Platform.s3)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    auth = providers.Factory(services.Auth,
 | 
				
			||||||
 | 
					                             db=Platform.database,
 | 
				
			||||||
 | 
					                             token_ttl=3600)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@injections.inject(users_service=Services.users)
 | 
				
			||||||
 | 
					@injections.inject(auth_service=Services.auth)
 | 
				
			||||||
 | 
					def main(argv, users_service, auth_service):
 | 
				
			||||||
 | 
					    """Main function."""
 | 
				
			||||||
 | 
					    login, password, photo_path = argv[1:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user = users_service.get_user(login)
 | 
				
			||||||
 | 
					    auth_service.authenticate(user, password)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    upload_photo(user, photo_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@injections.inject(photos_service=Services.photos)
 | 
				
			||||||
 | 
					def upload_photo(user, photo_path, photos_service):
 | 
				
			||||||
 | 
					    """Upload photo."""
 | 
				
			||||||
 | 
					    photos_service.upload_photo(user['id'], photo_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    main(sys.argv)
 | 
				
			||||||
							
								
								
									
										15
									
								
								examples/miniapps/api_client/api.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								examples/miniapps/api_client/api.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					"""asd."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ApiClient(object):
 | 
				
			||||||
 | 
					    """Some API client."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, host, api_key):
 | 
				
			||||||
 | 
					        """Initializer."""
 | 
				
			||||||
 | 
					        self.host = host
 | 
				
			||||||
 | 
					        self.api_key = api_key
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def call(self, operation, data):
 | 
				
			||||||
 | 
					        """Make some network operations."""
 | 
				
			||||||
 | 
					        print 'API call [{0}:{1}], method - {2}, data - {3}'.format(
 | 
				
			||||||
 | 
					            self.host, self.api_key, operation, repr(data))
 | 
				
			||||||
							
								
								
									
										36
									
								
								examples/miniapps/api_client/main.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								examples/miniapps/api_client/main.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,36 @@
 | 
				
			||||||
 | 
					"""asd."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import api
 | 
				
			||||||
 | 
					import models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Creating ApiClient and User providers:
 | 
				
			||||||
 | 
					api_client = providers.Singleton(api.ApiClient,
 | 
				
			||||||
 | 
					                                 host='production.com',
 | 
				
			||||||
 | 
					                                 api_key='PROD_API_KEY')
 | 
				
			||||||
 | 
					user_factory = providers.Factory(models.User,
 | 
				
			||||||
 | 
					                                 api_client=api_client)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    # Creating several users and register them:
 | 
				
			||||||
 | 
					    user1 = user_factory(1)
 | 
				
			||||||
 | 
					    user1.register()
 | 
				
			||||||
 | 
					    # API call [production.com:PROD_API_KEY], method - register, data -
 | 
				
			||||||
 | 
					    # {'id': 1}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user2 = user_factory(2)
 | 
				
			||||||
 | 
					    user2.register()
 | 
				
			||||||
 | 
					    # API call [production.com:PROD_API_KEY], method - register, data -
 | 
				
			||||||
 | 
					    # {'id': 2}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Overriding of ApiClient on dev environment:
 | 
				
			||||||
 | 
					    api_client.override(providers.Singleton(api.ApiClient,
 | 
				
			||||||
 | 
					                                            host='localhost',
 | 
				
			||||||
 | 
					                                            api_key='DEV_API_KEY'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    user3 = user_factory(3)
 | 
				
			||||||
 | 
					    user3.register()
 | 
				
			||||||
 | 
					    # API call [localhost:DEV_API_KEY], method - register, data - {'id': 3}
 | 
				
			||||||
							
								
								
									
										14
									
								
								examples/miniapps/api_client/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								examples/miniapps/api_client/models.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					"""asd."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class User(object):
 | 
				
			||||||
 | 
					    """User model."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, id, api_client):
 | 
				
			||||||
 | 
					        """Initializer."""
 | 
				
			||||||
 | 
					        self.id = id
 | 
				
			||||||
 | 
					        self.api_client = api_client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def register(self):
 | 
				
			||||||
 | 
					        """Register user."""
 | 
				
			||||||
 | 
					        self.api_client.call('register', {'id': self.id})
 | 
				
			||||||
							
								
								
									
										12
									
								
								examples/miniapps/api_client/tests.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								examples/miniapps/api_client/tests.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,12 @@
 | 
				
			||||||
 | 
					"""asd."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from mock import Mock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import main
 | 
				
			||||||
 | 
					import api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Mock ApiClient for testing:
 | 
				
			||||||
 | 
					with main.api_client.override(Mock(api.ApiClient)) as api_client_mock:
 | 
				
			||||||
 | 
					    user = main.user_factory('test')
 | 
				
			||||||
 | 
					    user.register()
 | 
				
			||||||
 | 
					    api_client_mock().call.assert_called_with('register', {'id': 'test'})
 | 
				
			||||||
							
								
								
									
										10
									
								
								examples/miniapps/flask_services/app.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								examples/miniapps/flask_services/app.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,10 @@
 | 
				
			||||||
 | 
					"""Flask application."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import flask
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app = flask.Flask(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    app.run()
 | 
				
			||||||
							
								
								
									
										8
									
								
								examples/miniapps/flask_services/services/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								examples/miniapps/flask_services/services/__init__.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,8 @@
 | 
				
			||||||
 | 
					"""Services package."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from dependency_injector import catalogs
 | 
				
			||||||
 | 
					from dependency_injector import providers
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ServicesModule(catalogs.DeclarativeCatalog):
 | 
				
			||||||
 | 
					    """Service providers module."""
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,10 @@ module component providers - ``MoviesModule``. It is recommended to use movies
 | 
				
			||||||
library functionality by fetching required instances from ``MoviesModule``
 | 
					library functionality by fetching required instances from ``MoviesModule``
 | 
				
			||||||
providers.
 | 
					providers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					``MoviesModule.movie_finder`` is a factory that provides abstract component
 | 
				
			||||||
 | 
					``finders.MovieFinder``. This provider should be overridden by provider of
 | 
				
			||||||
 | 
					concrete finder implementation in terms of library configuration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Each of ``MoviesModule`` providers could be overridden.
 | 
					Each of ``MoviesModule`` providers could be overridden.
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										40
									
								
								examples/services.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								examples/services.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					"""Services module."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Users(object):
 | 
				
			||||||
 | 
					    """Users service."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, db):
 | 
				
			||||||
 | 
					        """Initializer."""
 | 
				
			||||||
 | 
					        self.db = db
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def get_user(self, login):
 | 
				
			||||||
 | 
					        """Return user's information by login."""
 | 
				
			||||||
 | 
					        return {'id': 1,
 | 
				
			||||||
 | 
					                'login': login,
 | 
				
			||||||
 | 
					                'password_hash': 'secret_hash'}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Auth(object):
 | 
				
			||||||
 | 
					    """Auth service."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, db, token_ttl):
 | 
				
			||||||
 | 
					        """Initializer."""
 | 
				
			||||||
 | 
					        self.db = db
 | 
				
			||||||
 | 
					        self.token_ttl = token_ttl
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def authenticate(self, user, password):
 | 
				
			||||||
 | 
					        """Authenticate user."""
 | 
				
			||||||
 | 
					        assert user['password_hash'] == '_'.join((password, 'hash'))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Photos(object):
 | 
				
			||||||
 | 
					    """Photos service."""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, db, s3):
 | 
				
			||||||
 | 
					        """Initializer."""
 | 
				
			||||||
 | 
					        self.db = db
 | 
				
			||||||
 | 
					        self.s3 = s3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def upload_photo(self, user_id, photo_path):
 | 
				
			||||||
 | 
					        """Upload user photo."""
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user