Перевод статьи по методу Ильи Франка.

Источник: ссылка
Structuring (структурирование) a Flask Project 
Introduction
Flask provides (предоставляет) such (такую) great (большую) flexibility (гибкость) when (когда/при) developing a web application, including (включая) the structure of the application. Flask applications can range (варьироваться) from (от) a single file to (к) larger (более крупным) projects with multiple Blueprints (дословно: "эскиз". используется для разделения приложения на части). In this blog post, I’m going to (собираюсь) describe (описать) how I like (как мне нравится) to structure (структурировать) a Flask application using (используя) Blueprints and an Application Factory function. 
For reference (для справки), the project that (который) I created (создал) as part (как часть) of writing (написанного) this blog post is available (доступен) on GitLab: Flask User Management Example.
Structuring a Flask Project

Introduction

Flask provides such great flexibility when developing a web application, including the structure of the application. Flask applications can range from a single file to larger projects with multiple Blueprints. In this blog post, I’m going to describe how I like to structure a Flask application using Blueprints and an Application Factory function.

For reference, the project that I created as part of writing this blog post is available on GitLab: Flask User Management Example.


Blueprints 
Blueprints allow (позволяют) you to cleanly (четко) organize (организовать) the source code (исходный код/исходники) of your Flask application. Each (каждый) Blueprint encapsulates (инкапсулирует) a significant (значительную) piece of functionality (функциональности) in your application. For example (например), I like (мне нравится) to have (иметь) a separate (отдельный) Blueprint for handling (обработки) the user management (управления пользователями) of a Flask application.
I like to create a separate (отдельный) package (пакет) (ie. (т.е.) a directory that includes the __init__.py file) for each Blueprint. For example, here is the structure of the Flask User Management example that contains (содержит) two Blueprints (recipes (рецепты) and users):
(venv) $ tree -L 5
.
├── README.md
├── instance
├── main.py
├── project
│   ├── __init__.py
│   ├── models.py
│   ├── recipes
│   │   ├── __init__.py
│   │   ├── routes.py
│   │   └── templates
│   │       └── recipes
│   │           └── index.html
│   ├── templates
│   │   └── base.html
│   └── users
│       ├── __init__.py
│       ├── forms.py
│       ├── routes.py
│       └── templates
│           └── users
│               ├── login.html
│               ├── profile.html
│               └── register.html
├── requirements.txt
└── venv
    ├── bin
    │   ├── activate
     |    ├── ...

