Spec-Zone.ru › Flask 2.3

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

Желаете начать работу сразу? Эта страница предоставляет хорошее введение в 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.

$ flask --app hello run
 * Serving Flask app 'hello'
 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)

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

В качестве сокращения, если файл называется app.py или wsgi.py, вам не нужно использовать --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-адреса.

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

Команда flask run может делать больше, чем просто запускать сервер разработки. Включив режим отладки, сервер будет автоматически перезагружаться при изменении кода и покажет интерактивный отладчик в браузере, если во время запроса произойдёт ошибка.

Интерактивный отладчик в действии.

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

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

Чтобы включить режим отладки, используйте параметр --debug.

$ flask --app hello run --debug
 * Serving Flask app 'hello'
 * Debug mode: on
 * Running on http://127.0.0.1:5000 (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: nnn-nnn-nnn

См. также:

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

Экранирование 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 и передает его функции представления. Эти правила переменных описаны ниже.

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

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

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

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

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

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

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

Вы можете добавить переменные в 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()

В приведённом выше примере все методы для маршрута находятся в одной функции, что может быть полезно, если каждая часть использует общие данные.

Вы также можете разделить представления для различных методов на разные функции. Flask предоставляет сокращения для декорирования таких маршрутов с помощью get(), post() и т.д. для каждого распространённого HTTP-метода.

@app.get('/login')
def login_get():
    return show_the_login_form()

@app.post('/login')
def login_post():
    return do_the_login()

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

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

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

Для генерации URL статических файлов используйте специальное имя конечной точки 'static'.

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

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

Рендеринг шаблонов

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

Шаблоны могут использоваться для генерации любых типов текстовых файлов. Для веб-приложений вы в первую очередь будете генерировать HTML-страницы, но вы также можете генерировать Markdown, простой текст для электронных писем и все остальное.

Для справки по HTML, CSS и другим веб-API используйте MDN Web Docs.

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

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

О ответах

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

  1. Если возвращается объект ответа правильного типа, он возвращается напрямую из представления.
  2. Если это строка, создается объект ответа с этими данными и параметрами по умолчанию.
  3. Если это итератор или генератор, возвращающий строки или байты, он обрабатывается как ответ потокового типа.
  4. Если это словарь или список, создается объект ответа с помощью jsonify().
  5. Если возвращается кортеж, элементы кортежа могут предоставить дополнительную информацию. Такие кортежи должны быть в формате (response, status), (response, headers), или (response, status, headers). Значение status переопределит код состояния, а headers может быть списком или словарем дополнительных значений заголовков.
  6. Если ничто из вышеперечисленного не работает, 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 или list из представления, он будет преобразован в ответ 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),
    }

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

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

Для сложных типов, таких как модели базы данных, вам следует использовать библиотеку сериализации, чтобы сначала преобразовать данные в допустимые типы JSON. Существует множество библиотек сериализации и расширений API Flask, поддерживаемых сообществом, которые поддерживают более сложные приложения.

Сессии

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

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

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'

Заметка о сессиях на основе cookie: Flask возьмет значения, которые вы поместите в объект сессии, и сериализует их в cookie. Если вы обнаружите, что некоторые значения не сохраняются между запросами, cookie действительно включены, и вы не получаете ясного сообщения об ошибке, проверьте размер 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. Например, чтобы применить средство proxy_fix Werkzeug для работы за 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.3.x/quickstart/

Spec-Zone.ru

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