Сообщить об ошибке.

Как обслуживать статические файлы в Flask

Динамическим веб-приложениям также нужны статические файлы - это CSS и JavaScript файлы. Предпочтительным методом обслуживать статические файлы, является настройка и использование NGINX или другого веб-сервера на отдачу статики из определенной директории, так как они смогут сделать это более эффективно, чем Flask.

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

Подключение/обслуживания статики при помощи Flask.

В принципе Flask уже из коробки настроен на обслуживание статики из директории static. Во время разработки нужно создать папку с именем static в пакете с веб-приложением или рядом с приложением-модулем (приложение состоит из одного файла), и она будет доступна в приложении по URL /static.

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

В коде Python:

# в коде Python
url_for('static', filename='style.css')

В шаблонах Jinja2:

# в шаблонах Jinja2
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">

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

Переопределение папки хранения статически.

Для переопределения папки хранения статически и/или URL-пути отдачи статики необходимо использовать следующие аргументы класса flask.Flask:

  • static_url_path=None - может использоваться для указания другого URL-пути статических файлов в интернете. По умолчанию используется значение аргумента static_folder.
  • static_folder='static' - папка со статическими файлами, которая обслуживается по URL static_url_path. Может указываться относительно root_path приложения или как абсолютный путь. По умолчанию 'static'.

Что бы открывать статические файлы при помощи самого Flask, необходимо использовать метод flask.send_from_directory(), что может быть довольно удобно в некоторых ситуациях.

from flask import Flask, request, send_from_directory

# установим корневой каталог проекта в качестве
# статической папки (можно определить другой).
app = Flask(__name__, static_url_path='')

@app.route('/css/<path:path>')
def send_css(path):
    return send_from_directory('css', path)

if __name__ == "__main__":
    app.run()

В качестве альтернативы можно использовать flask.send_file() или app.send_static_file, но это крайне не рекомендуется, так как это может привести к угрозам безопасности с путями, предоставленными пользователем. Метод flask.send_from_directory был разработан для контроля этих рисков.

Переопределение URL-адреса статики на лету.

Смотрим реальный пример для отдачи файлов favicon.svg, robots.txt и sitemap.xml, которые лежат в директории static:

# функция, которая обрабатывает отдачу
# статики из корневой директории сайта
@app.route('/favicon.svg')
@app.route('/sitemap.xml')
@app.route('/robots.txt')
def static_root():
    return send_from_directory(app.static_folder, request.path[1:])

Файлы будут отдаваться от корня сайта (например https://docs-python.ru/favicon.svg и т.д.), хотя сами лежат в папке static