2010-11-21 37 views
79

Có giải pháp thông minh nào để lưu trữ các tệp tĩnh trong thư mục gốc ứng dụng của Flask hay không. robots.txt và sitemap.xml dự kiến ​​sẽ được tìm thấy trong /, vì vậy ý ​​tưởng của tôi là tạo ra các tuyến đường cho họ:Tệp tĩnh trong Flask - robot.txt, sitemap.xml (mod_wsgi)

@app.route('/sitemap.xml', methods=['GET']) 
def sitemap(): 
    response = make_response(open('sitemap.xml').read()) 
    response.headers["Content-type"] = "text/plain" 
    return response 

Phải có một cái gì đó thuận tiện hơn :)

Trả lời

60

cách tốt nhất là để thiết lập static_url_path để url gốc

from flask import Flask 

app = Flask(__name__, static_folder='static', static_url_path='') 
+2

đây là một trong những làm việc cho các tập tin tĩnh, Cảm ơn bạn. +1 –

+0

Điều đáng nói đến là static_folder không phải nằm trong thư mục dự án. ví dụ. static_folder = '/ app/ui' là tốt. – ashic

15

Phục vụ các tập tin tĩnh không có gì để làm với ứng dụng có nghĩa là cung cấp nội dung động. Cách phục vụ đúng các tệp tĩnh phụ thuộc vào máy chủ bạn đang sử dụng. Sau khi tất cả, khi bạn nhận được và chạy ứng dụng của bạn, bạn sẽ cần phải liên kết nó với một máy chủ web. Tôi chỉ có thể nói cho httpd apache, vì vậy cách phục vụ các tệp tĩnh được xác định trong máy chủ ảo mà bạn đang ràng buộc với ứng dụng của mình thông qua mod-wsgi. Dưới đây là hướng dẫn sẽ cho bạn biết cách phân phối sơ đồ trang web, robots.txt hoặc bất kỳ nội dung tĩnh nào: http://code.google.com/p/modwsgi/wiki/QuickConfigurationGuide#Mounting_At_Root_Of_Site

+0

Đó là câu trả lời tôi đã được tìm kiếm.Cảm ơn! – biesiad

+1

Một ứng dụng có nghĩa là cung cấp nội dung, một số động và một số tĩnh. –

65

@vonPetrushev là đúng, trong quá trình sản xuất bạn sẽ muốn phân phát tệp tĩnh qua nginx hoặc apache, nhưng để phát triển thật tuyệt khi bạn có môi trường dev đơn giản để ứng dụng python của bạn phục vụ nội dung tĩnh, vì vậy bạn không phải lo lắng về việc thay đổi cấu hình và nhiều dự án. Để làm điều đó, bạn sẽ muốn sử dụng 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') 
    }) 

Ví dụ này giả định tệp tĩnh nằm trong thư mục "tĩnh", điều chỉnh cho phù hợp với môi trường của bạn.

+0

THANKS! Đây là những gì tôi cần! Tôi đang tìm cách để làm điều này cho sản xuất của tôi heroku. Xem câu trả lời trên chuỗi sau: http://flask.pocoo.org/mailinglist/archive/2012/2/22/flask-on-heroku-%2B-gunicorn-static-files/#20ff50d1dac06bf228b38d62ab11c6a9 – David

+0

Điều này rất mẹo hay! –

+2

Cảnh báo - có cách dễ dàng hơn để xử lý việc này ngay bây giờ. Kiểm tra trả lời của tôi. –

3

Từ tài liệu ở đây: http://flask.pocoo.org/docs/quickstart/#static-files

các ứng dụng web động cần tĩnh file là tốt. Đó thường là nơi các tệp CSS và JavaScript là đến từ đó. Lý tưởng nhất là máy chủ web của bạn được định cấu hình để phục vụ chúng cho bạn, nhưng trong quá trình phát triển, Flask cũng có thể thực hiện . Chỉ cần tạo một thư mục được gọi là tĩnh trong gói của bạn hoặc tiếp theo vào mô-đun của bạn và nó sẽ là có sẵn tại/static trên ứng dụng .

Để tạo URL cho rằng một phần của URL , sử dụng đặc biệt URL 'tĩnh' tên:

url_for ('tĩnh', filename = 'style.css')

Các tập tin phải được lưu trữ trên hệ thống tệp dưới dạng static/style.css.

