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

Так что это неловко. У меня есть приложение, которое я сбросил вместе в Flask и теперь он просто обслуживает одну статическую HTML-страницу с некоторыми ссылками на CSS и JS. И я не могу найти, где в документации Flask описывается возвращение статических файлов. Да, я мог бы использовать render_template но я знаю, что данные не temtatized. Я бы подумал, что send_file или url_for был прав, но я не мог заставить их работать. Тем временем я открываю файлы, читаю контент и настраиваю Response с соответствующим типом mimetype:

 import os.path from flask import Flask, Response app = Flask(__name__) app.config.from_object(__name__) def root_dir(): # pragma: no cover return os.path.abspath(os.path.dirname(__file__)) def get_file(filename): # pragma: no cover try: src = os.path.join(root_dir(), filename) # Figure out how flask returns static files # Tried: # - render_template # - send_file # This should not be so non-obvious return open(src).read() except IOError as exc: return str(exc) @app.route('/', methods=['GET']) def metrics(): # pragma: no cover content = get_file('jenkins_analytics.html') return Response(content, mimetype="text/html") @app.route('/', defaults={'path': ''}) @app.route('/<path:path>') def get_resource(path): # pragma: no cover mimetypes = { ".css": "text/css", ".html": "text/html", ".js": "application/javascript", } complete_path = os.path.join(root_dir(), path) ext = os.path.splitext(path)[1] mimetype = mimetypes.get(ext, "text/html") content = get_file(complete_path) return Response(content, mimetype=mimetype) if __name__ == '__main__': # pragma: no cover app.run(port=80) 

