diff --git a/docs/api/utils.rst b/docs/api/utils.rst deleted file mode 100644 index 38ea3b70..00000000 --- a/docs/api/utils.rst +++ /dev/null @@ -1,5 +0,0 @@ -``dependency_injector.utils`` ------------------------------ - -.. automodule:: dependency_injector.utils - :members: diff --git a/docs/examples/index.rst b/docs/examples/index.rst index 89d623fb..3d57076e 100644 --- a/docs/examples/index.rst +++ b/docs/examples/index.rst @@ -16,3 +16,4 @@ and powered by *Dependency Injector* framework. :maxdepth: 2 movie_lister + services_miniapp diff --git a/docs/examples/services_miniapp.rst b/docs/examples/services_miniapp.rst new file mode 100644 index 00000000..33ea11ac --- /dev/null +++ b/docs/examples/services_miniapp.rst @@ -0,0 +1,73 @@ +Services mini application example +--------------------------------- + +.. 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 several IoC containers. + +"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 several IoC containers. + +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/example/services.py + :language: python + :linenos: + +Listing of ``example/main.py``: + +.. literalinclude:: ../../examples/miniapps/services/example/main.py + :language: python + :linenos: + +IoC containers +~~~~~~~~~~~~~~ + +Listing of ``containers.py``: + +.. literalinclude:: ../../examples/miniapps/services/containers.py + :language: python + :linenos: + +Run application +~~~~~~~~~~~~~~~ + +Listing of ``run.py``: + +.. literalinclude:: ../../examples/miniapps/services/run.py + :language: python + :linenos: diff --git a/docs/images/miniapps/services/classes.png b/docs/images/miniapps/services/classes.png new file mode 100644 index 00000000..8e9d29f7 Binary files /dev/null and b/docs/images/miniapps/services/classes.png differ diff --git a/docs/main/changelog.rst b/docs/main/changelog.rst index 27289641..a7da69e6 100644 --- a/docs/main/changelog.rst +++ b/docs/main/changelog.rst @@ -11,6 +11,11 @@ Development version ------------------- - No features. +3.1.0 +----- +- Add "Services mini application" example. +- Fix minor error in ``Factory`` provider API doc. + 3.0.1 ----- - Add ``*.c`` source files under version control. diff --git a/examples/miniapps/services/example/main.py b/examples/miniapps/services/example/main.py index d3399ff7..f1386c1a 100644 --- a/examples/miniapps/services/example/main.py +++ b/examples/miniapps/services/example/main.py @@ -2,7 +2,26 @@ def main(uid, password, photo, users_service, auth_service, photos_service): - """Example main function.""" + """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 index e907c1ca..4344e003 100644 --- a/examples/miniapps/services/example/services.py +++ b/examples/miniapps/services/example/services.py @@ -1,47 +1,103 @@ """Example business services module.""" -class UsersService(object): +class BaseService(object): + """Service base class.""" + + +class UsersService(BaseService): """Users service.""" def __init__(self, logger, db): - """Initializer.""" + """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 information by login.""" + """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 {'uid': uid, - 'password_hash': 'secret_hash'} + return dict(uid=uid, password_hash='secret_hash') -class AuthService(object): - """Auth service.""" +class AuthService(BaseService): + """Authentication service.""" def __init__(self, logger, db, token_ttl): - """Initializer.""" + """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.""" + """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(object): +class PhotosService(BaseService): """Photos service.""" def __init__(self, logger, db, s3): - """Initializer.""" + """Initializer. + + :param logger: Logger instance. + :type logger: logging.Logger + + :param db: Database connection. + :type db: sqlite3.Connection + + :param s3: AWS S3 client. + :type s3: boto.s3.connection.S3Connection + """ self.logger = logger self.db = db self.s3 = s3 def upload_photo(self, uid, photo_path): - """Upload user photo.""" + """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/src/dependency_injector/__init__.py b/src/dependency_injector/__init__.py index 169c3ea7..a344b9bf 100644 --- a/src/dependency_injector/__init__.py +++ b/src/dependency_injector/__init__.py @@ -1,6 +1,6 @@ """Dependency injector top-level package.""" -VERSION = '3.0.1' +VERSION = '3.1.0' """Version number that follows semantic versioning. :type: str