Taking a look (взглянем) at a single (отдельный) Blueprint (users), it encapsulates (инкапсулирует) all of components to handle the user management aspects (аспекты) of the application (defining routes (определение маршрутов / определение url'ов), handling forms (обработка форм), generating templates (генерация шаблонов)):

Taking a look at a single Blueprint (users), it encapsulates all of components to handle the user management aspects of the application (defining routes, handling forms, generating templates):

users
├── __init__.py
├── forms.py
├── routes.py
└── templates
    └── users
        ├── login.html
        ├── profile.html
        └── register.html

The subfolders (вложенные папки) for storing (для хранения) the template files may look (выглядеть) strange (странно), but this structure (…/blueprint_name/templates/blueprint_name/) is recommended (рекомендована) in the Flask documentation. The template directory for each Blueprint gets added (добавляется) to the search path (к пути поиска) for template files within (в) your Flask application. With this structure, you can define the templates for each Blueprint within the Blueprint, but still (при этом) import (импортировать) a base (базовый) template (in …/project/templates/) that gets (будет) shared (использоватья) by all (всеми) the Blueprints. With this structure, the template file for a Blueprint can be accessed (получить) using ‘users/login.html’. 
In order to (чтобы) create the Blueprint, an object of the Blueprint class (объет класса Blueprint) gets instantiated (создаем экземпляр) in the __init__.py file of the Blueprint folder:
The subfolders for storing the template files may look strange, but this structure (…/blueprint_name/templates/blueprint_name/) is recommended in the Flask documentation. The template directory for each Blueprint gets added to the search path for template files within your Flask application. With this structure, you can define the templates for each Blueprint within the Blueprint, but still import a base template (in …/project/templates/) that gets shared by all the Blueprints. With this structure, the template file for a Blueprint can be accessed using ‘users/login.html’.

In order to create the Blueprint, an object of the Blueprint class gets instantiated in the __init__.py file of the Blueprint folder:

"""
The users Blueprint handles the user management for this application.
Specifically, this Blueprint allows for new users to register and for
users to log in and to log out of the application.
"""
from flask import Blueprint
users_blueprint = Blueprint('users', __name__, template_folder='templates')
from . import routes

This instantiation (экземпляр) of the Blueprint specifies(определяет/указывает) the name of the Blueprint (users) and it specifies (определяет) the location (местоположение) of the template files within the Blueprint. Additionally (кроме того), the last line (последняя строка) imports (импортирует) the routes (маршруты) created (созданные) in routes.py.
This instantiation of the Blueprint specifies the name of the Blueprint (users) and it specifies the location of the template files within the Blueprint. Additionally, the last line imports the routes created in routes.py.

The users_blueprint that was created in __init__.py is then imported in the routes.py file:

#################
#### imports ####
#################
from . import users_blueprint

This import allows the routes that are being created in routes.py to be specified with ‘@users_blueprint’:

################
#### routes ####
################
@users_blueprint.route('/')
def index():
    return render_template('index.html')

After creating a Blueprint (and registering it (и его регистрации)), you can check (проверить) that the routes are being created (создаются) successfully (успешно) by checking (проверяя) the mapping (сопоставления) of the URLs to specific functions. The best way (способ) to see this is to bring up (вызвать) the Python interpreter (интерпретатор) with the key Flask components loaded (загруженных) using flask shell (оболочки) :
After creating a Blueprint (and registering it), you can check that the routes are being created successfully by checking the mapping of the URLs to specific functions. The best way to see this is to bring up the Python interpreter with the key Flask components loaded using flask shell:

(venv) $ flask shell
>>> print(app.url_map)
Map([ users.register>,
  users.profile>,
  users.logout>,
  users.login>,
  recipes.index>,
 ' (OPTIONS, HEAD, GET) -> static>])

This shows (видно) that the URLs are being mapped (отображаются) correctly (правильно) to the functions in the Blueprints.
 This shows that the URLs are being mapped correctly to the functions in the Blueprints.
Application Factory (Завод-изготовитель ;) )
The initialization (инициализация) of a Flask project requires (требует) the following steps:
  • Creating the Flask application as an instance (экземпляр объекта) of the Flask class
  • Configuring the Flask application
  • Initializing the extensions (расширений) to be used (для использования / которые будут использованы)
  • Registering the Blueprints in the project
Application Factory 

The initialization of a Flask project requires the following steps:

Creating the Flask application as an instance of the Flask class
Configuring the Flask application
Initializing the extensions to be used
Registering the Blueprints in the project

These steps can be put together (положены вместе / объединены) in a single function called (называемую) an Application Factory function (an implementation of the Factory method pattern). In addition (кроме того) to making it clear (выяснить / понять) what steps need to be taken (предпринять) to initialize a Flask application, the Application Factory function allows different (различные) Flask applications to be created with different configurations. This flexibility becomes (становится) very useful (полезной) during (во время) testing, where the configuration can often be different (отличаться) from development or production.

These steps can be put together in a single function called an Application Factory function (an implementation of the Factory method pattern). In addition to making it clear what steps need to be taken to initialize a Flask application, the Application Factory function allows different Flask applications to be created with different configurations. This flexibility becomes very useful during testing, where the configuration can often be different from development or production.

The Application Factory function is created in the …/project/__init__.py file. To start, import all of the modules (including the Flask extensions) that are needed for the Flask project:

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager
from flask_bcrypt import Bcrypt

Next (далее), create the instances of each of the Flask extensions without initializing them:

#######################
#### Configuration ####
#######################
# Create the instances of the Flask extensions (flask-sqlalchemy, flask-login, etc.) in
# the global scope, but without any arguments passed in. These instances are not attached
# to the application at this point.
# Create the instances of the Flask extensions (flask-sqlalchemy, flask-login, etc.) in
# the global scope (область видимости), but without (без) any arguments passed in (передачи). These instances (эти экземпляры)
# are not attached (не прилагаются) to the application at this point (в данный момент).
db = SQLAlchemy()
bcrypt = Bcrypt()
login = LoginManager()
login.login_view = "users.login"

Next, the actual Application Factory function (create_app) is defined (определяется):

######################################
#### Application Factory Function ####
######################################
def create_app(config_filename=None):
  app = Flask(__name__, instance_relative_config=True)
  app.config.from_pyfile(config_filename)
  initialize_extensions(app)
  register_blueprints(app)
  return app

The function to initialize (для инициализации) each Flask extension (расширения) passes in (проходит в) the Flask application to each extension:
The function to initialize each Flask extension passes in the Flask application to each extension:

def initialize_extensions(app):
  # Since the application instance is now created, pass it to each Flask
  # extension instance to bind it to the Flask application instance (app)
  db.init_app(app)
  bcrypt.init_app(app)
  login.init_app(app)
  ...

Finally (в конце), all of the Blueprints are registered (зарегистрированы) with the Flask application:

Finally, all of the Blueprints are registered with the Flask application:

def register_blueprints(app):
  # Since (поскольку) the application instance is now created, register each Blueprint
  # with the Flask application instance (app)
  from project.recipes import recipes_blueprint
  from project.users import users_blueprint
  app.register_blueprint(recipes_blueprint)
  app.register_blueprint(users_blueprint)

After creating the Application Factory function, it gets used in the …/main.py file:

from project import create_app
# Call the Application Factory function to construct a Flask application instance
# using the standard configuration defined in /instance/flask.cfg
app = create_app('flask.cfg')

Now the Flask application is ready to run using:

(venv) $ export FLASK_APP=main.py
(venv) $ flask run
* Serving Flask app "main"
* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Overall Structure (общая структура) 
The overall structure for this project is shown (показана) below (ниже):

Overall Structure

The overall structure for this project is shown below :

(venv) $ tree -L 3
.
├── README.md
├── instance
├── main.py
├── project
│ ├── __init__.py
│ ├── models.py
│ ├── recipes
│ │ ├── __init__.py
│ │ ├── routes.py
│ │ └── templates
│ ├── templates
│ │ └── base.html
│ └── users
│ ├── __init__.py
│ ├── forms.py
│ ├── routes.py
│ └── templates
├── requirements.txt
└── venv
  ├── bin
  ├── ...
The Blueprints are defined in separate modules in the …/project folder. The Application Factory function is defined in the …/project/__init__.py file. The actual Flask application is then created in …/main.py.

Conclusion (вывод) 
This blog post described (описывает) how to use Blueprints and an Application Factory function to help structure a Flask project. Blueprints provide (предоставляют) a great tool (отличный инструмент) to organize your project into major (основные) pieces (части) of functionality (функционала). An Application Factory function provides a clean method for creating the Flask application. Put together (в совокупности), these are the two primary (первичные/основные) ideas that I use to structure a Flask project.

Conclusion

This blog post described how to use Blueprints and an Application Factory function to help structure a Flask project. Blueprints provide a great tool to organize your project into major pieces of functionality. An Application Factory function provides a clean method for creating the Flask application. Put together, these are the two primary ideas that I use to structure a Flask project.

0 комментариев:

Отправить комментарий