Czy istnieje sprytne rozwiązanie do przechowywania plików statycznych w katalogu głównym aplikacji Flask? Pliki robots.txt i sitemap.xml powinny znajdować się w /, więc moim pomysłem było utworzenie dla nich tras:
@app.route('/sitemap.xml', methods=['GET'])
def sitemap():
response = make_response(open('sitemap.xml').read())
response.headers["Content-type"] = "text/plain"
return response
Musi być coś wygodniejszego :)
@vonPetrushev ma rację, w produkcji będziesz chciał obsługiwać pliki statyczne przez nginx lub apache, ale w przypadku programowania dobrze jest mieć proste środowisko programistyczne, w którym aplikacja Python obsługuje również statyczną zawartość, więc nie musisz się martwić o zmianie konfiguracji i wielu projektach. Aby to zrobić, będziesz chciał użyć SharedDataMiddleware .
from flask import Flask app = Flask(__name__) ''' Your app setup and code ''' if app.config['DEBUG']: from werkzeug import SharedDataMiddleware import os app.wsgi_app = SharedDataMiddleware(app.wsgi_app, { '/': os.path.join(os.path.dirname(__file__), 'static') })
Ten przykład zakłada, że Twoje pliki statyczne znajdują się w folderze „static”, dostosuj je do tego, co pasuje do Twojego środowiska.
źródło
Najczystszą odpowiedzią na to pytanie jest odpowiedź na to (identyczne) pytanie :
from flask import Flask, request, send_from_directory app = Flask(__name__, static_folder='static') @app.route('/robots.txt') @app.route('/sitemap.xml') def static_from_root(): return send_from_directory(app.static_folder, request.path[1:])
Podsumowując:
źródło
Mimo że jest to stare pytanie, odpowiadam na nie, ponieważ ten post pojawia się dość wysoko w wynikach Google. Chociaż nie jest to uwzględnione w dokumentacji, jeśli czytasz dokumentację API dla konstruktora obiektów Flask Application, jest to objęte. Przekazując nazwany parametr w ten
static_folder
sposób:from flask import Flask app = Flask(__name__, static_folder="/path/to/static", template_folder="/path/to/templates")
... możesz określić, skąd mają być obsługiwane pliki statyczne. Podobnie, możesz zdefiniować swoje
template_folder
imięstatic_url_path
.źródło
/static
ale możesz to zmienić, zastępującstatic_url_path
.Obsługa plików statycznych nie ma nic wspólnego z aplikacją, która ma dostarczać dynamiczną zawartość. Prawidłowy sposób obsługi plików statycznych zależy od używanego serwera. W końcu po uruchomieniu i uruchomieniu aplikacji będziesz musiał powiązać ją z serwerem internetowym. Mogę mówić tylko o apache httpd, więc sposób obsługi plików statycznych jest zdefiniowany na hoście wirtualnym, który łączysz z aplikacją za pomocą mod-wsgi. Oto przewodnik, który pokaże Ci, jak udostępniać mapy witryn, plik robots.txt lub dowolną zawartość statyczną: http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Mounting_At_Root_Of_Site
źródło
Innym sposobem wysyłania plików statycznych jest użycie reguły catch-all, takiej jak ta:
@app.route('/<path:path>') def catch_all(path): if not app.debug: flask.abort(404) try: f = open(path) except IOError, e: flask.abort(404) return return f.read()
Używam tego, aby zminimalizować konfigurację podczas programowania. Pomysł pochodzi z http://flask.pocoo.org/snippets/57/
Co więcej, pracuję przy użyciu Flask na mojej samodzielnej maszynie, ale wdrażam z Apache na serwerze produkcyjnym. Używam:
file_suffix_to_mimetype = { '.css': 'text/css', '.jpg': 'image/jpeg', '.html': 'text/html', '.ico': 'image/x-icon', '.png': 'image/png', '.js': 'application/javascript' } def static_file(path): try: f = open(path) except IOError, e: flask.abort(404) return root, ext = os.path.splitext(path) if ext in file_suffix_to_mimetype: return flask.Response(f.read(), mimetype=file_suffix_to_mimetype[ext]) return f.read() [...] if __name__ == '__main__': parser = optparse.OptionParser() parser.add_option('-d', '--debug', dest='debug', default=False, help='turn on Flask debugging', action='store_true') options, args = parser.parse_args() if options.debug: app.debug = True # set up flask to serve static content app.add_url_rule('/<path:path>', 'static_file', static_file) app.run()
źródło
Mogło to zostać dodane od czasu zadania tego pytania, ale przeglądałem plik „helpers.py” flask i znalazłem flask.send_from_directory:
send_from_directory(directory, filename, **options) ''' send_from_directory(directory, filename, **options) Send a file from a given directory with send_file. This is a secure way to quickly expose static files from an upload folder or something similar. '''
... który odwołuje się do flask.send_file:
send_file(filename_or_fp, mimetype=None, as_attachment=False, attachment_filename=None, add_etags=True, cache_timeout=43200, conditional=False)
... co wydaje się lepsze dla większej kontroli, chociaż send_from_directory przekazuje ** opcje bezpośrednio do send_file.
źródło
Z dokumentacji tutaj: http://flask.pocoo.org/docs/quickstart/#static-files
źródło
Ja też mam ten sam dylemat. Poszukałem i znalazłem odpowiedź (MHO):
Równie dobrze można cytować z dokumentacji
IMHO: Gdy aplikacja jest gotowa do produkcji , statyczne serwowanie plików powinno być (lub jest idealnie) skonfigurowane na serwerze internetowym (nginx, apache); ale podczas rozwoju Flask udostępnił go do obsługi plików statycznych. Ma to pomóc w szybkim rozwoju - nie ma potrzeby konfigurowania serwerów WWW i tym podobnych.
Mam nadzieję, że to pomoże.
źródło
Spróbuj tego:
@app.route("/ProtectedFolder/<path:filename>") @CheckUserSecurityAccessConditions def Protect_Content(filename): return send_from_directory((os.path.join(os.path.dirname(__file__), 'ProtectedFolder')),filename)
źródło