• en
  • Language: ru
  • Documentation version: 1.1.x

Быстрый старт

Не терпится начать? На этой странице дается хорошее введение в Flask. Предполагается, что у вас уже установлен Flask. Если нет, перейдите в раздел Установка.

Минимальное применение

Минимальное приложение Flask выглядит примерно так:

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello_world():
    return 'Hello, World!'

Так что же сделал этот код?

  1. Сначала мы импортировали класс Flask. Экземпляр этого класса будет нашим WSGI-приложением.

  2. Далее мы создаем экземпляр этого класса. Первый аргумент - это имя модуля или пакета приложения. Если вы используете один модуль (как в этом примере), то вам следует использовать __name__, поскольку в зависимости от того, запущен ли он как приложение или импортирован как модуль, имя будет отличаться ('__main__' от фактического имени импорта). Это необходимо для того, чтобы Flask знал, где искать шаблоны, статические файлы и так далее. Для получения дополнительной информации ознакомьтесь с документацией Flask.

  3. Затем мы используем декоратор route(), чтобы сообщить Flask, какой URL должен вызвать нашу функцию.

  4. Функции присваивается имя, которое также используется для генерации URL для этой конкретной функции, и возвращается сообщение, которое мы хотим отобразить в браузере пользователя.

Просто сохраните его как hello.py или что-то подобное. Убедитесь, что вы не называете свое приложение flask.py, потому что это будет конфликтовать с самой Flask.

Для запуска приложения вы можете использовать либо команду flask, либо переключатель python -m с Flask. Перед этим вам нужно указать терминалу, с каким приложением работать, экспортировав переменную окружения FLASK_APP:

$ export FLASK_APP=hello.py
$ flask run
 * Running on http://127.0.0.1:5000/

Если вы работаете в Windows, синтаксис переменной среды зависит от интерпретатора командной строки. В командной строке:

C:\path\to\app>set FLASK_APP=hello.py

И в PowerShell:

PS C:\path\to\app> $env:FLASK_APP = "hello.py"

В качестве альтернативы можно использовать python -m flask:

$ export FLASK_APP=hello.py
$ python -m flask run
 * Running on http://127.0.0.1:5000/

Это запускает очень простой встроенный сервер, который достаточно хорош для тестирования, но, вероятно, это не то, что вы хотите использовать в производстве. Параметры развертывания см. в разделе Варианты развертывания.

Теперь перейдите на http://127.0.0.1:5000/, и вы увидите приветствие hello world.

Внешне видимый сервер

Если вы запустите сервер, вы заметите, что сервер доступен только с вашего собственного компьютера, а не с любого другого в сети. Это значение является стандартным, поскольку в режиме отладки пользователь приложения может выполнить произвольный код Python на вашем компьютере.

Если у вас отключен отладчик или вы доверяете пользователям в вашей сети, вы можете сделать сервер общедоступным, просто добавив --host=0.0.0.0 в командную строку:

$ flask run --host=0.0.0.0

Это указывает вашей операционной системе прослушивать все публичные IP-адреса.

Что делать, если сервер не запускается

В случае если python -m flask не работает или flask не существует, существует несколько причин, по которым это может произойти. Прежде всего, необходимо посмотреть на сообщение об ошибке.

Старая версия Flask

В версиях Flask старше 0.11 использовались разные способы запуска приложения. Короче говоря, команды flask не существовало, как и python -m flask. В этом случае у вас есть два варианта: либо перейти на более новые версии Flask, либо заглянуть в документацию Сервер разработки, чтобы ознакомиться с альтернативным методом запуска сервера.

Недопустимое имя импорта

Переменная окружения FLASK_APP - это имя модуля, который нужно импортировать в flask run. Если модуль назван неверно, при запуске (или если включена отладка при переходе к приложению) вы получите ошибку импорта. В нем будет указано, что именно пытались импортировать и почему это не удалось.

Наиболее распространенной причиной является опечатка или то, что вы на самом деле не создали объект app.

Режим отладки

(Хотите просто регистрировать ошибки и трассировку стека? Смотрите Ошибки приложения)

