diff --git a/docs/tutorials/flask.rst b/docs/tutorials/flask.rst index b0a25ac7..ec11c109 100644 --- a/docs/tutorials/flask.rst +++ b/docs/tutorials/flask.rst @@ -1,4 +1,185 @@ Flask tutorial ============== -Coming soon... +This tutorials shows how to build ``Flask`` application following dependency injection principle. + +What are we going to build? +--------------------------- + +We will build a web application that helps to search for repositories on Github. Let's call it +Github Navigator. + +How does Github Navigator work? + +- User opens a web page that asks to provide a search term. +- User types the search term and hits Enter. +- Github Navigator takes that and searches through the Github for matching repositories. +- When search is done Github Navigator returns user a web page with the result. +- The results page shows all matching repositories and the provided search term. +- For any matching repository user sees: + - the repository name + - the owner of the repository + - the last commit to the repository +- User can click on the repository, the repository owner or the last commit to open its web page + on the Github. + +Prepare the environment +----------------------- + +Let's create the environment for the project. + +First we need to create a project folder and the virtual environment: + +.. code-block:: bash + + mkdir ghnav-flask-tutorial + cd ghnav-flask-tutorial + python3 -m venv venv + +Now let's activate the virtual environment: + +.. code-block:: bash + + . venv/bin/activate + +Project layout +-------------- + +Environment is ready and now we're going to create the layout of the project. + +Create next structure in the current directory. All files should be empty. That's ok for now. + +Initial project layout:: + + ./ + ├── githubnavigator/ + │ ├── __init__.py + │ ├── application.py + │ ├── containers.py + │ └── views.py + ├── venv/ + └requirements.txt + +Now it's time to install ``Flask`` and ``Dependency Injector``. + +Put next lines to the ``requirements.txt`` file:: + + flask + dependency-injector + +Now let's install it:: + + pip install -r requirements.txt + +And check that installation is successful:: + + python -c "import flask; print(flask.__version__)" + python -c "import dependency_injector; print(dependency_injector.__version__)" + + +You should see something like:: + + (venv) $ python -c "import flask; print(flask.__version__)" + 1.1.2 + (venv) $ python -c "import dependency_injector; print(dependency_injector.__version__)" + 3.22.0 + +*Versions can be different. That's fine.* + +Hello world! +------------ + +Let's create minimal application. + +Put next to the ``views.py``: + +.. code-block:: python + + """Views module.""" + + + def index(): + return 'Hello, World!' + +Ok, we have the view. + +Now let's create the heart of our application - the container. Container will keep all of the +application components and their dependencies. First two providers we need to add are +the ``Flask`` application provider and the view provider. + +Put next to the ``containers.py``: + +.. code-block:: python + + """Application containers module.""" + + from dependency_injector import containers + from dependency_injector.ext import flask + from flask import Flask + + from . import views + + + class ApplicationContainer(containers.DeclarativeContainer): + """Application container.""" + + app = flask.Application(Flask, __name__) + + index_view = flask.View(views.index) + +Finally we need to create the Flask application factory. It is traditionally called +``create_app()``. It will create the container. After that it will use the container to create +the Flask application. Last step is to configure the routing - we will assign ``index_view`` from the +container to handle user requests to the root ``/`` if our web application. + +Put next to the ``application.py``: + +.. code-block:: python + + """Application module.""" + + from .containers import ApplicationContainer + + + def create_app(): + """Create and return Flask application.""" + container = ApplicationContainer() + + app = container.app() + app.container = container + + app.add_url_rule('/', view_func=container.index_view.as_view()) + + return app + +.. note:: + + Container is the first object in the application. + + The container is used to create all other components. + +Ok. Now we're ready to say "Hello, World!". + +Do next in the terminal:: + + export FLASK_APP=githubnavigator.application + export FLASK_ENV=development + flask run + + + +The output should be something like:: + + * Serving Flask app "githubnavigator.application" (lazy loading) + * Environment: development + * Debug mode: on + * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) + * Restarting with fsevents reloader + * Debugger is active! + * Debugger PIN: 473-587-859 + +Open your browser and go to the ``http://127.0.0.1:5000/``. + +You should see ``Hello, World!``. + +That's it. Our minimal application is up and running.