Spec-Zone.ru › Flask 2.1

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

Желаете начать работу? Эта страница предоставляет хорошее введение в Flask. Сначала выполните Установку, чтобы настроить проект и установить Flask.

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

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

from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello_world():
    return "<p>Hello, World!</p>"

Что делает этот код?

  1. Сначала мы импортировали класс Flask. Экземпляр этого класса будет нашим WSGI-приложением.
  2. Затем мы создаем экземпляр этого класса. Первым аргументом является имя модуля или пакета приложения. __name__ — удобное сокращение, подходящее для большинства случаев. Это необходимо, чтобы Flask знал, где искать ресурсы, такие как шаблоны и статические файлы.
  3. Затем мы используем декоратор route(), чтобы указать Flask, какой URL должен вызывать нашу функцию.
  4. Функция возвращает сообщение, которое мы хотим отобразить в браузере пользователя. По умолчанию тип содержимого — HTML, поэтому HTML в строке будет отображен браузером.

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

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

$ export FLASK_APP=hello
$ flask run
 * Running on http://127.0.0.1:5000/
$ set -x FLASK_APP hello
$ flask run
 * Running on http://127.0.0.1:5000/
> set FLASK_APP=hello
> flask run
 * Running on http://127.0.0.1:5000/
> $env:FLASK_APP = "hello"
> flask run
 * Running on http://127.0.0.1:5000/

Поведение обнаружения приложения

В качестве сокращения, если файл называется app.py или wsgi.py, вам не нужно устанавливать переменную среды FLASK_APP. Подробнее см. в разделе Интерфейс командной строки.

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

Теперь перейдите по адресу http://127.0.0.1:5000/, и вы увидите приветствие «Hello world».

Если другая программа уже использует порт 5000, вы увидите OSError: [Errno 98] или OSError: [WinError 10013], когда сервер попытается запуститься. См. Адрес уже используется, чтобы узнать, как это обработать.

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

Если вы запустите сервер, вы заметите, что сервер доступен только с вашего компьютера, а не с любого другого в сети. Это значение по умолчанию, потому что в отладочном режиме пользователь приложения может выполнить произвольный код 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 run может сделать больше, чем просто запустить сервер разработки. Включив режим отладки, сервер будет автоматически перезагружаться при изменении кода и покажет интерактивный отладчик в браузере, если во время запроса произойдет ошибка.

The interactive debugger in action.

Предупреждение

Отладчик позволяет выполнять произвольный код Python из браузера. Он защищен пином, но всё равно представляет значительную угрозу безопасности. Не запускайте сервер разработки или отладчик в рабочей среде.

Чтобы включить все функции разработки, установите переменную среды FLASK_ENV в development перед вызовом flask run.

$ export FLASK_ENV=development
$ flask run
$ set -x FLASK_ENV development
$ flask run
> set FLASK_ENV=development
> flask run
> $env:FLASK_ENV = "development"
> flask run

См. также:

  • Сервер разработки и Интерфейс командной строки для получения информации о работе в режиме разработки.
  • Отладка ошибок приложения для получения информации об использовании встроенного отладчика и других отладчиков.
  • Ведение журналов и Обработка ошибок приложения для ведения журналов ошибок и отображения красивых страниц ошибок.

Обработка HTML-экранирования

При возвращении HTML (по умолчанию в Flask), любые предоставленные пользователем значения, отображаемые в выводе, должны быть экранированы для защиты от атак с внедрением кода. Шаблоны HTML, рендеренные с использованием Jinja, представленные позже, сделают это автоматически.

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

from markupsafe import escape

@app.route("/<name>")
def hello(name):
    return f"Hello, {escape(name)}!"

Если пользователь смог отправить имя <script>alert("bad")</script>, экранирование приведет к тому, что оно будет отображено как текст, а не к выполнению скрипта в браузере пользователя.

<name> в маршруте захватывает значение из URL и передает его в функцию представления. Эти правила переменных описаны ниже.

END_OF_DOCUMENT_MARKER ```

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

Современные веб-приложения используют осмысленные 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 f'User {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 f'Post {post_id}'

@app.route('/path/<path:subpath>')
def show_subpath(subpath):
    # show the subpath after /path/
    return f'Subpath {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-адресу без косой черты в конце (/projects), Flask перенаправляет вас на канонический URL-адрес с косой чертой в конце (/projects/).

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

Создание URL-адресов

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

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

  1. Обратное преобразование часто более описательно, чем жесткое кодирование URL-адресов.
  2. Вы можете изменить URL-адреса в один заход, вместо того, чтобы помнить о ручном изменении жестко закодированных URL-адресов.
  3. Создание URL-адресов обрабатывает экранирование специальных символов прозрачно.
  4. Сгенерированные пути всегда абсолютны, что предотвращает неожиданное поведение относительных путей в браузерах.
  5. Если ваше приложение расположено вне корневого URL-адреса, например, в /myapplication вместо /, url_for() правильно обрабатывает это за вас.

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

from flask import url_for

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

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

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

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-адресам. Вам следует ознакомиться с методами HTTP во время работы с Flask. По умолчанию маршрут отвечает только на запросы 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.

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

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

Внутри шаблонов вам также доступны объекты config, request, session и g 1, а также функции url_for() и 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('<strong>Hello &lt;blink&gt;hacker&lt;/blink&gt;!</strong>')
>>> Markup.escape('<blink>hacker</blink>')
Markup('&lt;blink&gt;hacker&lt;/blink&gt;')
>>> Markup('<em>Marked up</em> &raquo; HTML').striptags()
'Marked up » HTML'
Журнал изменений

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

1

Не знаете, что такое объект g? Это место, где вы можете хранить информацию для собственных нужд. Ознакомьтесь с документацией по flask.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():

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 bad request не очень удобно.

Полный список методов и атрибутов объекта запроса можно найти в документации 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 werkzeug.utils import secure_filename

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

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

Куки

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

Чтение куков:

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

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

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

Также см. Информация об ответах.

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

Для перенаправления пользователя на другой конечный пункт используйте функцию 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, что переводится как: всё прошло хорошо.

См. Обработка ошибок приложения для получения дополнительной информации.

END_OF_DOCUMENT_MARKER

О ответах

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

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

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

Представьте, что у вас есть представление такого вида:

from flask import render_template

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

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

from flask import 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, которые поддерживают более сложные приложения.

from flask import jsonify

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

Сессии

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

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

from flask import session

# 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 f'Logged in as {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'))

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

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

$ python -c 'import secrets; print(secrets.token_hex())'
'192b9bdd22ab9ed4d12e236c78afcb9a393ec15f71bbf5dc987d54727823bcbf'

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

Помимо сессий по умолчанию на клиентской стороне, если вы хотите обрабатывать сессии на серверной стороне, существуют несколько расширений 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? См. Варианты развертывания.

© 2007–2022 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/2.1.x/quickstart/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API