Сценарий flask хорошо подходит для запуска локального сервера разработки, но вам придется перезапускать его вручную после каждого изменения вашего кода. Это не очень хорошо, и Flask может сделать лучше. Если вы включите поддержку отладки, сервер будет перезагружаться при изменении кода, а также предоставит вам полезный отладчик, если что-то пойдет не так.

Чтобы включить все функции разработки (включая режим отладки), вы можете экспортировать переменную окружения FLASK_ENV и установить ее в значение development перед запуском сервера:

$ export FLASK_ENV=development
$ flask run

(В Windows нужно использовать set вместо export).

При этом выполняются следующие действия:

  1. активирует отладчик

  2. активирует автоматическую перезарядку

  3. включает режим отладки в приложении Flask.

Вы также можете управлять режимом отладки отдельно от среды, экспортируя FLASK_DEBUG=1.

Существует больше параметров, которые объясняются в документации Сервер разработки.

Внимание

Несмотря на то, что интерактивный отладчик не работает в средах форков (что делает его практически невозможным для использования на производственных серверах), он все еще позволяет выполнять произвольный код. Это делает его серьезным риском для безопасности, и поэтому он никогда не должен использоваться на производственных машинах.

Снимок экрана отладчика в действии:

screenshot of debugger in action

Более подробную информацию об использовании отладчика можно найти в разделе Werkzeug documentation.

У вас на примете другой отладчик? Смотрите Работа с отладчиками.

Маршрутизация

Современные веб-приложения используют осмысленные URL-адреса, чтобы помочь пользователям. Пользователи с большей вероятностью полюбят страницу и вернутся, если на странице используется осмысленный URL, который они могут запомнить и использовать для прямого посещения страницы.

Используйте декоратор route() для привязки функции к URL.

@app.route('/')
def index():
    return 'Index Page'

@app.route('/hello')
def hello():
    return 'Hello, World'

Вы можете сделать больше! Вы можете сделать части URL динамическими и прикрепить несколько правил к одной функции.

Переменные правила

Вы можете добавить переменные секции в URL, пометив секции символом <variable_name>. Затем ваша функция получает <variable_name> в качестве аргумента ключевое слово. По желанию вы можете использовать конвертер для указания типа аргумента, например <converter:variable_name>.

from markupsafe import escape

@app.route('/user/<username>')
def show_user_profile(username):
    # show the user profile for that user
    return 'User %s' % escape(username)

@app.route('/post/<int:post_id>')
def show_post(post_id):
    # show the post with the given id, the id is an integer
    return 'Post %d' % post_id

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return 'Subpath %s' % escape(subpath)

Типы преобразователей:

string

(по умолчанию) принимает любой текст без косой черты

int

принимает целые положительные числа

float

принимает положительные значения с плавающей точкой

path

как string, но также принимает косые черты

uuid

принимает строки UUID

Уникальные URL / Поведение при перенаправлении

Следующие два правила отличаются использованием косой черты.

@app.route('/projects/')
def projects():
    return 'The project page'

@app.route('/about')
def about():
    return 'The about page'

Канонический URL для конечной точки projects имеет косую черту. Это похоже на папку в файловой системе. Если вы обращаетесь к URL без косой черты, Flask перенаправляет вас на канонический URL с косой чертой.

Канонический URL для конечной точки about не содержит косой черты. Это похоже на имя пути к файлу. При доступе к URL с косой чертой выдается ошибка 404 «Не найдено». Это помогает сохранить уникальность URL-адресов для этих ресурсов, что помогает поисковым системам избежать индексации одной и той же страницы дважды.

Построение URL-адресов

Чтобы построить URL-адрес к определенной функции, используйте функцию url_for(). Она принимает имя функции в качестве первого аргумента и любое количество аргументов-ключей, каждый из которых соответствует переменной части правила URL. Неизвестные переменные части добавляются к URL в качестве параметров запроса.