Кто-то хочет дать образец кода или URL-адрес для этого? Я знаю, что это будет очень просто.

  • Переключение между python 2.7 и python 3.5 в Mac OS X
  • Использование SimpleXMLTreeBuilder в elementtree
  • Python: Как использовать DictReader дважды?
  • минимальная куча в python
  • настройка предпочтений Chrome w / Selenium Webdriver в Python
  • Удалить последние N элементов списка
  • Получить содержимое таблицы в BeautifulSoup
  • Как читать / dev / random в python
  • 12 Solutions collect form web for “Как обслуживать статические файлы в Flask”

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

    Однако вы можете использовать send_from_directory для отправки файлов из каталога, что может быть довольно удобным в некоторых ситуациях:

     from flask import Flask, request, send_from_directory # set the project root directory as the static folder, you can set others. app = Flask(__name__, static_url_path='') @app.route('/js/<path:path>') def send_js(path): return send_from_directory('js', path) if __name__ == "__main__": app.run() 

    Не используйте send_file или send_static_file с send_static_file пользователем send_static_file .

    send_static_file :

     from flask import Flask, request # set the project root directory as the static folder, you can set others. app = Flask(__name__, static_url_path='') @app.route('/') def root(): return app.send_static_file('index.html') 

    Я уверен, что вы найдете то, что вам нужно: http://flask.pocoo.org/docs/quickstart/#static-files

    В основном вам просто нужна «статическая» папка в корне вашего пакета, а затем вы можете использовать url_for('static', filename='foo.bar') или напрямую ссылаться на ваши файлы с помощью http://example.com/ static / foo.bar .

    EDIT : Как было предложено в комментариях, вы можете напрямую использовать URL '/static/foo.bar' адрес '/static/foo.bar' но накладные расходы url_for() слишком низки, а его использование означает, что вы сможете легко настроить поведение (измените папку, измените URL-путь, переместите ваши статические файлы на S3 и т. д.).

    Вы также можете, и это мой любимый, установить папку как статический путь, чтобы файлы внутри были доступны для всех.

     app = Flask(__name__, static_url_path='/static') 

    С помощью этого набора вы можете использовать стандартный HTML:

     <link rel="stylesheet" type="text/css" href="/static/style.css"> 

    То, что я использую (и отлично работает), является каталогом «шаблонов» и «статическим» каталогом. Я размещаю все мои .html файлы / флеш-шаблоны внутри каталога шаблонов, а static содержит CSS / JS. render_template отлично работает для общих html-файлов, насколько мне известно, независимо от того, насколько вы использовали синтаксис шаблонов Flask. Ниже приведен пример вызова в файле views.py.

     @app.route('/projects') def projects(): return render_template("projects.html", title = 'Projects') 

    Просто убедитесь, что вы используете url_for (), когда хотите ссылаться на некоторый статический файл в отдельном статическом каталоге. Вероятно, вы в конечном итоге все это сделаете в своих ссылках на файлы CSS / JS в html. Например…

     <script src="{{ url_for('static', filename='styles/dist/js/bootstrap.js') }}"></script> 

    Вот ссылка на «каноническое» неофициальное учебное пособие по фляге – множество замечательных советов здесь, чтобы помочь вам попасть в землю.

    http://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world

    Вы можете использовать эту функцию:

    send_static_file (имя файла)
    Функция, используемая для отправки статических файлов из статической папки в браузер.

     app = Flask(__name__) @app.route('/<path:path>') def static_file(path): return app.send_static_file(path) 

    Простейший рабочий пример, основанный на других ответах, следующий:

     from flask import Flask, request app = Flask(__name__, static_url_path='') @app.route('/index/') def root(): return app.send_static_file('index.html') if __name__ == '__main__': app.run(debug=True) 

    С HTML называется index.html :

     <!DOCTYPE html> <html> <head> <title>Hello World!</title> </head> <body> <div> <p> This is a test. </p> </div> </body> </html> 

    ВАЖНО: И index.html находится в папке static , то есть <projectpath> имеет .py файл, а <projectpath>\static имеет html файл.

    Если вы хотите, чтобы сервер был видимым в сети, используйте app.run(debug=True, host='0.0.0.0')

    EDIT: для отображения всех файлов в папке, если требуется, используйте это

     @app.route('/<path:path>') def static_file(path): return app.send_static_file(path) 

    Это, по сути, BlackMamba , поэтому дайте им преимущество.

    Для углового + плавного потока, который создает следующее дерево папок:

     backend/ | |------ui/ | |------------------build/ <--'static' folder, constructed by Grunt | |--<proj |----vendors/ <-- angular.js and others here | |-- folders> |----src/ <-- your js | |----index.html <-- your SPA entrypoint |------<proj |------ folders> | |------view.py <-- Flask app here 

    Я использую следующее решение:

     ... root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "ui", "build") @app.route('/<path:path>', methods=['GET']) def static_proxy(path): return send_from_directory(root, path) @app.route('/', methods=['GET']) def redirect_to_index(): return send_from_directory(root, 'index.html') ... 

    Это помогает переопределить «статическую» папку для пользовательских.

    Поэтому я получил работу (основанную на ответе @ user1671599) и хотел поделиться ею с вами, ребята (надеюсь, что я делаю это правильно, так как это мое первое приложение на python)

    поэтому на основе @ user1671599 ответ я сделал это –

    Структура проекта:

    введите описание изображения здесь

    server.py:

     from server.AppStarter import AppStarter import os static_folder_root = os.path.join(os.path.dirname(os.path.abspath(__file__)), "client") app = AppStarter() app.register_routes_to_resources(static_folder_root) app.run(__name__) 

    AppStarter.py:

     from flask import Flask, send_from_directory from flask_restful import Api, Resource from server.ApiResources.TodoList import TodoList from server.ApiResources.Todo import Todo class AppStarter(Resource): def __init__(self): self._static_files_root_folder_path = '' # Default is current folder self._app = Flask(__name__) # , static_folder='client', static_url_path='') self._api = Api(self._app) def _register_static_server(self, static_files_root_folder_path): self._static_files_root_folder_path = static_files_root_folder_path self._app.add_url_rule('/<path:file_relative_path_to_root>', 'serve_page', self._serve_page, methods=['GET']) self._app.add_url_rule('/', 'index', self._goto_index, methods=['GET']) def register_routes_to_resources(self, static_files_root_folder_path): self._register_static_server(static_files_root_folder_path) self._api.add_resource(TodoList, '/todos') self._api.add_resource(Todo, '/todos/<todo_id>') def _goto_index(self): return self._serve_page("index.html") def _serve_page(self, file_relative_path_to_root): return send_from_directory(self._static_files_root_folder_path, file_relative_path_to_root) def run(self, module_name): if module_name == '__main__': self._app.run(debug=True) 

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

     app = Flask(__name__, static_url_path='', static_folder='web/static', template_folder='web/templates') 
    • static_url_path='' удаляет любой предыдущий путь из URL (т. е. по умолчанию /static ).
    • static_folder='web/static' будет static_folder='web/static' на файлы, найденные в web/static .
    • template_folder='web/templates' , аналогично, это изменяет папку шаблонов.

    Используя этот метод, следующий URL-адрес вернет файл CSS:

     <link rel="stylesheet" type="text/css" href="/css/bootstrap.min.css"> 

    И, наконец, вот flask_server.py структуры папок, где flask_server.py – это экземпляр Flask:

    Вложенные статические фляжные папки

    По умолчанию флажок использует папку «шаблоны» для размещения всех ваших файлов шаблонов (любой текстовый файл, но обычно .html или какой-то язык шаблонов, такой как jinja2) и «статическая» папка, которая содержит все ваши статические файлы ( т.е. .js .css и ваши изображения).
    На ваших routes вы можете использовать render_template() для рендеринга файла шаблона (как я сказал выше, по умолчанию он помещается в папку templates ) в качестве ответа для вашего запроса. И в файле шаблона (обычно это файл в формате .html), вы можете использовать некоторые .js и / или `.css 'файлы, поэтому, я думаю, ваш вопрос заключается в том, как увязать эти статические файлы с текущим файлом шаблона.

     from flask import redirect, url_for ... @app.route('/', methods=['GET']) def metrics(): return redirect(url_for('static', filename='jenkins_analytics.html')) 

    Это серверы всех файлов (css & js …), на которые ссылается ваш html-файл.

    Если вы просто пытаетесь открыть файл, вы можете использовать app.open_resource() . Поэтому чтение файла будет выглядеть примерно так:

     with app.open_resource('/static/path/yourfile'): #code to read the file and do something 
    Python - лучший язык программирования в мире.