Быстрый старт
Желаете приступить к работе? Эта страница предоставляет хорошее введение в 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 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, пометив части <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', person=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 person %}
<h1>Hello {{ person }}!</h1>
{% else %}
<h1>Hello, World!</h1>
{% endif %}
Внутри шаблонов также есть доступ к объектам config, request, session и g [1], а также к функциям url_for() и get_flashed_messages().
Шаблоны особенно полезны при использовании наследования. Если вы хотите узнать, как это работает, обратитесь к Наследованию шаблонов. В основном наследование шаблонов позволяет сохранять определенные элементы на каждой странице (такие как заголовок, навигация и подвал).
Автоматическое экранирование включено, поэтому если person содержит HTML, он будет автоматически экранирован. Если вы можете доверять переменной и знаете, что она будет безопасным HTML (например, потому что она пришла из модуля, который преобразует разметку вики в 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. Для шаблонов, загруженных из строки, автоматическое экранирование отключено.
Получение данных запроса
Для веб-приложений крайне важно реагировать на данные, которые клиент отправляет серверу. В 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, который позволяет хранить информацию, специфичную для пользователя, от одного запроса к следующему. Он реализован на основе куки и шифруется криптографически. Это означает, что пользователь может просмотреть содержимое вашего куки, но не может его изменить, если он не знает секретный ключ, используемый для шифрования.
Для использования сессий необходимо установить секретный ключ. Вот как работают сессии:
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? См. Развёртывание в продакшен.
© 2010 Pallets
Licensed under the BSD 3-clause License.
https://flask.palletsprojects.com/en/stable/quickstart/