Почему вы хотите создавать URL с помощью функции обратного преобразования URL url_for() вместо того, чтобы жестко кодировать их в своих шаблонах?

  1. Реверсирование часто является более описательным, чем жесткое кодирование URL-адресов.

  2. Вы можете изменить свои URL за один раз вместо того, чтобы помнить о необходимости вручную изменять жестко закодированные URL.

  3. Построение URL-адресов прозрачно обрабатывает экранирование специальных символов и данных Unicode.

  4. Сгенерированные пути всегда абсолютны, что позволяет избежать неожиданного поведения относительных путей в браузерах.

  5. Если ваше приложение размещено вне корня URL, например, в /myapplication вместо /, url_for() правильно обработает это для вас.

Например, здесь мы используем метод test_request_context(), чтобы опробовать url_for(). test_request_context() указывает Flask вести себя так, как будто он обрабатывает запрос, даже если мы используем оболочку Python. См. Контекст Местные жители.

from flask import Flask, url_for
from markupsafe import escape

app = Flask(__name__)

@app.route('/')
def index():
    return 'index'

@app.route('/login')
def login():
    return 'login'

@app.route('/user/<username>')
def profile(username):
    return '{}\'s profile'.format(escape(username))

with app.test_request_context():
    print(url_for('index'))
    print(url_for('login'))
    print(url_for('login', next='/'))
    print(url_for('profile', username='John Doe'))
/
/login
/login?next=/
/user/John%20Doe

Методы HTTP

Веб-приложения используют различные методы HTTP при доступе к URL-адресам. В процессе работы с Flask вам следует ознакомиться с методами HTTP. По умолчанию маршрут отвечает только на запросы GET. Вы можете использовать аргумент methods декоратора route() для обработки различных методов HTTP.

from flask import request

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        return do_the_login()
    else:
        return show_the_login_form()

Если присутствует GET, Flask автоматически добавляет поддержку метода HEAD и обрабатывает запросы HEAD в соответствии с HTTP RFC. Аналогично, OPTIONS автоматически реализуется для вас.

Статические файлы

Динамические веб-приложения также нуждаются в статических файлах. Обычно это файлы CSS и JavaScript. В идеале ваш веб-сервер настроен на то, чтобы обслуживать их за вас, но во время разработки Flask может сделать и это. Просто создайте папку с названием static в вашем пакете или рядом с вашим модулем, и она будет доступна по адресу /static в приложении.

Чтобы сгенерировать URL для статических файлов, используйте специальное имя конечной точки 'static':

url_for('static', filename='style.css')

Файл должен храниться в файловой системе как static/style.css.

Шаблоны рендеринга

Генерировать HTML из Python не очень весело, и на самом деле довольно громоздко, потому что вам придется самостоятельно выполнять экранирование HTML для обеспечения безопасности приложения. Поэтому Flask автоматически настраивает шаблонизатор Jinja2 для вас.

Для рендеринга шаблона вы можете использовать метод render_template(). Все, что вам нужно сделать, это указать имя шаблона и переменные, которые вы хотите передать шаблонизатору в качестве аргументов ключевых слов. Вот простой пример того, как вывести шаблон:

from flask import render_template

@app.route('/hello/')
@app.route('/hello/<name>')
def hello(name=None):
    return render_template('hello.html', name=name)

Flask будет искать шаблоны в папке templates. Таким образом, если ваше приложение является модулем, эта папка находится рядом с модулем, если это пакет, то она находится внутри вашего пакета:

случай 1: модуль:

/application.py
/templates
    /hello.html

Случай 2: пакет:

/application
    /__init__.py
    /templates
        /hello.html

Для шаблонов вы можете использовать всю мощь шаблонов Jinja2. Перейдите на официальный сайт Jinja2 Template Documentation для получения дополнительной информации.

Вот примерный шаблон:

<!doctype html>
<title>Hello from Flask</title>
{% if name %}
  <h1>Hello {{ name }}!</h1>
{% else %}
  <h1>Hello, World!</h1>
{% endif %}

Внутри шаблонов вы также имеете доступ к объектам request, session и g 1, а также к функции get_flashed_messages().

Шаблоны особенно полезны, если используется наследование. Если вы хотите узнать, как это работает, обратитесь к документации по шаблону Наследование шаблонов. В основном наследование шаблонов позволяет сохранить определенные элементы на каждой странице (например, заголовок, навигацию и нижний колонтитул).

