Foreword
Last year I decided to get acquainted closely with Python, and later move to it with PHP. At the moment, my path is web development, and therefore I started to learn a new language from the web side, in particular, with an overview of the available frameworks and projects for them. Acquainted with the possibilities of TurboGears, web2py, Django, I still succumbed to the "trend" and plunged into the world of Django.
For almost a year, I honestly tried to make friends with him. I wrote some unpretentious projects, but the framework's monstrosity was scary, the abundance of “batteries” confused the choice, and did not want to put up with some restrictions. The soul required conciseness and unambiguity, which ultimately led me to get acquainted with Flask. Having studied the documentation on the framework and related projects (Jinja2, Werkzeug), I imbued with the ideology and began to closely study the framework.
Flask is positioned as an expandable microframe. This means that only the necessary minimum of functionality is present, but at the same time it is possible to add it through extensions to the level required by the project.
')
This epic is my experience under using Flask and extensions for it, or rather, an attempt to bring together and in Russian something that can be useful when creating projects of almost any level.
Structure and configuration
For each project, I follow the typical structure described below. Everything is rather trivial and familiar to Django programmers:
app/ --commands/ --migrations/ --static/ --templtaes/ --app.py --config.py --forms.py --manage.py --models.py --views.py
- The commands directory contains commands for servicing the application, connected in the manage.py module.
- Migrations directory - files and configurations of migrations. Usually created automatically when migrations are initialized.
- Catalog static - project resources: js, css, scss and pictures.
- Catalog templates - templates.
- The app.py file is the head module of the application, where the main settings are defined and extensions are registered, it also implements the web server.
- The manage.py file is used to manage and maintain the project.
- The config.py file contains the application configuration object. I note that Flask can be configured in various ways, but the most convenient method seemed to me based on objects. In simplified form, the contents of the file looks like this:
config.py import os basedir = os.path.abspath(os.path.dirname(__file__)) class Config(object): DEBUG = False CSRF_ENABLED = True WTF_CSRF_SECRET_KEY = 'dsofpkoasodksap' SECRET_KEY = 'zxczxasdsad' SQLALCHEMY_DATABASE_URI = 'mysql+mysqlconnector://webuser:web_password@localhost/webuser_db' class ProductionConfig(Config): DEBUG = False class DevelopConfig(Config): DEBUG = True ASSETS_DEBUG = True
And its use is as follows:
app.py app.config.from_object('config.DevelopConfig')
For large projects, official documentation recommends splitting up the functionality into so-called
blueprints — modules that are structurally similar to the Flask application, and organize the project itself into a python package. But today is not about that.
Extensions
Flask-SQLAlchemy
Any serious application uses databases. This extension makes Flask friends with the most popular Python ORM library, SQLAlchemy, allowing you to use any DBMS supported by it, as well as mapping tables to Python objects, similar to Django. However, SQLAlchemy allows you to do without ORM.
Documentation:
pythonhosted.org/Flask-SQLAlchemyFlask-script
Adds support for project serving scripts: starting a dev server, migrating databases, cron tasks and the like. Following the recommendations, I create for each project a file
manage.py , where all the necessary maintenance teams are added. By default, the
runserver command is
available . Commands are executed as follows:
$ python manage.py command <action> $ python manage.py runserver $ python manage.py db migate
You can add a command, for example, by implementing a child of the
Command class included in the package, and registering it with the manager. A command may contain actions (subcommands), command line parameters may be passed to it.
manage.py from flask.ext.script import Manager from flask.ext.migrate import Migrate, MigrateCommand from app import app, db from models import * migrate = Migrate(app, db)
Documentation:
flask-script.readthedocs.org/en/latestFlask-migrate
Allows you to configure the migration for ORM SQLAlchemy. The package provides the MigrateCommand class, which can be used in conjunction with the above-described Flask-Script extension. To use migrations, you need to connect a command (example above), perform initial initialization,
run manage.py db init , then use the migrate, upgrade, and downgrade actions of this command to manage migrations. It is worth noting that the list of actions for the team and their brief description can be obtained by running
manage.py db help .
Documentation:
flask-migrate.readthedocs.org/en/latestFlask-wtf
Implements binding to WTForms - a great library for working with forms. Again, there is an analogy with Django. In the box: a solid set of classes of fields and validators for them, inheritance, nested forms, and more.
forms.py from flask_wtf import Form from wtforms import StringField, PasswordField, TextAreaField, SelectField from wtforms.validators import Email, DataRequired, EqualTo class LoginForm(Form): email = StringField('E-mail', validators=[Email(), DataRequired()]) password = PasswordField('', validators=[DataRequired()]) class RegistrationForm(LoginForm): password_repeat = PasswordField(' ', validators=[DataRequired(), EqualTo('password')])
There is also a wtforms-alchemy extension for creating forms based on SQLAlchemy models. I stumbled upon it quite recently, therefore there is no work experience yet. However, I think, the analogy with Django is applicable here.
Documentation:
flask-wtf.readthedocs.org/en/latestFlask-Login
Adds basic support for authorization and user sessions. Connecting this extension requires a lot of actions, so I will try to be as concise as possible and skip the implementation of user logins and logouts.
Documentation:
flask-login.readthedocs.org/en/latestFlask-bcrypt
Adds functionality for hashing and checking passwords.
models.py from flask.ext.bcrypt import generate_password_hash, check_password_hash class User(db.Model): ... def check_password(self, password): return check_password_hash(self.password, password) @staticmethod def hash_password(password): return generate_password_hash(password)
Flask-assets
Flask is friends with the webassets library, allowing you to work with project resources incredibly elegantly. It knows how to combine resources into packages, compile scss (sass) and less, minify js and css and conveniently connect them in templates.
By specifying the
filters parameter in the package (Bundle), we will force the package files to pass through the specified filter (s). In our case, files are minified and merged into one. Some filters will require the installation of additional python-modules.
If the parameter ASSETS_DEBUG = True is set in the configuration, then the package files will not be passed through the filters and glued together, and a separate url will be generated for each file in the template.
PS With a sufficiently large number of resources, you should take out the functionality for forming packages (Bundle) and register them in a separate file - for example, assets.py.
Documentation:
flask-assets.readthedocs.org/en/latestFlask-debugtoolbar
What development will do without a convenient debugger? The extension adds a debug-panel ported from Django, with comprehensive information about the request. The panel is displayed when the parameter DEBUG = True is set in the configuration.
Documentation:
flask-debugtoolbar.readthedocs.org/en/latestInstead of conclusion
The article presents the extensions that I used to use in my projects, but this is not a complete list of what already exists for Flask. A more comprehensive list of current extensions is presented on the framework's official website by the link
flask.pocoo.org/extensions .
Additions
The user
danSamara pointed to the skeleton project of the application on Flask, which included many of the extensions described, as well as caching of Flask-Cache, the theme on bootstrap3, and the skeleton itself is designed as a python package and uses blueprints. Very useful thing. ;-)