From 6eff213a6841600499b26ae22577804708f2eca1 Mon Sep 17 00:00:00 2001 From: Roman Mogylatov Date: Sat, 18 Jul 2020 00:40:14 -0400 Subject: [PATCH] Migrate to alabaster (#264) * Add bootstrap and remove created at from ghnav-flask app * Update readme * Add logo to the docs * Update key features description * Update README * Change headers of API docs * Add alabaster theme config * Update docs index * Add tutorials section * Update what is DI page * Update DI in Python page * Update tutorials index page * Update provider docs * Update container docs * Update examples docs --- README.rst | 12 ++- docs/_static/logo.svg | 1 + docs/api/containers.rst | 4 +- docs/api/errors.rst | 4 +- docs/api/flaskext.rst | 4 +- docs/api/providers.rst | 4 +- docs/api/top_level.rst | 4 +- docs/conf.py | 26 ++++-- docs/containers/declarative.rst | 3 - docs/containers/dynamic.rst | 2 - docs/containers/overriding.rst | 2 - docs/containers/specialization.rst | 2 - docs/examples/bundles_miniapp.rst | 3 - docs/examples/chained_factories.rst | 2 - docs/examples/factory_of_factories.rst | 2 - docs/examples/movie_lister.rst | 6 -- docs/examples/password_hashing_miniapp.rst | 1 - docs/examples/services_miniapp_v1.rst | 4 - docs/examples/services_miniapp_v2.rst | 4 - docs/examples/use_cases_miniapp.rst | 2 - docs/index.rst | 31 +++---- docs/introduction/di_in_python.rst | 6 +- docs/introduction/key_features.rst | 44 ++++----- docs/introduction/what_is_di.rst | 4 +- docs/providers/callable.rst | 2 - docs/providers/configuration.rst | 9 -- docs/providers/coroutine.rst | 1 - docs/providers/custom.rst | 1 - docs/providers/dependency.rst | 1 - docs/providers/factory.rst | 9 -- docs/providers/list.rst | 2 - docs/providers/object.rst | 1 - docs/providers/overriding.rst | 2 - docs/providers/selector.rst | 2 - docs/providers/singleton.rst | 3 - docs/tutorials/aiohttp.rst | 4 + docs/tutorials/asyncio.rst | 4 + docs/tutorials/flask.rst | 4 + docs/tutorials/index.rst | 12 +++ examples/di_demo/example.py | 10 +- examples/di_demo/example_di.py | 14 +-- .../miniapps/engines_cars/example/engines.py | 4 +- .../githubnavigator/application.py | 3 + .../ghnav-flask/githubnavigator/containers.py | 3 + .../ghnav-flask/githubnavigator/services.py | 1 - .../githubnavigator/templates/base.html | 26 ++++++ .../githubnavigator/templates/index.html | 91 +++++++++++-------- .../ghnav-flask/githubnavigator/tests.py | 4 - .../providers/abstract_factory/example.py | 32 ++++--- .../providers/factory_aggregate/example.py | 8 +- examples/providers/factory_delegation.py | 42 ++++++--- examples/providers/singleton.py | 4 +- examples/providers/singleton_thread_locals.py | 17 ++-- requirements-doc.txt | 2 +- 54 files changed, 266 insertions(+), 229 deletions(-) create mode 100644 docs/_static/logo.svg create mode 100644 docs/tutorials/aiohttp.rst create mode 100644 docs/tutorials/asyncio.rst create mode 100644 docs/tutorials/flask.rst create mode 100644 docs/tutorials/index.rst create mode 100644 examples/miniapps/ghnav-flask/githubnavigator/templates/base.html diff --git a/README.rst b/README.rst index 34e80eb3..76de13c8 100644 --- a/README.rst +++ b/README.rst @@ -55,10 +55,12 @@ What is ``Dependency Injector``? Why do I need it? ================= -``Dependency Injector`` helps you improve application structure. +``Dependency Injector`` helps you understand and change the structure of the application. With the ``Dependency Injector`` you keep **application structure in one place**. -This place is called **the container**. You use the container to manage all the components of the application. All the component dependencies are defined explicitly. This provides the control on the application structure. It is **easy to understand and change** it. +This place is called **the container**. You use the container to manage all the components of the +application. All the component dependencies are defined explicitly. This provides the control on +the application structure. It is **easy to understand and change** it. .. figure:: https://raw.githubusercontent.com/wiki/ets-labs/python-dependency-injector/img/di-map.svg :target: https://github.com/ets-labs/python-dependency-injector @@ -72,6 +74,7 @@ This place is called **the container**. You use the container to manage all the from dependency_injector import containers, providers from dependency_injector.ext import flask from flask import Flask + from flask_bootstrap import Bootstrap from github import Github from . import views, services @@ -82,6 +85,8 @@ This place is called **the container**. You use the container to manage all the app = flask.Application(Flask, __name__) + bootstrap = flask.Extension(Bootstrap) + config = providers.Configuration() github_client = providers.Factory( @@ -118,6 +123,9 @@ Running such container looks like this: app = container.app() app.container = container + bootstrap = container.bootstrap() + bootstrap.init_app(app) + app.add_url_rule('/', view_func=container.index_view.as_view()) return app diff --git a/docs/_static/logo.svg b/docs/_static/logo.svg new file mode 100644 index 00000000..1b9cba09 --- /dev/null +++ b/docs/_static/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/api/containers.rst b/docs/api/containers.rst index 8a2a040d..4f3719e1 100644 --- a/docs/api/containers.rst +++ b/docs/api/containers.rst @@ -1,5 +1,5 @@ -``dependency_injector.containers`` ----------------------------------- +dependency_injector.containers +============================== .. automodule:: dependency_injector.containers :members: diff --git a/docs/api/errors.rst b/docs/api/errors.rst index 8c3d3036..49233e01 100644 --- a/docs/api/errors.rst +++ b/docs/api/errors.rst @@ -1,5 +1,5 @@ -``dependency_injector.errors`` ------------------------------- +dependency_injector.errors +========================== .. automodule:: dependency_injector.errors :members: diff --git a/docs/api/flaskext.rst b/docs/api/flaskext.rst index 12a9ecbf..d780da73 100644 --- a/docs/api/flaskext.rst +++ b/docs/api/flaskext.rst @@ -1,5 +1,5 @@ -``dependency_injector.ext.flask`` ---------------------------------- +dependency_injector.ext.flask +============================= .. automodule:: dependency_injector.ext.flask :members: diff --git a/docs/api/providers.rst b/docs/api/providers.rst index ef30f154..50d94147 100644 --- a/docs/api/providers.rst +++ b/docs/api/providers.rst @@ -1,5 +1,5 @@ -``dependency_injector.providers`` ---------------------------------- +dependency_injector.providers +============================= .. automodule:: dependency_injector.providers :members: diff --git a/docs/api/top_level.rst b/docs/api/top_level.rst index 0243257c..c61a6ca0 100644 --- a/docs/api/top_level.rst +++ b/docs/api/top_level.rst @@ -1,5 +1,5 @@ -``dependency_injector`` ------------------------ +dependency_injector +=================== .. automodule:: dependency_injector :members: __version__ diff --git a/docs/conf.py b/docs/conf.py index 4291d459..f3638a1a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -15,6 +15,7 @@ import os import re import sys +import alabaster # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -29,8 +30,11 @@ sys.path.insert(0, os.path.abspath('..')) # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. -extensions = ['sphinx.ext.autodoc', - 'sphinxcontrib.disqus'] +extensions = [ + 'alabaster', + 'sphinx.ext.autodoc', + 'sphinxcontrib.disqus', +] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -112,7 +116,8 @@ todo_include_todos = False # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_rtd_theme' +# html_theme = 'sphinx_rtd_theme' +html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the @@ -120,7 +125,7 @@ html_theme = 'sphinx_rtd_theme' # html_context = {} # Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = ['_themes'] +html_theme_path = [alabaster.get_path()] # The name for this set of Sphinx documents. If None, it defaults to # " v documentation". @@ -291,6 +296,13 @@ autodoc_member_order = 'bysource' disqus_shortname = 'python-dependency-injector' - -def setup(app): - app.add_css_file('sphinx_rtd_theme-hotfix.css') +html_theme_options = { + 'github_user': 'ets-labs', + 'github_repo': 'python-dependency-injector', + 'github_type': 'star', + 'github_button': True, + 'github_banner': True, + 'logo': 'logo.svg', + 'description': 'Dependency injection framework for Python', + 'code_font_size': '10pt', +} diff --git a/docs/containers/declarative.rst b/docs/containers/declarative.rst index 2f9f994c..045e9c6e 100644 --- a/docs/containers/declarative.rst +++ b/docs/containers/declarative.rst @@ -32,7 +32,6 @@ factories: .. literalinclude:: ../../examples/containers/declarative.py :language: python - :linenos: Example of declarative containers inheritance: @@ -42,7 +41,6 @@ Example of declarative containers inheritance: .. literalinclude:: ../../examples/containers/declarative_inheritance.py :language: python - :linenos: Example of declarative containers's provider injections: @@ -52,7 +50,6 @@ Example of declarative containers's provider injections: .. literalinclude:: ../../examples/containers/declarative_injections.py :language: python - :linenos: .. disqus:: diff --git a/docs/containers/dynamic.rst b/docs/containers/dynamic.rst index 85224916..bd879f23 100644 --- a/docs/containers/dynamic.rst +++ b/docs/containers/dynamic.rst @@ -17,14 +17,12 @@ Here is an simple example of defining dynamic container with several factories: .. literalinclude:: ../../examples/containers/dynamic.py :language: python - :linenos: Next example demonstrates creation of dynamic container based on some configuration: .. literalinclude:: ../../examples/containers/dynamic_runtime_creation.py :language: python - :linenos: .. disqus:: diff --git a/docs/containers/overriding.rst b/docs/containers/overriding.rst index b2b501b1..729a8b1c 100644 --- a/docs/containers/overriding.rst +++ b/docs/containers/overriding.rst @@ -18,13 +18,11 @@ method: .. literalinclude:: ../../examples/containers/override_declarative.py :language: python - :linenos: Example of overriding container using :py:func:`override` decorator: .. literalinclude:: ../../examples/containers/override_declarative_decorator.py :language: python - :linenos: Also there are several useful :py:class:`DeclarativeContainer` methods and properties that help to work with container overridings: diff --git a/docs/containers/specialization.rst b/docs/containers/specialization.rst index 1c8c1bf0..1c2619f1 100644 --- a/docs/containers/specialization.rst +++ b/docs/containers/specialization.rst @@ -14,14 +14,12 @@ for limitation of its provided type: .. literalinclude:: ../../examples/containers/declarative_provider_type.py :language: python - :linenos: Limitation for providers type could be used with :py:class:`DynamicContainer` as well: .. literalinclude:: ../../examples/containers/dynamic_provider_type.py :language: python - :linenos: .. disqus:: diff --git a/docs/examples/bundles_miniapp.rst b/docs/examples/bundles_miniapp.rst index ab543f97..4be60cb5 100644 --- a/docs/examples/bundles_miniapp.rst +++ b/docs/examples/bundles_miniapp.rst @@ -37,7 +37,6 @@ Listing of ``bundles/users/__init__.py``: .. literalinclude:: ../../examples/miniapps/bundles/bundles/users/__init__.py :language: python - :linenos: .. note:: @@ -47,7 +46,6 @@ Listing of ``bundles/photos/__init__.py``: .. literalinclude:: ../../examples/miniapps/bundles/bundles/photos/__init__.py :language: python - :linenos: .. note:: @@ -65,7 +63,6 @@ Listing of ``run.py``: .. literalinclude:: ../../examples/miniapps/bundles/run.py :language: python - :linenos: Links ~~~~~ diff --git a/docs/examples/chained_factories.rst b/docs/examples/chained_factories.rst index a260b746..6d20bc7a 100644 --- a/docs/examples/chained_factories.rst +++ b/docs/examples/chained_factories.rst @@ -10,14 +10,12 @@ Listing of ``data.py``, demonstrates sample classes structure: .. literalinclude:: ../../examples/miniapps/factory_patterns/data.py :language: python - :linenos: Listing of ``chained_factories.py``, demonstrates "Chained Factories" pattern and provide some explanation: .. literalinclude:: ../../examples/miniapps/factory_patterns/chained_factories.py :language: python - :linenos: .. disqus:: diff --git a/docs/examples/factory_of_factories.rst b/docs/examples/factory_of_factories.rst index adabd042..d3ef157b 100644 --- a/docs/examples/factory_of_factories.rst +++ b/docs/examples/factory_of_factories.rst @@ -9,14 +9,12 @@ Listing of ``data.py``, demonstrates sample classes structure: .. literalinclude:: ../../examples/miniapps/factory_patterns/data.py :language: python - :linenos: Listing of ``factory_of_factories.py``, demonstrates "Chained Factories" pattern and provide some explanation: .. literalinclude:: ../../examples/miniapps/factory_patterns/factory_of_factories.py :language: python - :linenos: .. disqus:: diff --git a/docs/examples/movie_lister.rst b/docs/examples/movie_lister.rst index 331c6abf..594a67f1 100644 --- a/docs/examples/movie_lister.rst +++ b/docs/examples/movie_lister.rst @@ -70,7 +70,6 @@ Listing of ``movies/__init__.py``: .. literalinclude:: ../../examples/miniapps/movie_lister/movies/__init__.py :language: python - :linenos: Example application ~~~~~~~~~~~~~~~~~~~ @@ -88,13 +87,11 @@ Listing of ``examples/main.py``: .. literalinclude:: ../../examples/miniapps/movie_lister/example/main.py :language: python - :linenos: Listing of ``examples/db.py``: .. literalinclude:: ../../examples/miniapps/movie_lister/example/db.py :language: python - :linenos: Csv application ~~~~~~~~~~~~~~~ @@ -103,7 +100,6 @@ Listing of ``app_csv.py``: .. literalinclude:: ../../examples/miniapps/movie_lister/app_csv.py :language: python - :linenos: Database application ~~~~~~~~~~~~~~~~~~~~ @@ -112,7 +108,6 @@ Listing of ``app_db.py``: .. literalinclude:: ../../examples/miniapps/movie_lister/app_db.py :language: python - :linenos: Csv and database application ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -121,7 +116,6 @@ Listing of ``app_db_csv.py``: .. literalinclude:: ../../examples/miniapps/movie_lister/app_db_csv.py :language: python - :linenos: .. disqus:: diff --git a/docs/examples/password_hashing_miniapp.rst b/docs/examples/password_hashing_miniapp.rst index 45eb1d4c..21177545 100644 --- a/docs/examples/password_hashing_miniapp.rst +++ b/docs/examples/password_hashing_miniapp.rst @@ -14,6 +14,5 @@ Listing of ``example.py``: .. literalinclude:: ../../examples/miniapps/password_hashing/example.py :language: python - :linenos: .. disqus:: diff --git a/docs/examples/services_miniapp_v1.rst b/docs/examples/services_miniapp_v1.rst index aa0df055..5277c56c 100644 --- a/docs/examples/services_miniapp_v1.rst +++ b/docs/examples/services_miniapp_v1.rst @@ -47,13 +47,11 @@ Listing of ``example/services.py``: .. literalinclude:: ../../examples/miniapps/services_v1/example/services.py :language: python - :linenos: Listing of ``example/main.py``: .. literalinclude:: ../../examples/miniapps/services_v1/example/main.py :language: python - :linenos: IoC containers ~~~~~~~~~~~~~~ @@ -62,7 +60,6 @@ Listing of ``containers.py``: .. literalinclude:: ../../examples/miniapps/services_v1/containers.py :language: python - :linenos: Run application ~~~~~~~~~~~~~~~ @@ -71,7 +68,6 @@ Listing of ``run.py``: .. literalinclude:: ../../examples/miniapps/services_v1/run.py :language: python - :linenos: .. disqus:: diff --git a/docs/examples/services_miniapp_v2.rst b/docs/examples/services_miniapp_v2.rst index b507c606..4c29fca7 100644 --- a/docs/examples/services_miniapp_v2.rst +++ b/docs/examples/services_miniapp_v2.rst @@ -47,13 +47,11 @@ 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 ~~~~~~~~~~~~~ @@ -62,7 +60,6 @@ Listing of ``container.py``: .. literalinclude:: ../../examples/miniapps/services_v2/container.py :language: python - :linenos: Run application ~~~~~~~~~~~~~~~ @@ -71,7 +68,6 @@ Listing of ``run.py``: .. literalinclude:: ../../examples/miniapps/services_v2/run.py :language: python - :linenos: .. disqus:: diff --git a/docs/examples/use_cases_miniapp.rst b/docs/examples/use_cases_miniapp.rst index cf4a8ab4..03aa7150 100644 --- a/docs/examples/use_cases_miniapp.rst +++ b/docs/examples/use_cases_miniapp.rst @@ -29,7 +29,6 @@ Listing of ``use_cases/containers.py``: .. literalinclude:: ../../examples/miniapps/use_cases/containers.py :language: python - :linenos: Run application ~~~~~~~~~~~~~~~ @@ -38,7 +37,6 @@ Listing of ``run.py``: .. literalinclude:: ../../examples/miniapps/use_cases/run.py :language: python - :linenos: Instructions for running: diff --git a/docs/index.rst b/docs/index.rst index d4f3aa45..9ee19f8d 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,8 +17,6 @@ Dependency Injector --- Dependency injection framework for Python .. _index: -.. figure:: https://raw.githubusercontent.com/wiki/ets-labs/python-dependency-injector/img/logo.svg - .. image:: https://img.shields.io/pypi/v/dependency_injector.svg :target: https://pypi.org/project/dependency-injector/ :alt: Latest Version @@ -63,27 +61,21 @@ Dependency Injector --- Dependency injection framework for Python :target: https://coveralls.io/github/ets-labs/python-dependency-injector?branch=master :alt: Coverage Status -What is ``Dependency Injector``? -================================ +``Dependency Injector`` is a dependency injection framework for Python. -``Dependency Injector`` is a dependency injection microframework for Python. -It was designed to be a unified and developer-friendly tool that helps -implement a dependency injection design pattern in a formal, pretty, and -Pythonic way. +It helps you understand and change the structure of the application. -The key features of the *Dependency Injector* framework are: +With the ``Dependency Injector`` you keep **application structure in one place**. +This place is called **the container**. You use the container to manage all the components of the +application. All the component dependencies are defined explicitly. This provides the control on +the application structure. It is **easy to understand and change** it. -+ Easy, smart, and pythonic style. -+ Obvious and clear structure. -+ Extensibility and flexibility. -+ High performance. -+ Memory efficiency. -+ Thread safety. -+ Documented. -+ Semantically versioned. +.. figure:: https://raw.githubusercontent.com/wiki/ets-labs/python-dependency-injector/img/di-map.svg + :target: https://github.com/ets-labs/python-dependency-injector -*Dependency Injector* containers and providers are implemented as C extension -types using Cython. +*The container is like a map of your application. You always know what depends on what.* + +Explore the documentation to know more about the ``Dependency Injector``. Contents -------- @@ -93,6 +85,7 @@ Contents introduction/index main/installation + tutorials/index providers/index containers/index examples/index diff --git a/docs/introduction/di_in_python.rst b/docs/introduction/di_in_python.rst index b772cf34..65a3727c 100644 --- a/docs/introduction/di_in_python.rst +++ b/docs/introduction/di_in_python.rst @@ -103,21 +103,18 @@ Listing of ``example.engines`` module: .. literalinclude:: ../../examples/miniapps/engines_cars/example/engines.py :language: python - :linenos: Listing of ``example.cars`` module: .. literalinclude:: ../../examples/miniapps/engines_cars/example/cars.py :language: python - :linenos: Next example demonstrates creation of several cars with different engines: .. literalinclude:: ../../examples/miniapps/engines_cars/example_di.py :language: python - :linenos: -While previous example demonstrates advantages of dependency injection, there +While previous example demonstrates advantages of dependency injection, there is a disadvantage demonstration as well - creation of car requires additional code for specification of dependencies. Nevertheless, this disadvantage could be easily avoided by using a dependency injection framework for creation of @@ -128,7 +125,6 @@ using :doc:`Dependency Injector <../index>`: .. literalinclude:: ../../examples/miniapps/engines_cars/example_ioc_containers.py :language: python - :linenos: Useful links ~~~~~~~~~~~~ diff --git a/docs/introduction/key_features.rst b/docs/introduction/key_features.rst index e1d06c29..9ed30269 100644 --- a/docs/introduction/key_features.rst +++ b/docs/introduction/key_features.rst @@ -1,5 +1,5 @@ -Key features of Dependency Injector ------------------------------------ +Key features +------------ .. meta:: :keywords: Python,DI,Dependency injection,IoC,Inversion of Control @@ -7,13 +7,16 @@ Key features of Dependency Injector framework. It also provides some cases and recommendations about usage of "Dependency Injector" framework. -*Dependency Injector* is a dependency injection framework for Python projects. -It was designed to be unified, developer-friendly tool for managing any kind -of Python objects and their dependencies in formal, pretty way. -*Dependency Injector* framework key features are: +``Dependency Injector`` is a dependency injection framework for Python. +It was designed to be a unified and developer-friendly tool that helps +implement a dependency injection design pattern in a formal, pretty, and +Pythonic way. -+ Easy, smart, and pythonic style. +The key features of the ``Dependency Injector`` framework are: + ++ Easy, smart, and Pythonic style. ++ Does NOT pollute client code. + Obvious and clear structure. + Extensibility and flexibility. + High performance. @@ -21,29 +24,28 @@ of Python objects and their dependencies in formal, pretty way. + Thread safety. + Documented. + Semantically versioned. ++ Distributed as pre-compiled wheels. -*Dependency Injector* framework could be used in different application types: +``Dependency Injector`` containers and providers are implemented as C extension +types using ``Cython``. -+ Web applications based on Flask, Django or any other web framework. -+ Asynchronous applications based on asyncio, Tornado and Twisted. +``Dependency Injector`` framework can be used in the different application types: + ++ Web applications based on the ``Flask``, ``Django`` or any other web framework. ++ Asynchronous applications ``asyncio``, ``aiohttp``, ``Tornado``, or ``Twisted``. + Standalone frameworks and libraries. + GUI applications. -*Dependency Injector* framework could be integrated on different project +``Dependency Injector`` framework can be integrated on the different project stages: -+ It could be used in the beginning of development of new applications. -+ It could be integrated into applications that are in active development - stage. -+ It could be used for refactoring of legacy applications. ++ It can be used in the beginning of the development of a new application. ++ It can be integrated into application that is on its active development stage. ++ It can be used for refactoring of legacy application. -Components of *Dependency Injector* framework could be used: +Components of ``Dependency Injector`` framework could be used: + In composition with each other. -+ Separately between each other. - -Main idea of *Dependency Injector* framework is to be useful tool for the -right thing. - ++ Independently from each other. .. disqus:: diff --git a/docs/introduction/what_is_di.rst b/docs/introduction/what_is_di.rst index fb9caa62..82392029 100644 --- a/docs/introduction/what_is_di.rst +++ b/docs/introduction/what_is_di.rst @@ -83,14 +83,12 @@ Let's go through the code of ``example.py``: .. literalinclude:: ../../examples/di_demo/example.py :language: python - :linenos: -At some point, things defined above mean, that the code from ``example.py``, +At some point, things defined above mean, that the code from ``example.py``, could look different, like in ``example_di.py``: .. literalinclude:: ../../examples/di_demo/example_di.py :language: python - :linenos: Best explanation, ever ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/providers/callable.rst b/docs/providers/callable.rst index 3d62ee20..9c82c87f 100644 --- a/docs/providers/callable.rst +++ b/docs/providers/callable.rst @@ -30,7 +30,6 @@ injections: .. literalinclude:: ../../examples/providers/callable_args.py :language: python - :linenos: Next one example shows usage of :py:class:`Callable` with keyword argument injections: @@ -41,7 +40,6 @@ injections: .. literalinclude:: ../../examples/providers/callable_kwargs.py :language: python - :linenos: .. _callable_providers_delegation: diff --git a/docs/providers/configuration.rst b/docs/providers/configuration.rst index 045a0e22..1c36ee21 100644 --- a/docs/providers/configuration.rst +++ b/docs/providers/configuration.rst @@ -9,7 +9,6 @@ Configuration providers :language: python :emphasize-lines: 4,9-10 :lines: 4-14 - :linenos: It implements "use first, define later" principle. @@ -23,13 +22,11 @@ Loading from ``ini`` file :language: python :lines: 3-5,6- :emphasize-lines: 6 - :linenos: where ``examples/providers/configuration/config.ini`` is: .. literalinclude:: ../../examples/providers/configuration/config.ini :language: ini - :linenos: :py:meth:`Configuration.from_ini` supports environment variables interpolation. Use ``${ENV_NAME}`` format in the configuration file to substitute value of environment @@ -45,13 +42,11 @@ Loading from ``yaml`` file :language: python :lines: 3-5,6- :emphasize-lines: 6 - :linenos: where ``examples/providers/configuration/config.yml`` is: .. literalinclude:: ../../examples/providers/configuration/config.yml :language: ini - :linenos: :py:meth:`Configuration.from_yaml` supports environment variables interpolation. Use ``${ENV_NAME}`` format in the configuration file to substitute value of environment @@ -73,7 +68,6 @@ Loading from ``dict`` :language: python :lines: 3-5,6- :emphasize-lines: 6-13 - :linenos: Loading from environment variable ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -85,7 +79,6 @@ Loading from environment variable :language: python :lines: 5-7,13-21 :emphasize-lines: 6-8 - :linenos: Loading from multiple sources ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -97,12 +90,10 @@ configuration is merged recursively over existing configuration. :language: python :lines: 3-5,6-14 :emphasize-lines: 6-7 - :linenos: where ``examples/providers/configuration/config.local.yml`` is: .. literalinclude:: ../../examples/providers/configuration/config.local.yml :language: ini - :linenos: .. disqus:: diff --git a/docs/providers/coroutine.rst b/docs/providers/coroutine.rst index e37b286f..303e420e 100644 --- a/docs/providers/coroutine.rst +++ b/docs/providers/coroutine.rst @@ -18,7 +18,6 @@ coroutine: .. literalinclude:: ../../examples/providers/coroutine_async_await.py :language: python - :linenos: Coroutine providers and injections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/providers/custom.rst b/docs/providers/custom.rst index 54603468..237504c2 100644 --- a/docs/providers/custom.rst +++ b/docs/providers/custom.rst @@ -30,7 +30,6 @@ Example: .. literalinclude:: ../../examples/providers/custom_factory.py :language: python - :linenos: .. disqus:: diff --git a/docs/providers/dependency.rst b/docs/providers/dependency.rst index 6fdbb912..4bd9bf2f 100644 --- a/docs/providers/dependency.rst +++ b/docs/providers/dependency.rst @@ -39,6 +39,5 @@ Example: .. literalinclude:: ../../examples/providers/dependency.py :language: python - :linenos: .. disqus:: diff --git a/docs/providers/factory.rst b/docs/providers/factory.rst index 66fbcbf6..86093384 100644 --- a/docs/providers/factory.rst +++ b/docs/providers/factory.rst @@ -14,7 +14,6 @@ Nothing could be better than brief example: .. literalinclude:: ../../examples/providers/factory.py :language: python - :linenos: Factory providers and __init__ injections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -48,7 +47,6 @@ injectable values are also provided by another factories: .. literalinclude:: ../../examples/providers/factory_init_injections.py :language: python - :linenos: .. _factory_providers_delegation: @@ -92,7 +90,6 @@ Example: .. literalinclude:: ../../examples/providers/factory_delegation.py :language: python - :linenos: .. _factory_providers_specialization: @@ -107,7 +104,6 @@ provided type: .. literalinclude:: ../../examples/providers/factory_provided_type.py :language: python - :linenos: .. _abstract_factory_providers: @@ -142,13 +138,11 @@ Listing of ``cache.py``: .. literalinclude:: ../../examples/providers/abstract_factory/cache.py :language: python - :linenos: Listing of ``example.py``: .. literalinclude:: ../../examples/providers/abstract_factory/example.py :language: python - :linenos: Factory aggregate providers ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -167,7 +161,6 @@ Next prototype might be the best demonstration of .. literalinclude:: ../../examples/providers/factory_aggregate/prototype.py :language: python - :linenos: Example below shows one of the :py:class:`FactoryAggregate` use cases, when concrete implementation (game) must be selected based on dynamic input (CLI). @@ -176,12 +169,10 @@ Listing of ``games.py``: .. literalinclude:: ../../examples/providers/factory_aggregate/games.py :language: python - :linenos: Listing of ``example.py``: .. literalinclude:: ../../examples/providers/factory_aggregate/example.py :language: python - :linenos: .. disqus:: diff --git a/docs/providers/list.rst b/docs/providers/list.rst index 58f89f44..4b92eeca 100644 --- a/docs/providers/list.rst +++ b/docs/providers/list.rst @@ -9,7 +9,6 @@ List providers :language: python :emphasize-lines: 6-9 :lines: 6-8, 23-29 - :linenos: :py:class:`List` provider is needed for injecting a list of dependencies. It handles positional argument injections the same way as :py:class:`Factory` provider: @@ -27,7 +26,6 @@ Full example: :language: python :emphasize-lines: 23-26 :lines: 3- - :linenos: .. note:: diff --git a/docs/providers/object.rst b/docs/providers/object.rst index 00bae167..6599dd92 100644 --- a/docs/providers/object.rst +++ b/docs/providers/object.rst @@ -9,7 +9,6 @@ Example: .. literalinclude:: ../../examples/providers/object.py :language: python - :linenos: .. disqus:: diff --git a/docs/providers/overriding.rst b/docs/providers/overriding.rst index d7876e6a..7c0770bb 100644 --- a/docs/providers/overriding.rst +++ b/docs/providers/overriding.rst @@ -33,7 +33,6 @@ Example: .. literalinclude:: ../../examples/providers/overriding_simple.py :language: python - :linenos: Example: @@ -43,7 +42,6 @@ Example: .. literalinclude:: ../../examples/providers/overriding_users_model.py :language: python - :linenos: .. disqus:: diff --git a/docs/providers/selector.rst b/docs/providers/selector.rst index a8920253..883e4fa0 100644 --- a/docs/providers/selector.rst +++ b/docs/providers/selector.rst @@ -9,7 +9,6 @@ Selector providers :language: python :emphasize-lines: 6-10 :lines: 3-5,14-20 - :linenos: :py:class:`Selector` provider has a callable called ``selector`` and a dictionary of providers. @@ -26,6 +25,5 @@ Full example: :language: python :emphasize-lines: 14-18 :lines: 3- - :linenos: .. disqus:: diff --git a/docs/providers/singleton.rst b/docs/providers/singleton.rst index 88d4c006..f479770f 100644 --- a/docs/providers/singleton.rst +++ b/docs/providers/singleton.rst @@ -14,7 +14,6 @@ Example: .. literalinclude:: ../../examples/providers/singleton.py :language: python - :linenos: Singleton providers resetting ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -28,7 +27,6 @@ Example: .. literalinclude:: ../../examples/providers/singleton_resetting.py :language: python - :linenos: Singleton providers and injections ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -108,7 +106,6 @@ Example: .. literalinclude:: ../../examples/providers/singleton_thread_locals.py :language: python - :linenos: .. disqus:: diff --git a/docs/tutorials/aiohttp.rst b/docs/tutorials/aiohttp.rst new file mode 100644 index 00000000..84f2d82e --- /dev/null +++ b/docs/tutorials/aiohttp.rst @@ -0,0 +1,4 @@ +Aiohttp tutorial +================ + +Coming soon... diff --git a/docs/tutorials/asyncio.rst b/docs/tutorials/asyncio.rst new file mode 100644 index 00000000..406c3788 --- /dev/null +++ b/docs/tutorials/asyncio.rst @@ -0,0 +1,4 @@ +Asyncio tutorial +================ + +Coming soon... diff --git a/docs/tutorials/flask.rst b/docs/tutorials/flask.rst new file mode 100644 index 00000000..b0a25ac7 --- /dev/null +++ b/docs/tutorials/flask.rst @@ -0,0 +1,4 @@ +Flask tutorial +============== + +Coming soon... diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst new file mode 100644 index 00000000..d3efc2b6 --- /dev/null +++ b/docs/tutorials/index.rst @@ -0,0 +1,12 @@ +Tutorials +========= + +This section contains tutorials that show how to apply dependency injection for popular Python +frameworks. + +.. toctree:: + :maxdepth: 2 + + flask + aiohttp + asyncio diff --git a/examples/di_demo/example.py b/examples/di_demo/example.py index 4aaa9590..8f4a4234 100644 --- a/examples/di_demo/example.py +++ b/examples/di_demo/example.py @@ -2,16 +2,16 @@ class Service: - """Some "Service".""" + """The Service.""" class Client: - """Some "Client" that uses "Service".""" + """The Client that uses the Service.""" def __init__(self): - """Initialize instance.""" - self.service = Service() # Service instance is created inside Client + """Initialize the Client.""" + self.service = Service() # The Service is created by the Client if __name__ == '__main__': - client = Client() # Application creates Client's instance + client = Client() # Application creates the Client diff --git a/examples/di_demo/example_di.py b/examples/di_demo/example_di.py index cd19c591..ddbbe14b 100644 --- a/examples/di_demo/example_di.py +++ b/examples/di_demo/example_di.py @@ -1,18 +1,18 @@ -"""The Code, that demonstrates dependency injection pattern.""" +"""The Code that demonstrates dependency injection pattern.""" class Service: - """Some "Service".""" + """The Service.""" class Client: - """Some "Client" that uses "Service".""" + """The Client that uses the Service.""" - def __init__(self, service): # Service instance is injected into Client - """Initialize instance.""" + def __init__(self, service): # The Service is injected into the Client + """Initialize the Client.""" self.service = service if __name__ == '__main__': - service = Service() # Application creates Service instance - client = Client(service) # and inject Service instance into the Client + service = Service() # Application creates the Service + client = Client(service) # and inject the Service into the Client diff --git a/examples/miniapps/engines_cars/example/engines.py b/examples/miniapps/engines_cars/example/engines.py index 9cdfd357..191f9e88 100644 --- a/examples/miniapps/engines_cars/example/engines.py +++ b/examples/miniapps/engines_cars/example/engines.py @@ -4,8 +4,8 @@ class Engine: """Example engine base class. - Engine is a heart of every car. Engine is a very common term and could be - implemented in very different ways. + Engine is a heart of every car. Engine is a very common term and + could be implemented in very different ways. """ diff --git a/examples/miniapps/ghnav-flask/githubnavigator/application.py b/examples/miniapps/ghnav-flask/githubnavigator/application.py index bcac7289..297c5812 100644 --- a/examples/miniapps/ghnav-flask/githubnavigator/application.py +++ b/examples/miniapps/ghnav-flask/githubnavigator/application.py @@ -12,6 +12,9 @@ def create_app(): app = container.app() app.container = container + bootstrap = container.bootstrap() + bootstrap.init_app(app) + app.add_url_rule('/', view_func=container.index_view.as_view()) return app diff --git a/examples/miniapps/ghnav-flask/githubnavigator/containers.py b/examples/miniapps/ghnav-flask/githubnavigator/containers.py index 40f4d435..872640f1 100644 --- a/examples/miniapps/ghnav-flask/githubnavigator/containers.py +++ b/examples/miniapps/ghnav-flask/githubnavigator/containers.py @@ -3,6 +3,7 @@ from dependency_injector import containers, providers from dependency_injector.ext import flask from flask import Flask +from flask_bootstrap import Bootstrap from github import Github from . import views, services @@ -13,6 +14,8 @@ class ApplicationContainer(containers.DeclarativeContainer): app = flask.Application(Flask, __name__) + bootstrap = flask.Extension(Bootstrap) + config = providers.Configuration() github_client = providers.Factory( diff --git a/examples/miniapps/ghnav-flask/githubnavigator/services.py b/examples/miniapps/ghnav-flask/githubnavigator/services.py index 413e9b04..9df52007 100644 --- a/examples/miniapps/ghnav-flask/githubnavigator/services.py +++ b/examples/miniapps/ghnav-flask/githubnavigator/services.py @@ -29,7 +29,6 @@ class SearchService: 'url': repository.owner.html_url, 'avatar_url': repository.owner.avatar_url, }, - 'created_at': repository.created_at, 'latest_commit': self._format_commit(commits[0]) if commits else {}, } diff --git a/examples/miniapps/ghnav-flask/githubnavigator/templates/base.html b/examples/miniapps/ghnav-flask/githubnavigator/templates/base.html new file mode 100644 index 00000000..2797916a --- /dev/null +++ b/examples/miniapps/ghnav-flask/githubnavigator/templates/base.html @@ -0,0 +1,26 @@ + + + + {% block head %} + + + + + {% block styles %} + + {{ bootstrap.load_css() }} + {% endblock %} + + {% block title %}{% endblock %} + {% endblock %} + + + + {% block content %}{% endblock %} + + {% block scripts %} + + {{ bootstrap.load_js() }} + {% endblock %} + + diff --git a/examples/miniapps/ghnav-flask/githubnavigator/templates/index.html b/examples/miniapps/ghnav-flask/githubnavigator/templates/index.html index ecb7d266..9f75018e 100644 --- a/examples/miniapps/ghnav-flask/githubnavigator/templates/index.html +++ b/examples/miniapps/ghnav-flask/githubnavigator/templates/index.html @@ -1,40 +1,55 @@ - - - - Github Navigator - - -

Github Navigator

-
+{% extends "base.html" %} + +{% block title %}Github Navigator{% endblock %} + +{% block content %} +
+

Github Navigator

+ + +
+ +
+ +
+
+ + + {% if repositories|length == 0 %} + No search results + {% endif %} +

- Search term: - Limit: - + Results found: {{ repositories|length }}

- -

Search results

-{% if repositories|length == 0 %} -No search results -{% endif %} -{% for repository in repositories %} {{n}} -

- Search result # {{ loop.index }} from {{ repositories|length }} -

-

- Repository: {{ repository.name }} -

-

- Repository owner: - avatar - {{ repository.owner.login }} -

-

- Created at: {{ repository.created_at }} -

-

- LastCommit: {{ repository.latest_commit.sha }} {{ repository.latest_commit['message'] }} {{ repository.latest_commit.author_name }} -

-
-{% endfor %} - - + + + + + + + + + + + + + {% for repository in repositories %} {{n}} + + + + + + + {% endfor %} + + +
#RepositoryRepository ownerLast commit
{{ loop.index }}{{ repository.name }}avatar + {{ repository.owner.login }} + {{ repository.latest_commit.sha }} {{ repository.latest_commit['message'] }} {{ repository.latest_commit.author_name }}
+
+ +{% endblock %} diff --git a/examples/miniapps/ghnav-flask/githubnavigator/tests.py b/examples/miniapps/ghnav-flask/githubnavigator/tests.py index 0d6267ed..fa36678c 100644 --- a/examples/miniapps/ghnav-flask/githubnavigator/tests.py +++ b/examples/miniapps/ghnav-flask/githubnavigator/tests.py @@ -25,7 +25,6 @@ def test_index(client, app): html_url='owner1-url', avatar_url='owner1-avatar-url', ), - created_at='repo1-created-at', get_commits=mock.Mock(return_value=[mock.Mock()]), ), mock.Mock( @@ -36,7 +35,6 @@ def test_index(client, app): html_url='owner2-url', avatar_url='owner2-avatar-url', ), - created_at='repo2-created-at', get_commits=mock.Mock(return_value=[mock.Mock()]), ), ] @@ -51,14 +49,12 @@ def test_index(client, app): assert b'owner1-login' in response.data assert b'owner1-url' in response.data assert b'owner1-avatar-url' in response.data - assert b'repo1-created-at' in response.data assert b'repo2-url' in response.data assert b'repo2-name' in response.data assert b'owner2-login' in response.data assert b'owner2-url' in response.data assert b'owner2-avatar-url' in response.data - assert b'repo2-created-at' in response.data def test_index_no_results(client, app): diff --git a/examples/providers/abstract_factory/example.py b/examples/providers/abstract_factory/example.py index 2bad9a77..46382afa 100644 --- a/examples/providers/abstract_factory/example.py +++ b/examples/providers/abstract_factory/example.py @@ -10,19 +10,27 @@ cache_client_factory = providers.AbstractFactory(cache.AbstractCacheClient) if __name__ == '__main__': # Override abstract factory with redis client factory: - cache_client_factory.override(providers.Factory(cache.RedisCacheClient, - host='localhost', - port=6379, - db=0)) + cache_client_factory.override( + providers.Factory( + cache.RedisCacheClient, + host='localhost', + port=6379, + db=0, + ), + ) redis_cache = cache_client_factory() - print(redis_cache) # + print(redis_cache) + # # Override abstract factory with memcache client factory: - cache_client_factory.override(providers.Factory(cache.MemcacheCacheClient, - hosts=['10.0.1.1', - '10.0.1.2', - '10.0.1.3'], - port=11211, - prefix='my_app')) + cache_client_factory.override( + providers.Factory( + cache.MemcacheCacheClient, + hosts=['10.0.1.1', '10.0.1.2', '10.0.1.3'], + port=11211, + prefix='my_app', + ), + ) memcache_cache = cache_client_factory() - print(memcache_cache) # + print(memcache_cache) + # diff --git a/examples/providers/factory_aggregate/example.py b/examples/providers/factory_aggregate/example.py index 53fe69eb..906c8484 100644 --- a/examples/providers/factory_aggregate/example.py +++ b/examples/providers/factory_aggregate/example.py @@ -7,9 +7,11 @@ import dependency_injector.providers as providers from games import Chess, Checkers, Ludo -game_factory = providers.FactoryAggregate(chess=providers.Factory(Chess), - checkers=providers.Factory(Checkers), - ludo=providers.Factory(Ludo)) +game_factory = providers.FactoryAggregate( + chess=providers.Factory(Chess), + checkers=providers.Factory(Checkers), + ludo=providers.Factory(Ludo), +) if __name__ == '__main__': game_type = sys.argv[1].lower() diff --git a/examples/providers/factory_delegation.py b/examples/providers/factory_delegation.py index 64ce36ce..f57d2dc9 100644 --- a/examples/providers/factory_delegation.py +++ b/examples/providers/factory_delegation.py @@ -26,27 +26,36 @@ class User: # Defining User and Photo factories using DelegatedFactory provider: photos_factory = providers.DelegatedFactory(Photo) -users_factory = providers.DelegatedFactory(User, - photos_factory=photos_factory) +users_factory = providers.DelegatedFactory( + User, + photos_factory=photos_factory, +) # or using Delegate(Factory(...)) photos_factory = providers.Factory(Photo) -users_factory = providers.Factory(User, - photos_factory=providers.Delegate( - photos_factory)) +users_factory = providers.Factory( + User, + photos_factory=providers.Delegate(photos_factory), +) # or using Factory(...).delegate() photos_factory = providers.Factory(Photo) -users_factory = providers.Factory(User, - photos_factory=photos_factory.delegate()) +users_factory = providers.Factory( + User, + photos_factory=photos_factory.delegate(), +) # Creating several User objects: -user1 = users_factory() # Same as: user1 = User(photos_factory=photos_factory) -user2 = users_factory() # Same as: user2 = User(photos_factory=photos_factory) +user1 = users_factory() +user2 = users_factory() + +# Same as: +# user1 = User(photos_factory=photos_factory) +# user2 = User(photos_factory=photos_factory) # Making some asserts: assert isinstance(user1.main_photo, Photo) @@ -55,13 +64,18 @@ assert isinstance(user2.main_photo, Photo) # or using Factory(...).provider photos_factory = providers.Factory(Photo) -users_factory = providers.Factory(User, - photos_factory=photos_factory.provider) - +users_factory = providers.Factory( + User, + photos_factory=photos_factory.provider, +) # Creating several User objects: -user1 = users_factory() # Same as: user1 = User(photos_factory=photos_factory) -user2 = users_factory() # Same as: user2 = User(photos_factory=photos_factory) +user1 = users_factory() +user2 = users_factory() + +# Same as: +# user1 = User(photos_factory=photos_factory) +# user2 = User(photos_factory=photos_factory) # Making some asserts: assert isinstance(user1.main_photo, Photo) diff --git a/examples/providers/singleton.py b/examples/providers/singleton.py index 92fcdf9d..97fe5c02 100644 --- a/examples/providers/singleton.py +++ b/examples/providers/singleton.py @@ -7,8 +7,8 @@ import dependency_injector.providers as providers UsersService = collections.namedtuple('UsersService', []) -# Singleton provider creates new instance of specified class on first call and -# returns same instance on every next call. +# Singleton provider creates new instance of specified class on first call +# and returns same instance on every next call. users_service_provider = providers.Singleton(UsersService) # Retrieving several UserService objects: diff --git a/examples/providers/singleton_thread_locals.py b/examples/providers/singleton_thread_locals.py index f85cd812..7c1a0aa3 100644 --- a/examples/providers/singleton_thread_locals.py +++ b/examples/providers/singleton_thread_locals.py @@ -18,19 +18,22 @@ thread_local_object = providers.ThreadLocalSingleton(object) queue_factory = providers.ThreadSafeSingleton(queue.Queue) # Create callable provider for example(), inject dependencies: -example = providers.DelegatedCallable(example, - example_object=thread_local_object, - queue_object=queue_factory) +example = providers.DelegatedCallable( + example, + example_object=thread_local_object, + queue_object=queue_factory, +) -# Create factory provider for threads that are targeted to execute example(): -thread_factory = providers.Factory(threading.Thread, - target=example) +# Create factory for threads that are targeted to execute example(): +thread_factory = providers.Factory(threading.Thread, target=example) if __name__ == '__main__': # Create 10 threads for concurrent execution of example(): threads = [] for thread_number in range(10): - threads.append(thread_factory(name='Thread{0}'.format(thread_number))) + threads.append( + thread_factory(name='Thread{0}'.format(thread_number)), + ) # Start execution of all created threads: for thread in threads: diff --git a/requirements-doc.txt b/requirements-doc.txt index fd0b9248..1223452c 100644 --- a/requirements-doc.txt +++ b/requirements-doc.txt @@ -1,5 +1,5 @@ sphinx -sphinx_rtd_theme>=0.2.5b2 +alabaster>=0.7.12 -e git://github.com/rmk135/sphinxcontrib-disqus.git#egg=sphinxcontrib-disqus -r requirements-ext.txt