Автоматическое экранирование включено, поэтому если name содержит HTML, он будет экранирован автоматически. Если вы можете доверять переменной и знаете, что это будет безопасный HTML (например, потому что она пришла из модуля, который преобразует вики-разметку в HTML), вы можете пометить ее как безопасную с помощью класса Markup или с помощью фильтра |safe в шаблоне. За примерами обращайтесь к документации по Jinja 2.

Вот основное введение в то, как работает класс Markup:

>>> from markupsafe import Markup
>>> Markup('<strong>Hello %s!</strong>') % '<blink>hacker</blink>'
Markup(u'<strong>Hello &lt;blink&gt;hacker&lt;/blink&gt;!</strong>')
>>> Markup.escape('<blink>hacker</blink>')
Markup(u'&lt;blink&gt;hacker&lt;/blink&gt;')
>>> Markup('<em>Marked up</em> &raquo; HTML').striptags()
u'Marked up \xbb HTML'

Изменено в версии 0.5: Автозамена больше не включена для всех шаблонов. Следующие расширения для шаблонов включают автозавершение: .html, .htm, .xml, .xhtml. Шаблоны, загруженные из строки, будут иметь отключенную функцию автозамены.

1

Не знаете, что это за объект g? Это что-то, в чем вы можете хранить информацию для своих нужд, проверьте документацию этого объекта (g) и Использование SQLite 3 с Flask для получения дополнительной информации.

Доступ к данным запроса

Для веб-приложений очень важно реагировать на данные, которые клиент отправляет на сервер. Во Flask эту информацию предоставляет глобальный объект request. Если у вас есть некоторый опыт работы с Python, вы можете задаться вопросом, как этот объект может быть глобальным и как Flask удается сохранить потокобезопасность. Ответ - контекстные локали:

Контекст Местные жители

Инсайдерская информация

Если вы хотите понять, как это работает и как можно реализовать тесты с контекстными локалями, прочитайте этот раздел, в противном случае просто пропустите его.

Некоторые объекты во Flask являются глобальными объектами, но не обычного типа. Эти объекты на самом деле являются прокси-объектами объектов, локальных для определенного контекста. Как многозначительно. Но на самом деле это довольно легко понять.

Представьте, что контекст - это поток обработки. Поступает запрос, и веб-сервер решает породить новый поток (или что-то другое, базовый объект способен работать с параллельными системами, отличными от потоков). Когда Flask начинает свою внутреннюю обработку запросов, он определяет, что текущий поток является активным контекстом, и привязывает текущее приложение и окружение WSGI к этому контексту (потоку). Это делается разумным образом, чтобы одно приложение могло вызывать другое приложение без сбоев.

Итак, что это значит для вас? В принципе, вы можете полностью игнорировать этот факт, если только вы не занимаетесь чем-то вроде модульного тестирования. Вы заметите, что код, который зависит от объекта запроса, внезапно сломается, потому что объекта запроса нет. Решением является создание объекта запроса самостоятельно и привязка его к контексту. Самым простым решением для модульного тестирования является использование менеджера контекста test_request_context(). В сочетании с оператором with он свяжет тестовый запрос так, что вы сможете взаимодействовать с ним. Вот пример:

from flask import request

with app.test_request_context('/hello', method='POST'):
    # now you can do something with the request until the
    # end of the with block, such as basic assertions:
    assert request.path == '/hello'
    assert request.method == 'POST'

Другой возможностью является передача всего окружения WSGI в метод request_context():

from flask import request

with app.request_context(environ):
    assert request.method == 'POST'

Объект запроса

Объект запроса документирован в разделе API, и мы не будем подробно рассматривать его здесь (см. Request). Здесь приведен общий обзор некоторых наиболее часто встречающихся операций. Прежде всего, вы должны импортировать его из модуля flask:

from flask import request

Текущий метод запроса доступен с помощью атрибута method. Для доступа к данным формы (данные, переданные в запросе POST или PUT) можно использовать атрибут form. Вот полный пример использования двух вышеупомянутых атрибутов:

