Быстрый старт
Вы хотите начать работу? Эта страница предоставляет хорошее введение в Flask. Сначала выполните Установку, чтобы настроить проект и установить Flask.
Минимальное приложение
Минимальное приложение Flask выглядит примерно так:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def hello_world():
return "<p>Hello, World!</p>"
Что делает этот код?
- Сначала мы импортировали класс
Flask. Экземпляр этого класса будет нашим приложением WSGI. - Затем мы создаем экземпляр этого класса. Первым аргументом является имя модуля или пакета приложения.
__name__— удобное сокращение, подходящее для большинства случаев. Это необходимо, чтобы Flask знал, где искать ресурсы, такие как шаблоны и статические файлы. - Затем мы используем декоратор
route(), чтобы указать Flask, какой URL должен вызвать нашу функцию. - Функция возвращает сообщение, которое мы хотим отобразить в браузере пользователя. По умолчанию тип содержимого — 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 --debug run * 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-адресу, пометив их <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)}'
Типы преобразователей:
| (по умолчанию) принимает любой текст без косой черты |
| принимает положительные целые числа |
| принимает положительные значения с плавающей запятой |
| как |
| принимает строки 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(), а не жестко кодировать их в шаблонах?
- Обратное преобразование часто более описательно, чем жесткая кодировка URL-адресов.
- Вы можете изменить свои URL-адреса за один раз, вместо того, чтобы помнить о необходимости вручную изменять жестко закодированные URL-адреса.
- Создание URL-адресов обрабатывает экранирование специальных символов прозрачно.
- Сгенерированные пути всегда абсолютные, избегая непредсказуемого поведения относительных путей в браузерах.
- Если ваше приложение размещено вне корневого 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 в соответствии с HTTP RFC. Аналогично, 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 <blink>hacker</blink>!</strong>')
>>> Markup.escape('<blink>hacker</blink>')
Markup('<blink>hacker</blink>')
>>> Markup('<em>Marked up</em> » 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)}")
...
Для более подробных примеров см. Загрузка файлов.
Перенаправления и ошибки
Для перенаправления пользователя на другой конечный пункт используйте функцию 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 использует для преобразования значений возврата в объекты ответа, такова:
- Если возвращается объект ответа правильного типа, он возвращается напрямую из представления.
- Если это строка, создается объект ответа с этими данными и параметрами по умолчанию.
- Если это итератор или генератор, возвращающий строки или байты, он обрабатывается как ответ потокового типа.
- Если это словарь или список, объект ответа создается с помощью
jsonify(). - Если возвращается кортеж, элементы кортежа могут предоставлять дополнительную информацию. Такие кортежи должны иметь вид
(response, status),(response, headers), или(response, status, headers). Значениеstatusпереопределит код состояния, аheadersможет быть списком или словарем дополнительных значений заголовков. - Если ничто из вышеперечисленного не подходит, 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, но не может его изменить, если ему неизвестен секретный ключ для шифрования.
Для использования сессий необходимо задать секретный ключ. Вот как работают сессии:
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 приложения. Например, чтобы применить средство 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.2.x/quickstart/