diff --git a/docs/examples/index.rst b/docs/examples/index.rst index 7c375cd8..ac1a59da 100644 --- a/docs/examples/index.rst +++ b/docs/examples/index.rst @@ -16,6 +16,7 @@ and powered by *Dependency Injector* framework. :maxdepth: 2 movie_lister - services_miniapp + services_miniapp_v1 + services_miniapp_v2 bundles_miniapp use_cases_miniapp diff --git a/docs/examples/services_miniapp.rst b/docs/examples/services_miniapp_v1.rst similarity index 72% rename from docs/examples/services_miniapp.rst rename to docs/examples/services_miniapp_v1.rst index b274e8bc..aa0df055 100644 --- a/docs/examples/services_miniapp.rst +++ b/docs/examples/services_miniapp_v1.rst @@ -1,5 +1,5 @@ -Services mini application example ---------------------------------- +Services mini application example (v1 - multiple containers) +------------------------------------------------------------ .. meta:: :description: "Services miniapp" is an example mini application that @@ -7,7 +7,8 @@ Services mini application example some standard and 3rd-party libraries for logging, interaction with database and remote service via API. "Services miniapp" example demonstrates usage of - Dependency Injector for creating several IoC containers. + Dependency Injector for creating several inversion of control / + dependency injection containers. "Services miniapp" is an example mini application that consists from several services that have dependencies on some standard and 3rd-party libraries for @@ -44,13 +45,13 @@ Example application structure: Listing of ``example/services.py``: -.. literalinclude:: ../../examples/miniapps/services/example/services.py +.. literalinclude:: ../../examples/miniapps/services_v1/example/services.py :language: python :linenos: Listing of ``example/main.py``: -.. literalinclude:: ../../examples/miniapps/services/example/main.py +.. literalinclude:: ../../examples/miniapps/services_v1/example/main.py :language: python :linenos: @@ -59,7 +60,7 @@ IoC containers Listing of ``containers.py``: -.. literalinclude:: ../../examples/miniapps/services/containers.py +.. literalinclude:: ../../examples/miniapps/services_v1/containers.py :language: python :linenos: @@ -68,7 +69,7 @@ Run application Listing of ``run.py``: -.. literalinclude:: ../../examples/miniapps/services/run.py +.. literalinclude:: ../../examples/miniapps/services_v1/run.py :language: python :linenos: diff --git a/docs/examples/services_miniapp_v2.rst b/docs/examples/services_miniapp_v2.rst new file mode 100644 index 00000000..b507c606 --- /dev/null +++ b/docs/examples/services_miniapp_v2.rst @@ -0,0 +1,77 @@ +Services mini application example (v2 - single container) +--------------------------------------------------------- + +.. meta:: + :description: "Services miniapp" is an example mini application that + consists from several services that have dependencies on + some standard and 3rd-party libraries for logging, + interaction with database and remote service via API. + "Services miniapp" example demonstrates usage of + Dependency Injector for creating inversion of control / + dependency injection container. + +"Services miniapp" is an example mini application that consists from several +services that have dependencies on some standard and 3rd-party libraries for +logging, interaction with database and remote service calls via API. + +"Services miniapp" example demonstrates usage of +:doc:`Dependency Injector <../index>` for creating IoC container. + +Instructions for running: + +.. code-block:: bash + + python run.py 1 secret photo.jpg + +Example application +~~~~~~~~~~~~~~~~~~~ + +Classes diagram: + +.. image:: /images/miniapps/services/classes.png + :width: 100% + :align: center + + +Example application structure: + +.. code-block:: bash + + /example + /__init__.py + /main.py + /services.py + + +Listing of ``example/services.py``: + +.. literalinclude:: ../../examples/miniapps/services_v2/example/services.py + :language: python + :linenos: + +Listing of ``example/main.py``: + +.. literalinclude:: ../../examples/miniapps/services_v2/example/main.py + :language: python + :linenos: + +IoC container +~~~~~~~~~~~~~ + +Listing of ``container.py``: + +.. literalinclude:: ../../examples/miniapps/services_v2/container.py + :language: python + :linenos: + +Run application +~~~~~~~~~~~~~~~ + +Listing of ``run.py``: + +.. literalinclude:: ../../examples/miniapps/services_v2/run.py + :language: python + :linenos: + + +.. disqus:: diff --git a/examples/miniapps/ioc_container/example/main.py b/examples/miniapps/ioc_container/example/main.py deleted file mode 100644 index f1386c1a..00000000 --- a/examples/miniapps/ioc_container/example/main.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Example main module.""" - - -def main(uid, password, photo, users_service, auth_service, photos_service): - """Authenticate user and upload photo. - - :param uid: User identifier. - :type uid: int - - :param password: User's password for verification. - :type password: str - - :param photo_path: Path to photo for uploading. - :type photo_path: str - - :param users_service: Users service. - :type users_service: example.services.UsersService - - :param auth_service: Authentication service. - :type auth_service: example.services.AuthService - - :param photo_service: Photo service. - :type photo_service: example.services.PhotoService - """ - user = users_service.get_user_by_id(uid) - auth_service.authenticate(user, password) - photos_service.upload_photo(user['uid'], photo) diff --git a/examples/miniapps/ioc_container/example/services.py b/examples/miniapps/ioc_container/example/services.py deleted file mode 100644 index 77e1ae99..00000000 --- a/examples/miniapps/ioc_container/example/services.py +++ /dev/null @@ -1,103 +0,0 @@ -"""Example business services module.""" - - -class BaseService(object): - """Service base class.""" - - -class UsersService(BaseService): - """Users service.""" - - def __init__(self, logger, db): - """Initializer. - - :param logger: Logger instance. - :type logger: logging.Logger - - :param db: Database connection. - :type db: sqlite3.Connection - """ - self.logger = logger - self.db = db - - def get_user_by_id(self, uid): - """Return user's data by identifier. - - :param uid: User identifier. - :type uid: int - - :rtype: dict - """ - self.logger.debug('User %s has been found in database', uid) - return dict(uid=uid, password_hash='secret_hash') - - -class AuthService(BaseService): - """Authentication service.""" - - def __init__(self, logger, db, token_ttl): - """Initializer. - - :param logger: Logger instance. - :type logger: logging.Logger - - :param db: Database connection. - :type db: sqlite3.Connection - - :param token_ttl: Token lifetime in seconds. - :type token_ttl: int - """ - self.logger = logger - self.db = db - self.token_ttl = token_ttl - - def authenticate(self, user, password): - """Authenticate user. - - :param user: User's data. - :type user: dict - - :param password: User's password for verification. - :type password: str - - :raises: AssertionError when password is wrong - - :rtype: None - """ - assert user['password_hash'] == '_'.join((password, 'hash')) - self.logger.debug('User %s has been successfully authenticated', - user['uid']) - - -class PhotosService(BaseService): - """Photos service.""" - - def __init__(self, logger, db, s3): - """Initializer. - - :param logger: Logger instance. - :type logger: logging.Logger - - :param db: Database connection. - :type db: sqlite3.Connection - - :param s3: AWS S3 client. - :type s3: botocore.client.S3 - """ - self.logger = logger - self.db = db - self.s3 = s3 - - def upload_photo(self, uid, photo_path): - """Upload user photo. - - :param uid: User identifier. - :type uid: int - - :param photo_path: Path to photo for uploading. - :type photo_path: str - - :rtpe: None - """ - self.logger.debug('Photo %s has been successfully uploaded by user %s', - photo_path, uid) diff --git a/examples/miniapps/services/example/main.py b/examples/miniapps/services/example/main.py deleted file mode 100644 index f1386c1a..00000000 --- a/examples/miniapps/services/example/main.py +++ /dev/null @@ -1,27 +0,0 @@ -"""Example main module.""" - - -def main(uid, password, photo, users_service, auth_service, photos_service): - """Authenticate user and upload photo. - - :param uid: User identifier. - :type uid: int - - :param password: User's password for verification. - :type password: str - - :param photo_path: Path to photo for uploading. - :type photo_path: str - - :param users_service: Users service. - :type users_service: example.services.UsersService - - :param auth_service: Authentication service. - :type auth_service: example.services.AuthService - - :param photo_service: Photo service. - :type photo_service: example.services.PhotoService - """ - user = users_service.get_user_by_id(uid) - auth_service.authenticate(user, password) - photos_service.upload_photo(user['uid'], photo) diff --git a/examples/miniapps/services/example/services.py b/examples/miniapps/services/example/services.py deleted file mode 100644 index 77e1ae99..00000000 --- a/examples/miniapps/services/example/services.py +++ /dev/null @@ -1,103 +0,0 @@ -"""Example business services module.""" - - -class BaseService(object): - """Service base class.""" - - -class UsersService(BaseService): - """Users service.""" - - def __init__(self, logger, db): - """Initializer. - - :param logger: Logger instance. - :type logger: logging.Logger - - :param db: Database connection. - :type db: sqlite3.Connection - """ - self.logger = logger - self.db = db - - def get_user_by_id(self, uid): - """Return user's data by identifier. - - :param uid: User identifier. - :type uid: int - - :rtype: dict - """ - self.logger.debug('User %s has been found in database', uid) - return dict(uid=uid, password_hash='secret_hash') - - -class AuthService(BaseService): - """Authentication service.""" - - def __init__(self, logger, db, token_ttl): - """Initializer. - - :param logger: Logger instance. - :type logger: logging.Logger - - :param db: Database connection. - :type db: sqlite3.Connection - - :param token_ttl: Token lifetime in seconds. - :type token_ttl: int - """ - self.logger = logger - self.db = db - self.token_ttl = token_ttl - - def authenticate(self, user, password): - """Authenticate user. - - :param user: User's data. - :type user: dict - - :param password: User's password for verification. - :type password: str - - :raises: AssertionError when password is wrong - - :rtype: None - """ - assert user['password_hash'] == '_'.join((password, 'hash')) - self.logger.debug('User %s has been successfully authenticated', - user['uid']) - - -class PhotosService(BaseService): - """Photos service.""" - - def __init__(self, logger, db, s3): - """Initializer. - - :param logger: Logger instance. - :type logger: logging.Logger - - :param db: Database connection. - :type db: sqlite3.Connection - - :param s3: AWS S3 client. - :type s3: botocore.client.S3 - """ - self.logger = logger - self.db = db - self.s3 = s3 - - def upload_photo(self, uid, photo_path): - """Upload user photo. - - :param uid: User identifier. - :type uid: int - - :param photo_path: Path to photo for uploading. - :type photo_path: str - - :rtpe: None - """ - self.logger.debug('Photo %s has been successfully uploaded by user %s', - photo_path, uid) diff --git a/examples/miniapps/ioc_container/README.rst b/examples/miniapps/services_v1/README.rst similarity index 100% rename from examples/miniapps/ioc_container/README.rst rename to examples/miniapps/services_v1/README.rst diff --git a/examples/miniapps/services/containers.py b/examples/miniapps/services_v1/containers.py similarity index 100% rename from examples/miniapps/services/containers.py rename to examples/miniapps/services_v1/containers.py diff --git a/examples/miniapps/ioc_container/example/__init__.py b/examples/miniapps/services_v1/example/__init__.py similarity index 100% rename from examples/miniapps/ioc_container/example/__init__.py rename to examples/miniapps/services_v1/example/__init__.py diff --git a/examples/miniapps/services_v1/example/main.py b/examples/miniapps/services_v1/example/main.py new file mode 100644 index 00000000..2f80a1c7 --- /dev/null +++ b/examples/miniapps/services_v1/example/main.py @@ -0,0 +1,8 @@ +"""Example main module.""" + + +def main(uid, password, photo, users_service, auth_service, photos_service): + """Authenticate user and upload photo.""" + user = users_service.get_user_by_id(uid) + auth_service.authenticate(user, password) + photos_service.upload_photo(user['uid'], photo) diff --git a/examples/miniapps/services_v1/example/services.py b/examples/miniapps/services_v1/example/services.py new file mode 100644 index 00000000..c3b1b7cf --- /dev/null +++ b/examples/miniapps/services_v1/example/services.py @@ -0,0 +1,50 @@ +"""Example business services module.""" + + +class BaseService(object): + """Service base class.""" + + +class UsersService(BaseService): + """Users service.""" + + def __init__(self, logger, db): + """Initializer.""" + self.logger = logger + self.db = db + + def get_user_by_id(self, uid): + """Return user's data by identifier.""" + self.logger.debug('User %s has been found in database', uid) + return dict(uid=uid, password_hash='secret_hash') + + +class AuthService(BaseService): + """Authentication service.""" + + def __init__(self, logger, db, token_ttl): + """Initializer.""" + self.logger = logger + self.db = db + self.token_ttl = token_ttl + + def authenticate(self, user, password): + """Authenticate user.""" + assert user['password_hash'] == '_'.join((password, 'hash')) + self.logger.debug('User %s has been successfully authenticated', + user['uid']) + + +class PhotosService(BaseService): + """Photos service.""" + + def __init__(self, logger, db, s3): + """Initializer.""" + self.logger = logger + self.db = db + self.s3 = s3 + + def upload_photo(self, uid, photo_path): + """Upload user photo.""" + self.logger.debug('Photo %s has been successfully uploaded by user %s', + photo_path, uid) diff --git a/examples/miniapps/services/run.py b/examples/miniapps/services_v1/run.py similarity index 100% rename from examples/miniapps/services/run.py rename to examples/miniapps/services_v1/run.py diff --git a/examples/miniapps/services/README.rst b/examples/miniapps/services_v2/README.rst similarity index 100% rename from examples/miniapps/services/README.rst rename to examples/miniapps/services_v2/README.rst diff --git a/examples/miniapps/ioc_container/container.py b/examples/miniapps/services_v2/container.py similarity index 100% rename from examples/miniapps/ioc_container/container.py rename to examples/miniapps/services_v2/container.py diff --git a/examples/miniapps/services/example/__init__.py b/examples/miniapps/services_v2/example/__init__.py similarity index 100% rename from examples/miniapps/services/example/__init__.py rename to examples/miniapps/services_v2/example/__init__.py diff --git a/examples/miniapps/services_v2/example/main.py b/examples/miniapps/services_v2/example/main.py new file mode 100644 index 00000000..2f80a1c7 --- /dev/null +++ b/examples/miniapps/services_v2/example/main.py @@ -0,0 +1,8 @@ +"""Example main module.""" + + +def main(uid, password, photo, users_service, auth_service, photos_service): + """Authenticate user and upload photo.""" + user = users_service.get_user_by_id(uid) + auth_service.authenticate(user, password) + photos_service.upload_photo(user['uid'], photo) diff --git a/examples/miniapps/services_v2/example/services.py b/examples/miniapps/services_v2/example/services.py new file mode 100644 index 00000000..c3b1b7cf --- /dev/null +++ b/examples/miniapps/services_v2/example/services.py @@ -0,0 +1,50 @@ +"""Example business services module.""" + + +class BaseService(object): + """Service base class.""" + + +class UsersService(BaseService): + """Users service.""" + + def __init__(self, logger, db): + """Initializer.""" + self.logger = logger + self.db = db + + def get_user_by_id(self, uid): + """Return user's data by identifier.""" + self.logger.debug('User %s has been found in database', uid) + return dict(uid=uid, password_hash='secret_hash') + + +class AuthService(BaseService): + """Authentication service.""" + + def __init__(self, logger, db, token_ttl): + """Initializer.""" + self.logger = logger + self.db = db + self.token_ttl = token_ttl + + def authenticate(self, user, password): + """Authenticate user.""" + assert user['password_hash'] == '_'.join((password, 'hash')) + self.logger.debug('User %s has been successfully authenticated', + user['uid']) + + +class PhotosService(BaseService): + """Photos service.""" + + def __init__(self, logger, db, s3): + """Initializer.""" + self.logger = logger + self.db = db + self.s3 = s3 + + def upload_photo(self, uid, photo_path): + """Upload user photo.""" + self.logger.debug('Photo %s has been successfully uploaded by user %s', + photo_path, uid) diff --git a/examples/miniapps/ioc_container/run.py b/examples/miniapps/services_v2/run.py similarity index 100% rename from examples/miniapps/ioc_container/run.py rename to examples/miniapps/services_v2/run.py