@app.route('/login', methods=['POST', 'GET'])
def login():
    error = None
    if request.method == 'POST':
        if valid_login(request.form['username'],
                       request.form['password']):
            return log_the_user_in(request.form['username'])
        else:
            error = 'Invalid username/password'
    # the code below is executed if the request method
    # was GET or the credentials were invalid
    return render_template('login.html', error=error)

Что произойдет, если ключ не существует в атрибуте form? В этом случае возникает специальная ошибка KeyError. Вы можете поймать его как обычный KeyError, но если вы этого не сделаете, то вместо него будет показана страница ошибки HTTP 400 Bad Request. Поэтому во многих ситуациях вам не придется решать эту проблему.

Для доступа к параметрам, представленным в URL (?key=value), можно использовать атрибут args:

searchword = request.args.get('key', '')

Мы рекомендуем получать доступ к параметрам URL с помощью get или путем перехвата KeyError, поскольку пользователи могут изменить URL, и в этом случае выдавать им страницу с ошибкой запроса 400 не очень удобно для пользователя.

Полный список методов и атрибутов объекта запроса можно найти в документации Request.

Загрузка файлов

Вы можете легко работать с загруженными файлами с помощью Flask. Только не забудьте установить атрибут enctype="multipart/form-data" на вашей HTML-форме, иначе браузер вообще не будет передавать ваши файлы.

Загруженные файлы хранятся в памяти или во временном месте в файловой системе. Вы можете получить доступ к этим файлам, просмотрев атрибут files на объекте запроса. Каждый загруженный файл хранится в этом словаре. Он ведет себя так же, как стандартный объект Python file, но у него также есть метод save(), который позволяет сохранить этот файл в файловой системе сервера. Вот простой пример, показывающий, как это работает:

from flask import request

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['the_file']
        f.save('/var/www/uploads/uploaded_file.txt')
    ...

Если вы хотите узнать, как файл был назван на клиенте до того, как он был загружен в ваше приложение, вы можете обратиться к атрибуту filename. Однако имейте в виду, что это значение может быть подделано, поэтому никогда не доверяйте ему. Если вы хотите использовать имя файла на клиенте для хранения файла на сервере, передайте его через функцию secure_filename(), которую Werkzeug предоставляет для вас:

from flask import request
from werkzeug.utils import secure_filename