5

Điều này có thể đã được thêm vào kể từ khi câu hỏi này được hỏi, nhưng tôi đang tìm kiếm thông qua "helpers.py" bình và tôi thấy 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. 
''' 

... mà tham chiếu flask.send_file :

send_file(filename_or_fp, mimetype=None, as_attachment=False, attachment_filename=None, add_etags=True, cache_timeout=43200, conditional=False) 

... có vẻ tốt hơn để kiểm soát nhiều hơn, mặc dù send_from_directory chuyển ** tùy chọn trực tiếp đến send_file.

0

Tôi cũng đang gặp khó khăn tương tự.Đã làm một số tìm kiếm và tìm thấy câu trả lời của tôi (MHO):

Cũng có thể trích dẫn từ tài liệu

các ứng dụng web động cần file tĩnh là tốt. Đó thường là nơi các tệp CSS và JavaScript đến từ đó. Lý tưởng nhất là máy chủ web của bạn được cấu hình để phục vụ chúng cho bạn, nhưng trong quá trình phát triển Flask cũng có thể thực hiện điều đó cũng như. Chỉ cần tạo một thư mục có tên là static trong gói của bạn hoặc bên cạnh module của bạn và nó sẽ có sẵn tại/static trên ứng dụng.

IMHO: Khi ứng dụng của bạn là lên cho sản xuất, tập tin phục vụ tĩnh nên (hoặc là lý tưởng) cấu hình trên máy chủ web (nginx, apache); nhưng trong quá trình phát triển , Flask đã sẵn sàng để phân phối các tệp tĩnh. Điều này là để giúp bạn phát triển nhanh chóng - không cần phải thiết lập máy chủ web và như vậy.

Hy vọng điều đó sẽ hữu ích.

13

Một cách khác để gửi các tập tin tĩnh là sử dụng một nhận tất cả quy tắc như vậy:

@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() 

Tôi sử dụng này để cố gắng giảm thiểu các thiết lập khi đang phát triển. Tôi đã có ý tưởng từ http://flask.pocoo.org/snippets/57/

Hơn nữa, tôi đang phát triển sử dụng bình trên máy độc lập của mình nhưng triển khai với máy chủ sản xuất Apache. Tôi sử dụng:

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() 
+1

Cảnh báo - có cách dễ dàng hơn để xử lý việc này ngay bây giờ. Kiểm tra trả lời của tôi. –

+0

Cách tuyệt vời nếu bạn cần phục vụ nhiều đường dẫn! –

21

Mặc dù đây là câu hỏi được trả lời cũ, tôi trả lời câu hỏi này vì bài đăng này có kết quả khá cao trong kết quả của Google. Trong khi nó không được đề cập trong tài liệu, nếu bạn đọc the API docs cho hàm tạo đối tượng Flask Application, nó được bảo vệ. Bằng cách chuyển thông số được đặt tên static_folder như vậy:

from flask import Flask 
app = Flask(__name__, 
      static_folder="/path/to/static", 
      template_folder="/path/to/templates") 

... bạn có thể xác định nơi tệp được phân phát. Tương tự, bạn có thể xác định template_folder, tên của bạn static_url_path.

+0

Tuyệt vời! Tôi đoán tuyến đường đến các tệp tĩnh sau đó vẫn là/static/.... – chmike

+0

@chmike yes, mặc định là '/ static' nhưng bạn có thể thay đổi điều đó bằng cách ghi đè' static_url_path'. –

+0

Điều này đúng nhưng các câu trả lời khác linh hoạt hơn. Điều này bị hạn chế bởi thực tế nó chỉ có thể phục vụ một đường dẫn thư mục. –

53

Câu trả lời sạch nhất cho câu hỏi này là answer này (giống hệt nhau) question:

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:]) 

Để tóm tắt:

  • như David chỉ ra, với cấu hình đúng đó là ok to serve a few static files through prod
  • tìm kiếm /robots.txt không nên dẫn đến chuyển hướng đến /static/robots.txt. (. Trong Seans trả lời nó không phải là ngay lập tức rõ ràng như thế nào đó là đạt được)
  • nó không sạch để thêm các tập tin tĩnh vào thư mục gốc ứng dụng
  • cuối cùng, giải pháp đề xuất có vẻ sạch hơn nhiều so với phương pháp middleware thêm:
Các vấn đề liên quan