2012-03-13 58 views
14

Tôi đã thiết lập máy chủ Apache và đang xử lý phản hồi Flask qua mod_wsgi. Tôi đã đăng ký kịch bản WSGI qua bí danh:Làm cách nào để sử dụng các tuyến Flask với Apache và mod_wsgi?

[httpd.conf]

WSGIScriptAlias /service "/mnt/www/wsgi-scripts/service.wsgi" 

Tôi đã thêm các tập tin WSGI tương ứng ở đường dẫn ở trên:

[/ mnt/www/wsgi-scripts/service.wsgi]

import sys 
sys.path.insert(0, "/mnt/www/wsgi-scripts") 

from service import application 

Và tôi có một thử nghiệm đơn giản Flask Python script cung cấp các mô-đun dịch vụ:

[/mnt/www/wsgi-scripts/service.py]

from flask import Flask 

app = Flask(__name__) 

@app.route('/') 
def application(environ, start_response): 
     status = '200 OK' 
     output = "Hello World!" 
     response_headers = [('Content-type', 'text/plain'), 
          ('Content-Length', str(len(output)))] 
     start_response(status, response_headers) 
     return [output] 

@app.route('/upload') 
def upload(environ, start_response): 
     output = "Uploading" 
     status = '200 OK' 
     response_headers = [('Content-type', 'text/plain'), 
          ('Content-Length', str(len(output)))] 
     start_response(status, response_headers) 
     return [output] 

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

Khi tôi đi đến URL trang web của tôi [hostname]/dịch vụ nó hoạt động như mong đợi và tôi nhận được "Hello World!" trở lại. Vấn đề là tôi không biết làm thế nào để có được các tuyến đường khác để làm việc như, 'tải lên' trong ví dụ trên. Điều này hoạt động tốt trong Flask độc lập nhưng theo mod_wsgi tôi stumped. Điều duy nhất tôi có thể tưởng tượng là đăng ký một biệt danh kịch bản WSGI riêng biệt trong httpd.conf cho mỗi điểm cuối mà tôi muốn, nhưng nó sẽ lấy đi sự hỗ trợ định tuyến ưa thích của Flask. Có cách nào để làm cho công việc này?

+3

Bạn đã thử duyệt qua '/ service/upload' chưa? Bạn có thể ngạc nhiên. –

+0

Khi tôi nhấn/dịch vụ/tải lên, yêu cầu vẫn được gửi đến chức năng 'ứng dụng'. Trong thực tế, tôi có thể loại bỏ các tuyên bố tuyến đường trước khi chức năng ứng dụng và nó vẫn hoạt động. Nó giống như ứng dụng luôn được sử dụng bởi mod_wsgi làm điểm vào ứng dụng. Nó cảm thấy như tôi cần phải làm một cái gì đó bên trong 'ứng dụng' mà bắt đầu logic định tuyến của Flask. –

Trả lời

17

Trong tệp wsgi của bạn, bạn đang thực hiện from service import application, chỉ nhập phương thức application của bạn.

Thay đổi điều đó thành from service import app as application và mọi thứ sẽ hoạt động như mong đợi.

Sau khi bình luận của bạn, tôi nghĩ rằng tôi muốn mở rộng câu trả lời một chút:

tập tin wsgi của bạn là mã python - bạn có thể có bất kỳ mã python hợp lệ bên trong tập tin này. Trình xử lý "wsgi" được cài đặt trong Apache đang tìm kiếm tên ứng dụng trong tệp này, nó sẽ chuyển yêu cầu đến. Một cá thể lớp Flask - app = Flask(__name__) - cung cấp một giao diện như vậy, nhưng kể từ khi nó được gọi là app và không phải là application, bạn phải đặt bí danh nó khi bạn nhập nó - đó là những gì từ dòng.

Bạn có thể - và điều này là hoàn toàn tốt - chỉ cần làm điều này application = Flask(__name__) và sau đó trỏ trình xử lý wsgi trong Apache vào tệp service.py của bạn. Nếu service.py có thể nhập được (có nghĩa là, ở đâu đó trong số PYTHONPATH), bạn sẽ không cần tập lệnh trung gian wsgi.

Mặc dù các tác phẩm trên, thực tiễn kém của nó. Tệp wsgi cần quyền từ quy trình Apache để hoạt động; và bạn thường tách biệt mã nguồn đó khỏi mã nguồn thực tế nên ở một nơi khác trên hệ thống tệp của bạn, với quyền phù hợp.

+0

đã làm các trick. Cảm ơn bạn! Ngoài việc thay đổi service.wsgi để khớp với những gì bạn đã chỉ ra, tôi cũng cần phải khôi phục service.py của mình để trở thành bình tinh khiết. Trong tuyên bố vấn đề ban đầu tôi nghĩ rằng tôi đã nhận được ra khỏi đường ray trộn mã mod_wsgi tinh khiết với Flask.Tôi nghĩ rằng nguồn gốc của sự nhầm lẫn này đã đặt tên cho ứng dụng xử lý tuyến đường gốc của tôi. –

+1

Tôi nghĩ rằng tôi không rõ ràng về mod_wsgi so với mã Flask. Tôi hiểu rằng đó là tất cả Python. Những gì tôi đã bị mắc kẹt trên là trong ví dụ trên '@ app.route ('/')' của tôi là trang trí chức năng 'ứng dụng'. Trong thiết lập ban đầu của tôi, tôi đã nhập chỉ ứng dụng để chỉ có chức năng đó đã được gọi. Khi tôi thay đổi _service.wsgi_ để sử dụng 'từ ứng dụng nhập dịch vụ là ứng dụng' đã tham chiếu chính xác đối tượng Flask, nhưng nó cũng có vẻ đã tạo ra xung đột đặt tên với hàm' application'. Tôi đã đổi tên hàm này thành '@def root():' và bây giờ nó hoạt động tốt. Cảm ơn một lần nữa! –

+0

Ngọt ngào! Đây là câu trả lời cho những tai ương của tôi. –

Các vấn đề liên quan