@app.route('/upload', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        f = request.files['the_file']
        f.save('/var/www/uploads/' + secure_filename(f.filename))
    ...

Для более наглядных примеров посмотрите шаблон Загрузка файлов.

Cookies

Для доступа к cookies можно использовать атрибут cookies. Для установки cookies можно использовать метод set_cookie объектов ответа. Атрибут cookies объектов запроса представляет собой словарь со всеми cookies, передаваемыми клиентом. Если вы хотите использовать сессии, не используйте непосредственно cookies, а воспользуйтесь Сессии во Flask, которые добавляют некоторую безопасность поверх cookies для вас.

Чтение печенья:

from flask import request

@app.route('/')
def index():
    username = request.cookies.get('username')
    # use cookies.get(key) instead of cookies[key] to not get a
    # KeyError if the cookie is missing.

Хранение печенья:

from flask import make_response

@app.route('/')
def index():
    resp = make_response(render_template(...))
    resp.set_cookie('username', 'the username')
    return resp

Обратите внимание, что cookies устанавливаются на объекты ответа. Поскольку вы обычно просто возвращаете строки из функций представления, Flask преобразует их в объекты ответа. Если вы явно хотите сделать это, вы можете использовать функцию make_response() и затем изменить ее.

Иногда вы можете захотеть установить cookie в точке, где объект ответа еще не существует. Это возможно с помощью шаблона Обратные вызовы отложенных запросов.

Об этом также смотрите Об ответах.

Перенаправления и ошибки

Чтобы перенаправить пользователя на другую конечную точку, используйте функцию redirect(); чтобы прервать запрос раньше времени с кодом ошибки, используйте функцию abort():

from flask import abort, redirect, url_for

@app.route('/')
def index():
    return redirect(url_for('login'))

@app.route('/login')
def login():
    abort(401)
    this_is_never_executed()

Это довольно бессмысленный пример, потому что пользователь будет перенаправлен из индекса на страницу, к которой он не может получить доступ (401 означает отказ в доступе), но он показывает, как это работает.

По умолчанию для каждого кода ошибки отображается черно-белая страница ошибки. Если вы хотите настроить страницу ошибки, вы можете использовать декоратор errorhandler():

from flask import render_template

@app.errorhandler(404)
def page_not_found(error):
    return render_template('page_not_found.html'), 404

Обратите внимание на 404 после вызова render_template(). Это сообщает Flask, что код состояния этой страницы должен быть 404, что означает «не найдено». По умолчанию предполагается 200, что переводится как: все прошло хорошо.

Более подробную информацию см. в разделе Обработчики ошибок.

Об ответах

Возвращаемое значение из функции представления автоматически преобразуется в объект ответа. Если возвращаемое значение является строкой, оно преобразуется в объект ответа со строкой в качестве тела ответа, кодом состояния 200 OK и миметипом text/html. Если возвращаемое значение является диктой, то для создания ответа вызывается jsonify(). Логика, которую применяет Flask для преобразования возвращаемых значений в объекты ответа, выглядит следующим образом:

  1. Если возвращается объект ответа правильного типа, он возвращается непосредственно из представления.

  2. Если это строка, то создается объект ответа с этими данными и параметрами по умолчанию.

  3. Если это dict, то объект ответа создается с помощью jsonify.

  4. Если возвращается кортеж, элементы в кортеже могут предоставлять дополнительную информацию. Такие кортежи должны быть в форме (response, status), (response, headers) или (response, status, headers). Значение status будет переопределять код статуса, а headers может быть списком или словарем дополнительных значений заголовков.

  5. Если ничего из этого не работает, Flask примет возвращаемое значение за действительное приложение WSGI и преобразует его в объект ответа.

Если вы хотите получить результирующий объект ответа внутри представления, вы можете использовать функцию make_response().

Представьте, что у вас такой вид:

@app.errorhandler(404)
def not_found(error):
    return render_template('error.html'), 404

Вам просто нужно обернуть выражение return выражением make_response() и получить объект ответа, чтобы изменить его, а затем вернуть его:

@app.errorhandler(404)
def not_found(error):
    resp = make_response(render_template('error.html'), 404)
    resp.headers['X-Something'] = 'A value'
    return resp

API с JSON

Распространенным форматом ответа при написании API является JSON. Начать писать такой API с помощью Flask очень просто. Если вы возвращаете dict из представления, он будет преобразован в ответ JSON.

@app.route("/me")
def me_api():
    user = get_current_user()
    return {
        "username": user.username,
        "theme": user.theme,
        "image": url_for("user_image", filename=user.image),
    }

В зависимости от дизайна вашего API, вы можете захотеть создавать ответы JSON для типов, отличных от dict. В этом случае используйте функцию jsonify(), которая сериализует любой поддерживаемый тип данных JSON. Или обратитесь к расширениям сообщества Flask, которые поддерживают более сложные приложения.

@app.route("/users")
def users_api():
    users = get_all_users()
    return jsonify([user.to_json() for user in users])

Сессии

В дополнение к объекту запроса существует также второй объект session, который позволяет хранить информацию, специфичную для пользователя, от одного запроса к другому. Это реализовано поверх cookies и подписывает cookies криптографически. Это означает, что пользователь может посмотреть содержимое вашего cookie, но не сможет его изменить, если только не знает секретный ключ, используемый для подписи.

Для использования сеансов необходимо установить секретный ключ. Вот как работают сеансы:

from flask import Flask, session, redirect, url_for, request
from markupsafe import escape

app = Flask(__name__)

# Set the secret key to some random bytes. Keep this really secret!
app.secret_key = b'_5#y2L"F4Q8z\n\xec]/'

@app.route('/')
def index():
    if 'username' in session:
        return 'Logged in as %s' % escape(session['username'])
    return 'You are not logged in'

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        session['username'] = request.form['username']
        return redirect(url_for('index'))
    return '''
        <form method="post">
            <p><input type=text name=username>
            <p><input type=submit value=Login>
        </form>
    '''

@app.route('/logout')
def logout():
    # remove the username from the session if it's there
    session.pop('username', None)
    return redirect(url_for('index'))

Упомянутый здесь escape() делает экранирование за вас, если вы не используете шаблонизатор (как в этом примере).

Как генерировать хорошие секретные ключи

Секретный ключ должен быть настолько случайным, насколько это возможно. В вашей операционной системе есть способы генерации довольно случайных данных на основе криптографического генератора случайных чисел. Используйте следующую команду для быстрой генерации значения для Flask.secret_key (или SECRET_KEY):

$ python -c 'import os; print(os.urandom(16))'
b'_5#y2L"F4Q8z\n\xec]/'

Замечание о сеансах на основе куки: Flask берет значения, которые вы помещаете в объект сессии, и сериализует их в cookie. Если вы обнаружили, что некоторые значения не сохраняются при разных запросах, куки действительно включены, и вы не получаете четкого сообщения об ошибке, проверьте размер куки в ответах страницы по сравнению с размером, поддерживаемым веб-браузерами.

Помимо стандартных сессий на стороне клиента, если вы хотите обрабатывать сессии на стороне сервера, есть несколько расширений Flask, которые поддерживают это.

Мигание сообщения

Хорошие приложения и пользовательские интерфейсы основаны на обратной связи. Если пользователь не получает достаточно обратной связи, он, скорее всего, в конечном итоге возненавидит приложение. Flask предоставляет действительно простой способ обратной связи с пользователем с помощью системы мигания. Система мигания в основном позволяет записать сообщение в конце запроса и получить доступ к нему при следующем (и только следующем) запросе. Обычно это сочетается с шаблоном макета для отображения сообщения.

Чтобы прошить сообщение, используйте метод flash(), чтобы получить сообщения, вы можете использовать get_flashed_messages(), который также доступен в шаблонах. Посмотрите Мигание сообщения для полного примера.

Ведение журнала

Добавлено в версии 0.3.

Иногда вы можете оказаться в ситуации, когда имеете дело с данными, которые должны быть правильными, но на самом деле таковыми не являются. Например, у вас может быть код на стороне клиента, который отправляет HTTP-запрос на сервер, но он, очевидно, неправильно сформирован. Это может быть вызвано вмешательством пользователя в данные или сбоем клиентского кода. В большинстве случаев в такой ситуации можно ответить 400 Bad Request, но иногда это не поможет, и код должен продолжать работать.

Вы можете захотеть зафиксировать, что произошло что-то подозрительное. Вот тут-то и пригодятся логгеры. Начиная с версии Flask 0.3 логгер уже настроен для использования.

Вот некоторые примеры вызовов журнала:

app.logger.debug('A value for debugging')
app.logger.warning('A warning occurred (%d apples)', 42)
app.logger.error('An error occurred')

Прилагаемый logger является стандартным протоколированием Logger, поэтому для получения дополнительной информации перейдите к официальной документации logging.

Читать далее Ошибки приложения.

Использование крючков в промежуточном ПО WSGI

Чтобы добавить промежуточное ПО WSGI в ваше приложение Flask, оберните атрибут приложения wsgi_app. Например, чтобы применить промежуточное ПО Werkzeug ProxyFix для работы за Nginx:

from werkzeug.middleware.proxy_fix import ProxyFix
app.wsgi_app = ProxyFix(app.wsgi_app)

Обертывание app.wsgi_app вместо app означает, что app по-прежнему указывает на ваше приложение Flask, а не на промежуточное ПО, поэтому вы можете продолжать использовать и настраивать app напрямую.

Использование расширений Flask

Расширения - это пакеты, которые помогают выполнять общие задачи. Например, Flask-SQLAlchemy обеспечивает поддержку SQLAlchemy, что делает его простым и удобным в использовании с Flask.

Подробнее о расширениях Flask читайте в Расширения.

Развертывание на веб-сервере

Готовы развернуть свое новое приложение Flask? Перейдите к Варианты развертывания.