wsgiref --- WSGI Tiện ích và triển khai tham khảo

Source code: Lib/wsgiref


Cảnh báo

wsgiref là một triển khai tham khảo và không được khuyến nghị đưa vào sản xuất. Mô-đun này chỉ thực hiện kiểm tra bảo mật cơ bản.

Giao diện cổng máy chủ web (WSGI) là giao diện tiêu chuẩn giữa phần mềm máy chủ web và ứng dụng web được viết bằng Python. Việc có giao diện chuẩn giúp bạn dễ dàng sử dụng ứng dụng hỗ trợ WSGI với một số máy chủ web khác nhau.

Chỉ tác giả của máy chủ web và khung lập trình mới cần biết mọi chi tiết và góc cạnh của thiết kế WSGI. Bạn không cần phải hiểu mọi chi tiết về WSGI chỉ để cài đặt ứng dụng WSGI hoặc viết ứng dụng web bằng framework hiện có.

wsgiref là một triển khai tham chiếu của đặc tả WSGI có thể được sử dụng để thêm hỗ trợ WSGI cho máy chủ web hoặc khung. Nó cung cấp các tiện ích để thao tác các biến môi trường WSGI và tiêu đề phản hồi, các lớp cơ sở để triển khai máy chủ WSGI, máy chủ HTTP demo phục vụ các ứng dụng WSGI, các loại để kiểm tra loại tĩnh và công cụ xác thực kiểm tra sự phù hợp của máy chủ và ứng dụng WSGI với thông số kỹ thuật WSGI (PEP 3333).

Xem wsgi.readthedocs.io để biết thêm thông tin về WSGI và liên kết đến các hướng dẫn cũng như các tài nguyên khác.

wsgiref.util -- tiện ích môi trường WSGI

Mô-đun này cung cấp nhiều chức năng tiện ích để làm việc với môi trường WSGI. Môi trường WSGI là một từ điển chứa các biến yêu cầu HTTP như được mô tả trong PEP 3333. Tất cả các hàm sử dụng tham số environ đều yêu cầu cung cấp từ điển tuân thủ WSGI; vui lòng xem PEP 3333 để biết thông số kỹ thuật chi tiết và WSGIEnvironment để biết bí danh loại có thể được sử dụng trong chú thích loại.

wsgiref.util.guess_scheme(environ)

Đưa ra dự đoán xem wsgi.url_scheme nên là "http" hay "https", bằng cách kiểm tra biến môi trường HTTPS trong từ điển environ. Giá trị trả về là một chuỗi.

Chức năng này hữu ích khi tạo một cổng bao bọc CGI hoặc giao thức giống CGI như FastCGI. Thông thường, các máy chủ cung cấp các giao thức như vậy sẽ bao gồm biến HTTPS có giá trị "1", "có" hoặc "bật" khi nhận được yêu cầu qua SSL. Vì vậy, hàm này trả về "https" nếu tìm thấy giá trị như vậy và "http" nếu không.

wsgiref.util.request_uri(environ, include_query=True)

Trả về yêu cầu đầy đủ URI, tùy chọn bao gồm chuỗi truy vấn, sử dụng thuật toán có trong phần "Tái tạo URL" của PEP 3333. Nếu include_query sai thì chuỗi truy vấn sẽ không được đưa vào URI thu được.

wsgiref.util.application_uri(environ)

Tương tự như request_uri(), ngoại trừ các biến PATH_INFOQUERY_STRING bị bỏ qua. Kết quả là URI cơ sở của đối tượng ứng dụng được xử lý theo yêu cầu.

wsgiref.util.shift_path_info(environ)

Chuyển một tên từ PATH_INFO sang SCRIPT_NAME và trả lại tên đó. Từ điển environmodified tại chỗ; sử dụng một bản sao nếu bạn cần giữ nguyên PATH_INFO hoặc SCRIPT_NAME gốc.

Nếu không còn đoạn đường dẫn nào trong PATH_INFO, None sẽ được trả về.

Thông thường, quy trình này được sử dụng để xử lý từng phần của đường dẫn URI yêu cầu, ví dụ: coi đường dẫn đó là một chuỗi các khóa từ điển. Quy trình này sửa đổi môi trường được truyền vào để làm cho nó phù hợp để gọi một ứng dụng WSGI khác nằm ở URI đích. Ví dụ: nếu có ứng dụng WSGI tại /foo và đường dẫn URI yêu cầu là /foo/bar/baz và ứng dụng WSGI tại /foo gọi shift_path_info(), nó sẽ nhận được chuỗi "bar" và môi trường sẽ được cập nhật để phù hợp để chuyển sang ứng dụng WSGI tại /foo/bar. Nghĩa là, SCRIPT_NAME sẽ thay đổi từ /foo thành /foo/barPATH_INFO sẽ thay đổi từ /bar/baz thành /baz.

Khi PATH_INFO chỉ là "/", quy trình này trả về một chuỗi trống và nối thêm dấu gạch chéo vào SCRIPT_NAME, mặc dù các đoạn đường dẫn trống thường bị bỏ qua và SCRIPT_NAME thường không kết thúc bằng dấu gạch chéo. Đây là hành vi có chủ ý, nhằm đảm bảo rằng ứng dụng có thể cho biết sự khác biệt giữa các URI kết thúc bằng /x và các URI kết thúc bằng /x/ khi sử dụng quy trình này để thực hiện truyền tải đối tượng.

wsgiref.util.setup_testing_defaults(environ)

Cập nhật environ với các giá trị mặc định tầm thường cho mục đích thử nghiệm.

Quy trình này thêm các tham số khác nhau cần thiết cho WSGI, bao gồm HTTP_HOST, SERVER_NAME, SERVER_PORT, REQUEST_METHOD, SCRIPT_NAME, PATH_INFO và tất cả các biến PEP 3333-được xác định wsgi.*. Nó chỉ cung cấp các giá trị mặc định và không thay thế bất kỳ cài đặt hiện có nào cho các biến này.

Quy trình này nhằm giúp việc kiểm tra đơn vị của máy chủ và ứng dụng WSGI dễ dàng hơn trong việc thiết lập môi trường giả. Nó nên được sử dụng bởi các máy chủ hoặc ứng dụng WSGI thực tế vì dữ liệu là giả mạo!

Cách sử dụng ví dụ (xem thêm demo_app() để biết ví dụ khác):

từ wsgiref.util nhập setup_testing_defaults
từ wsgiref.simple_server nhập make_server

# A ứng dụng WSGI tương đối đơn giản. Nó sẽ in ra
Từ điển # environment sau khi được setup_testing_defaults cập nhật
def simple_app(environ, start_response):
    setup_testing_defaults(môi trường)

    trạng thái = '200 OK'
    tiêu đề = [('Loại nội dung', 'văn bản/thuần túy; bộ ký tự=utf-8')]

    start_response(trạng thái, tiêu đề)

    ret = [("%s: %s\n" % (khóa, giá trị)).encode("utf-8")
           cho khóa, giá trị trong environ.items()]
    trở lại

với make_server('', 8000, simple_app)  httpd:
    print("Phục vụ trên cổng 8000...")
    httpd.serve_forever()

Ngoài các chức năng môi trường ở trên, mô-đun wsgiref.util còn cung cấp các tiện ích linh tinh sau:

wsgiref.util.is_hop_by_hop(header_name)

Trả về True nếu 'header_name' là tiêu đề HTTP/1.1 "Hop-by-Hop", như được xác định bởi RFC 2616.

class wsgiref.util.FileWrapper(filelike, blksize=8192)

Triển khai cụ thể giao thức wsgiref.types.FileWrapper được sử dụng để chuyển đổi một đối tượng giống như tệp thành iterator. Đối tượng thu được là iterables. Khi đối tượng được lặp lại, tham số blksize tùy chọn sẽ được chuyển đi lặp lại tới phương thức read() của đối tượng filelike để thu được chuỗi byte mang lại. Khi read() trả về một chuỗi byte trống, quá trình lặp kết thúc và không thể tiếp tục.

Nếu filelike có phương thức close(), đối tượng được trả về cũng sẽ có phương thức close() và nó sẽ gọi phương thức close() của đối tượng filelike khi được gọi.

Ví dụ sử dụng:

từ io nhập StringIO
từ wsgiref.util nhập FileWrapper

# We đang sử dụng bộ đệm StringIO làm đối tượng giống như tệp
filelike = StringIO("Đây là một đối tượng giống như tệp mẫu"*10)
trình bao bọc = FileWrapper(filelike, blksize=5)

cho đoạn trong trình bao bọc:
    in (đoạn)

Thay đổi trong phiên bản 3.11: Hỗ trợ cho phương pháp __getitem__() đã bị xóa.

wsgiref.headers -- công cụ tiêu đề phản hồi WSGI

Mô-đun này cung cấp một lớp duy nhất, Headers, để thao tác thuận tiện với các tiêu đề phản hồi WSGI bằng giao diện giống như ánh xạ.

class wsgiref.headers.Headers([headers])

Tạo một đối tượng giống như ánh xạ bao bọc headers, đối tượng này phải là danh sách các bộ giá trị/tên tiêu đề như được mô tả trong PEP 3333. Giá trị mặc định của headers là danh sách trống.

Các đối tượng Headers hỗ trợ các hoạt động ánh xạ điển hình bao gồm __getitem__(), get(), __setitem__(), setdefault(), __delitem__()__contains__(). Đối với mỗi phương thức này, khóa là tên tiêu đề (được xử lý không phân biệt chữ hoa chữ thường) và giá trị là giá trị đầu tiên được liên kết với tên tiêu đề đó. Việc đặt tiêu đề sẽ xóa mọi giá trị hiện có cho tiêu đề đó, sau đó thêm giá trị mới vào cuối danh sách tiêu đề được bao bọc. Thứ tự hiện tại của các tiêu đề thường được duy trì, với các tiêu đề mới được thêm vào cuối danh sách được bao bọc.

Không giống như từ điển, các đối tượng Headers không gây ra lỗi khi bạn cố lấy hoặc xóa một khóa không có trong danh sách tiêu đề được bao bọc. Việc lấy một tiêu đề không tồn tại chỉ trả về None và việc xóa một tiêu đề không tồn tại sẽ không có tác dụng gì.

Các đối tượng Headers cũng hỗ trợ các phương thức keys(), values()items(). Các danh sách được trả về bởi keys()items() có thể bao gồm cùng một khóa nhiều lần nếu có tiêu đề đa giá trị. len() của đối tượng Headers giống với độ dài của items(), giống với độ dài của danh sách tiêu đề được bao bọc. Trong thực tế, phương thức items() chỉ trả về một bản sao của danh sách tiêu đề được gói.

Việc gọi bytes() trên đối tượng Headers sẽ trả về một chuỗi byte được định dạng phù hợp để truyền dưới dạng tiêu đề phản hồi HTTP. Mỗi tiêu đề được đặt trên một dòng với giá trị của nó, cách nhau bằng dấu hai chấm và dấu cách. Mỗi dòng được kết thúc bằng dấu xuống dòng và nguồn cấp dữ liệu dòng, đồng thời chuỗi byte được kết thúc bằng một dòng trống.

Ngoài các tính năng định dạng và giao diện ánh xạ, các đối tượng Headers còn có các phương thức sau để truy vấn và thêm các tiêu đề có nhiều giá trị cũng như để thêm các tiêu đề có tham số MIME:

get_all(name)

Trả về danh sách tất cả các giá trị cho tiêu đề được đặt tên.

Danh sách trả về sẽ được sắp xếp theo thứ tự chúng xuất hiện trong danh sách tiêu đề ban đầu hoặc được thêm vào trường hợp này và có thể chứa các bản sao. Bất kỳ trường nào bị xóa và chèn lại luôn được thêm vào danh sách tiêu đề. Nếu không có trường nào tồn tại với tên đã cho, trả về một danh sách trống.

add_header(name, value, **_params)

Thêm tiêu đề (có thể có nhiều giá trị), với các tham số MIME tùy chọn được chỉ định thông qua đối số từ khóa.

name là trường tiêu đề cần thêm. Đối số từ khóa có thể được sử dụng để đặt tham số MIME cho trường tiêu đề. Mỗi tham số phải là một chuỗi hoặc None. Dấu gạch dưới trong tên tham số được chuyển thành dấu gạch ngang, vì dấu gạch ngang là bất hợp pháp trong mã định danh Python, nhưng nhiều tên tham số MIME bao gồm dấu gạch ngang. Nếu giá trị tham số là một chuỗi, nó sẽ được thêm vào tham số giá trị tiêu đề ở dạng name="value". Nếu là None thì chỉ thêm tên tham số. (Cái này được sử dụng cho các tham số MIME không có giá trị.) Cách sử dụng ví dụ:

h.add_header('bố trí nội dung', 'tệp đính kèm', filename='bud.gif')

Ở trên sẽ thêm một tiêu đề trông như thế này

Bố trí nội dung: tệp đính kèm; tên tệp="bud.gif"

Thay đổi trong phiên bản 3.5: Tham số headers là tùy chọn.

wsgiref.simple_server -- một máy chủ WSGI HTTP đơn giản

Mô-đun này triển khai một máy chủ HTTP đơn giản (dựa trên http.server) phục vụ các ứng dụng WSGI. Mỗi phiên bản máy chủ phục vụ một ứng dụng WSGI duy nhất trên một máy chủ và cổng nhất định. Nếu muốn phân phát nhiều ứng dụng trên một máy chủ và cổng, bạn nên tạo một ứng dụng WSGI phân tích cú pháp PATH_INFO để chọn ứng dụng nào sẽ gọi cho mỗi yêu cầu. (Ví dụ: sử dụng hàm shift_path_info() từ wsgiref.util.)

wsgiref.simple_server.make_server(host, port, app, server_class=WSGIServer, handler_class=WSGIRequestHandler)

Tạo máy chủ WSGI mới nghe trên hostport, chấp nhận kết nối cho app. Giá trị trả về là một phiên bản của server_class được cung cấp và sẽ xử lý các yêu cầu bằng cách sử dụng handler_class được chỉ định. app phải là đối tượng ứng dụng WSGI, như được xác định bởi PEP 3333.

Ví dụ sử dụng:

từ wsgiref.simple_server nhập make_server, demo_app

với make_server('', 8000, demo_app)  httpd:
    print("Phục vụ HTTP trên cổng 8000...")

    # Respond để yêu cầu cho đến khi quá trình bị hủy
    httpd.serve_forever()

    # Alternative: phục vụ một yêu cầu, sau đó thoát
    httpd.handle_request()
wsgiref.simple_server.demo_app(environ, start_response)

Hàm này là một ứng dụng WSGI nhỏ nhưng hoàn chỉnh trả về một trang văn bản có chứa thông báo "Xin chào thế giới!" và danh sách các cặp khóa/giá trị được cung cấp trong tham số environ. Việc này rất hữu ích khi xác minh rằng máy chủ WSGI (chẳng hạn như wsgiref.simple_server) có thể chạy chính xác một ứng dụng WSGI đơn giản.

Có thể gọi start_response phải tuân theo giao thức StartResponse.

class wsgiref.simple_server.WSGIServer(server_address, RequestHandlerClass)

Tạo một phiên bản WSGIServer. server_address phải là một bộ (host,port)RequestHandlerClass phải là lớp con của http.server.BaseHTTPRequestHandler sẽ được sử dụng để xử lý các yêu cầu.

Thông thường bạn không cần phải gọi hàm tạo này vì hàm make_server() có thể xử lý tất cả các chi tiết cho bạn.

WSGIServer là một lớp con của http.server.HTTPServer, vì vậy tất cả các phương thức của nó (chẳng hạn như serve_forever()handle_request()) đều khả dụng. WSGIServer cũng cung cấp các phương thức dành riêng cho WSGI sau:

set_app(application)

Đặt application có thể gọi được làm ứng dụng WSGI sẽ nhận được yêu cầu.

get_app()

Trả về ứng dụng hiện được đặt có thể gọi được.

Tuy nhiên, thông thường, bạn không cần sử dụng các phương thức bổ sung này, vì set_app() thường được gọi bởi make_server()get_app() tồn tại chủ yếu vì lợi ích của các phiên bản xử lý yêu cầu.

class wsgiref.simple_server.WSGIRequestHandler(request, client_address, server)

Tạo trình xử lý HTTP cho request đã cho (tức là một ổ cắm), client_address (một bộ (host,port)) và server (phiên bản WSGIServer).

Bạn không cần phải tạo trực tiếp các thể hiện của lớp này; chúng được tạo tự động khi cần thiết bởi các đối tượng WSGIServer. Tuy nhiên, bạn có thể phân lớp lớp này và cung cấp nó dưới dạng handler_class cho hàm make_server(). Một số phương pháp có thể có liên quan để ghi đè trong các lớp con:

get_environ()

Trả lại từ điển WSGIEnvironment cho một yêu cầu. Việc triển khai mặc định sao chép nội dung thuộc tính từ điển base_environ của đối tượng WSGIServer và sau đó thêm các tiêu đề khác nhau bắt nguồn từ yêu cầu HTTP. Mỗi lệnh gọi phương thức này sẽ trả về một từ điển mới chứa tất cả các biến môi trường CGI có liên quan như được chỉ định trong PEP 3333.

get_stderr()

Trả về đối tượng nên được sử dụng làm luồng wsgi.errors. Việc triển khai mặc định chỉ trả về sys.stderr.

handle()

Xử lý yêu cầu HTTP. Việc triển khai mặc định sẽ tạo một phiên bản trình xử lý bằng cách sử dụng lớp wsgiref.handlers để triển khai giao diện ứng dụng WSGI thực tế.

wsgiref.validate --- trình kiểm tra tuân thủ WSGI

Khi tạo các đối tượng, khung, máy chủ hoặc phần mềm trung gian mới của ứng dụng WSGI, việc xác thực tính tuân thủ của mã mới bằng wsgiref.validate có thể hữu ích. Mô-đun này cung cấp chức năng tạo các đối tượng ứng dụng WSGI để xác thực thông tin liên lạc giữa máy chủ hoặc cổng WSGI và đối tượng ứng dụng WSGI, để kiểm tra sự tuân thủ giao thức của cả hai bên.

Lưu ý rằng tiện ích này không đảm bảo tuân thủ hoàn toàn PEP 3333; việc không có lỗi trong mô-đun này không nhất thiết có nghĩa là không có lỗi. Tuy nhiên, nếu mô-đun này gây ra lỗi thì gần như chắc chắn rằng máy chủ hoặc ứng dụng không tuân thủ 100%.

Mô-đun này dựa trên mô-đun paste.lint từ thư viện "Python Paste" của Ian Bicking.

wsgiref.validate.validator(application)

Gói application và trả về một đối tượng ứng dụng WSGI mới. Ứng dụng được trả về sẽ chuyển tiếp tất cả các yêu cầu tới application ban đầu và sẽ kiểm tra xem cả application và máy chủ gọi nó có tuân thủ đặc tả WSGI và RFC 2616 hay không.

Bất kỳ sự không phù hợp nào được phát hiện đều dẫn đến AssertionError được nâng lên; tuy nhiên, lưu ý rằng cách xử lý những lỗi này phụ thuộc vào máy chủ. Ví dụ: wsgiref.simple_server và các máy chủ khác dựa trên wsgiref.handlers (không ghi đè các phương pháp xử lý lỗi để làm việc khác) sẽ chỉ đưa ra thông báo rằng đã xảy ra lỗi và chuyển truy nguyên sang sys.stderr hoặc một số luồng lỗi khác.

Trình bao bọc này cũng có thể tạo đầu ra bằng mô-đun warnings để chỉ ra các hành vi đáng ngờ nhưng có thể không thực sự bị PEP 3333 cấm. Trừ khi chúng bị chặn bằng cách sử dụng các tùy chọn dòng lệnh Python hoặc warnings API, mọi cảnh báo như vậy sẽ được ghi vào sys.stderr (not wsgi.errors, trừ khi chúng là cùng một đối tượng).

Ví dụ sử dụng:

từ trình xác nhận nhập wsgiref.validate
từ wsgiref.simple_server nhập make_server

Đối tượng  thể gọi # Our cố tình không tuân thủ
# standard, vậy là trình xác nhận sẽ bị hỏng
def simple_app(environ, start_response):
    trạng thái = '200 OK' # HTTP Trạng thái
    tiêu đề = [('Loại nội dung', 'văn bản/thuần túy')] # HTTP Tiêu đề
    start_response(trạng thái, tiêu đề)

    # This sắp bị hỏng vì chúng tôi cần trả về một danh sách và
    Trình xác thực # the sẽ thông báo cho chúng tôi
    return b"Xin chào thế giới"

# This là ứng dụng được gói trong trình xác thực
validator_app = trình xác nhận (simple_app)

với make_server('', 8000, validator_app)  httpd:
    print("Đang nghe trên cổng 8000....")
    httpd.serve_forever()

wsgiref.handlers -- lớp cơ sở máy chủ/cổng

Mô-đun này cung cấp các lớp xử lý cơ sở để triển khai các máy chủ và cổng WSGI. Các lớp cơ sở này xử lý hầu hết công việc giao tiếp với ứng dụng WSGI, miễn là chúng được cung cấp môi trường giống CGI, cùng với các luồng đầu vào, đầu ra và lỗi.

class wsgiref.handlers.CGIHandler

Lệnh gọi dựa trên CGI thông qua sys.stdin, sys.stdout, sys.stderros.environ. Điều này hữu ích khi bạn có ứng dụng WSGI và muốn chạy nó dưới dạng tập lệnh CGI. Đơn giản chỉ cần gọi CGIHandler().run(app), trong đó app là đối tượng ứng dụng WSGI mà bạn muốn gọi.

Lớp này là một lớp con của BaseCGIHandler đặt wsgi.run_once thành true, wsgi.multithread thành false và wsgi.multiprocess thành true, đồng thời luôn sử dụng sysos để có được các luồng và môi trường CGI cần thiết.

class wsgiref.handlers.IISCGIHandler

Một giải pháp thay thế chuyên dụng cho CGIHandler, để sử dụng khi triển khai trên máy chủ web IIS của Microsoft mà không cần đặt tùy chọn cấu hình allowPathInfo (IIS>=7) hoặc siêu dữ liệu allowPathInfoForScriptMappings (IIS<7).

Theo mặc định, IIS cung cấp PATH_INFO sao chép SCRIPT_NAME ở phía trước, gây ra sự cố cho các ứng dụng WSGI muốn triển khai định tuyến. Trình xử lý này loại bỏ mọi đường dẫn trùng lặp như vậy.

IIS có thể được định cấu hình để chuyển PATH_INFO chính xác, nhưng điều này gây ra một lỗi khác trong đó PATH_TRANSLATED sai. May mắn thay, biến này hiếm khi được sử dụng và không được WSGI đảm bảo. Tuy nhiên, trên IIS<7, cài đặt chỉ có thể được thực hiện ở cấp vhost, ảnh hưởng đến tất cả các ánh xạ tập lệnh khác, nhiều trong số đó bị hỏng khi gặp lỗi PATH_TRANSLATED. Vì lý do này, IIS<7 gần như không bao giờ được triển khai cùng với bản sửa lỗi (Ngay cả IIS7 cũng hiếm khi sử dụng nó vì vẫn chưa có giao diện người dùng cho nó.).

Không có cách nào để mã CGI biết liệu tùy chọn đã được đặt hay chưa, do đó, một lớp xử lý riêng sẽ được cung cấp. Nó được sử dụng theo cách tương tự như CGIHandler, tức là bằng cách gọi IISCGIHandler().run(app), trong đó app là đối tượng ứng dụng WSGI mà bạn muốn gọi.

Added in version 3.2.

class wsgiref.handlers.BaseCGIHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)

Tương tự như CGIHandler, nhưng thay vì sử dụng các mô-đun sysos, môi trường CGI và các luồng I/O được chỉ định rõ ràng. Các giá trị multithreadmultiprocess được sử dụng để đặt cờ wsgi.multithreadwsgi.multiprocess cho bất kỳ ứng dụng nào được chạy bởi phiên bản trình xử lý.

Lớp này là một lớp con của SimpleHandler được thiết kế để sử dụng với phần mềm không phải là "máy chủ gốc" HTTP. Nếu bạn đang viết triển khai giao thức cổng (chẳng hạn như CGI, FastCGI, SCGI, v.v.) sử dụng tiêu đề Status: để gửi trạng thái HTTP, bạn có thể muốn phân lớp này thay vì SimpleHandler.

class wsgiref.handlers.SimpleHandler(stdin, stdout, stderr, environ, multithread=True, multiprocess=False)

Tương tự như BaseCGIHandler, nhưng được thiết kế để sử dụng với máy chủ gốc HTTP. Nếu bạn đang viết một triển khai máy chủ HTTP, có thể bạn sẽ muốn phân lớp này thay vì BaseCGIHandler.

Lớp này là một lớp con của BaseHandler. Nó ghi đè các phương thức __init__(), get_stdin(), get_stderr(), add_cgi_vars(), _write()_flush() để hỗ trợ thiết lập rõ ràng môi trường và luồng thông qua hàm tạo. Môi trường và luồng được cung cấp được lưu trữ trong các thuộc tính stdin, stdout, stderrenviron.

Phương thức write() của stdout sẽ viết đầy đủ từng đoạn, như io.BufferedIOBase.

class wsgiref.handlers.BaseHandler

Đây là lớp cơ sở trừu tượng để chạy các ứng dụng WSGI. Mỗi phiên bản sẽ xử lý một yêu cầu HTTP duy nhất, mặc dù về nguyên tắc, bạn có thể tạo một lớp con có thể sử dụng lại cho nhiều yêu cầu.

Các phiên bản BaseHandler chỉ có một phương thức dành cho mục đích sử dụng bên ngoài:

run(app)

Chạy ứng dụng WSGI được chỉ định, app.

Tất cả các phương thức BaseHandler khác đều được gọi bằng phương thức này trong quá trình chạy ứng dụng và do đó tồn tại chủ yếu để cho phép tùy chỉnh quy trình.

Các phương thức MUST sau đây sẽ được ghi đè trong một lớp con:

_write(data)

Đệm các byte data để truyền tới máy khách. Sẽ không sao nếu phương pháp này thực sự truyền dữ liệu; BaseHandler chỉ tách biệt các thao tác ghi và xóa để có hiệu quả cao hơn khi hệ thống cơ bản thực sự có sự khác biệt như vậy.

_flush()

Buộc truyền dữ liệu vào bộ đệm đến máy khách. Sẽ không sao nếu phương pháp này không hoạt động (tức là nếu _write() thực sự gửi dữ liệu).

get_stdin()

Trả về một đối tượng tương thích với InputStream phù hợp để sử dụng làm wsgi.input của yêu cầu hiện đang được xử lý.

get_stderr()

Trả về một đối tượng tương thích với ErrorStream phù hợp để sử dụng làm wsgi.errors của yêu cầu hiện đang được xử lý.

add_cgi_vars()

Chèn các biến CGI cho yêu cầu hiện tại vào thuộc tính environ.

Dưới đây là một số phương pháp và thuộc tính khác mà bạn có thể muốn ghi đè. Tuy nhiên, danh sách này chỉ là bản tóm tắt và không bao gồm mọi phương thức có thể bị ghi đè. Bạn nên tham khảo các chuỗi tài liệu và mã nguồn để biết thêm thông tin trước khi thử tạo một lớp con BaseHandler tùy chỉnh.

Các thuộc tính và phương thức để tùy chỉnh môi trường WSGI:

wsgi_multithread

Giá trị được sử dụng cho biến môi trường wsgi.multithread. Nó mặc định là true trong BaseHandler, nhưng có thể có giá trị mặc định khác (hoặc được đặt bởi hàm tạo) trong các lớp con khác.

wsgi_multiprocess

Giá trị được sử dụng cho biến môi trường wsgi.multiprocess. Nó mặc định là true trong BaseHandler, nhưng có thể có giá trị mặc định khác (hoặc được đặt bởi hàm tạo) trong các lớp con khác.

wsgi_run_once

Giá trị được sử dụng cho biến môi trường wsgi.run_once. Nó mặc định là sai trong BaseHandler, nhưng CGIHandler đặt nó thành true theo mặc định.

os_environ

Các biến môi trường mặc định được bao gồm trong môi trường WSGI của mọi yêu cầu. Theo mặc định, đây là bản sao của os.environ tại thời điểm wsgiref.handlers được nhập, nhưng các lớp con có thể tạo lớp con của riêng chúng ở cấp độ lớp hoặc cấp độ phiên bản. Lưu ý rằng từ điển nên được coi là chỉ đọc vì giá trị mặc định được chia sẻ giữa nhiều lớp và phiên bản.

server_software

Nếu thuộc tính origin_server được đặt, giá trị của thuộc tính này được sử dụng để đặt biến môi trường SERVER_SOFTWARE WSGI mặc định và cũng để đặt tiêu đề Server: mặc định trong phản hồi HTTP. Nó bị bỏ qua đối với các trình xử lý (chẳng hạn như BaseCGIHandlerCGIHandler) không phải là máy chủ gốc HTTP.

Thay đổi trong phiên bản 3.3: Thuật ngữ "Python" được thay thế bằng thuật ngữ cụ thể khi triển khai như "CPython", "Jython", v.v.

get_scheme()

Trả về sơ đồ URL đang được sử dụng cho yêu cầu hiện tại. Việc triển khai mặc định sử dụng hàm guess_scheme() từ wsgiref.util để đoán xem lược đồ nên là "http" hay "https", dựa trên các biến environ của yêu cầu hiện tại.

setup_environ()

Đặt thuộc tính environ thành môi trường WSGI được điền đầy đủ. Việc triển khai mặc định sử dụng tất cả các phương thức và thuộc tính ở trên, cộng với các phương thức get_stdin(), get_stderr()add_cgi_vars() cũng như thuộc tính wsgi_file_wrapper. Nó cũng chèn khóa SERVER_SOFTWARE nếu không có, miễn là thuộc tính origin_server là giá trị đúng và thuộc tính server_software được đặt.

Các phương thức và thuộc tính để tùy chỉnh xử lý ngoại lệ:

log_exception(exc_info)

Ghi lại bộ dữ liệu exc_info vào nhật ký máy chủ. exc_info là một bộ (type, value, traceback). Việc triển khai mặc định chỉ đơn giản ghi truy nguyên vào luồng wsgi.errors của yêu cầu và xóa nó. Các lớp con có thể ghi đè phương thức này để thay đổi định dạng hoặc nhắm mục tiêu lại đầu ra, gửi thông tin truy nguyên qua thư cho quản trị viên hoặc bất kỳ hành động nào khác có thể được coi là phù hợp.

traceback_limit

Số lượng khung hình tối đa cần đưa vào đầu ra truy nguyên theo phương thức log_exception() mặc định. Nếu None, tất cả các khung đều được bao gồm.

error_output(environ, start_response)

Phương pháp này là một ứng dụng WSGI để tạo trang lỗi cho người dùng. Nó chỉ được gọi nếu xảy ra lỗi trước khi tiêu đề được gửi đến máy khách.

Phương pháp này có thể truy cập lỗi hiện tại bằng cách sử dụng sys.exception() và sẽ chuyển thông tin đó đến start_response khi gọi nó (như được mô tả trong phần "Xử lý lỗi" của PEP 3333). Đặc biệt, start_response có thể gọi được phải tuân theo giao thức StartResponse.

Việc triển khai mặc định chỉ sử dụng các thuộc tính error_status, error_headerserror_body để tạo trang đầu ra. Các lớp con có thể ghi đè điều này để tạo ra nhiều lỗi động hơn.

Tuy nhiên, xin lưu ý rằng từ góc độ bảo mật, bạn không nên đưa ra chẩn đoán cho bất kỳ người dùng cũ nào; lý tưởng nhất là bạn phải làm điều gì đó đặc biệt để bật đầu ra chẩn đoán, đó là lý do tại sao việc triển khai mặc định không bao gồm bất kỳ điều gì.

error_status

Trạng thái HTTP được sử dụng để phản hồi lỗi. Đây phải là chuỗi trạng thái như được xác định trong PEP 3333; nó mặc định là mã 500 và tin nhắn.

error_headers

Các tiêu đề HTTP được sử dụng để phản hồi lỗi. Đây phải là danh sách các tiêu đề phản hồi WSGI (bộ dữ liệu (name, value)), như được mô tả trong PEP 3333. Danh sách mặc định chỉ đặt loại nội dung thành text/plain.

error_body

Cơ quan phản hồi lỗi. Đây phải là chuỗi nội dung phản hồi HTTP. Nó mặc định ở dạng văn bản thuần túy, "Đã xảy ra lỗi máy chủ. Vui lòng liên hệ với quản trị viên."

Các phương thức và thuộc tính cho tính năng "Xử lý tệp dành riêng cho nền tảng tùy chọn" của PEP 3333:

wsgi_file_wrapper

Nhà máy wsgi.file_wrapper, tương thích với wsgiref.types.FileWrapper hoặc None. Giá trị mặc định của thuộc tính này là lớp wsgiref.util.FileWrapper.

sendfile()

Ghi đè để triển khai truyền tệp dành riêng cho nền tảng. Phương thức này chỉ được gọi nếu giá trị trả về của ứng dụng là một thể hiện của lớp được chỉ định bởi thuộc tính wsgi_file_wrapper. Nó sẽ trả về giá trị đúng nếu có thể truyền tệp thành công, do đó mã truyền mặc định sẽ không được thực thi. Việc triển khai mặc định của phương thức này chỉ trả về một giá trị sai.

Các phương thức và thuộc tính khác:

origin_server

Thuộc tính này phải được đặt thành giá trị thực nếu _write()_flush() của trình xử lý đang được sử dụng để liên lạc trực tiếp với máy khách, thay vì thông qua giao thức cổng giống CGI muốn trạng thái HTTP trong tiêu đề Status: đặc biệt.

Giá trị mặc định của thuộc tính này là đúng trong BaseHandler nhưng sai trong BaseCGIHandlerCGIHandler.

http_version

Nếu origin_server là đúng, thuộc tính chuỗi này được sử dụng để đặt phiên bản HTTP của phản hồi được đặt cho máy khách. Nó mặc định là "1.0".

wsgiref.handlers.read_environ()

Chuyển mã các biến CGI từ chuỗi "byte in unicode" os.environ sang PEP 3333, trả về một từ điển mới. Chức năng này được CGIHandlerIISCGIHandler sử dụng thay cho việc sử dụng trực tiếp os.environ, không nhất thiết phải tuân thủ WSGI trên tất cả các nền tảng và máy chủ web sử dụng Python 3 -- cụ thể là những nền tảng có môi trường thực tế của HĐH là Unicode (tức là Windows) hoặc môi trường có môi trường là byte, nhưng mã hóa hệ thống được Python sử dụng để giải mã nó là bất kỳ thứ gì khác ngoài ISO-8859-1 (ví dụ: các hệ thống Unix sử dụng UTF-8).

Nếu bạn đang triển khai một trình xử lý dựa trên CGI của riêng mình, bạn có thể muốn sử dụng quy trình này thay vì chỉ sao chép trực tiếp các giá trị ra khỏi os.environ.

Added in version 3.2.

wsgiref.types -- các loại WSGI để kiểm tra kiểu tĩnh

Mô-đun này cung cấp nhiều loại khác nhau để kiểm tra loại tĩnh như được mô tả trong PEP 3333.

Added in version 3.11.

class wsgiref.types.StartResponse

Một typing.Protocol mô tả các lệnh gọi start_response() (PEP 3333).

wsgiref.types.WSGIEnvironment

Bí danh loại mô tả từ điển môi trường WSGI.

wsgiref.types.WSGIApplication

Bí danh loại mô tả ứng dụng WSGI có thể gọi được.

class wsgiref.types.InputStream

Một typing.Protocol mô tả một WSGI Input Stream.

class wsgiref.types.ErrorStream

Một typing.Protocol mô tả một WSGI Error Stream.

class wsgiref.types.FileWrapper

Một typing.Protocol mô tả một file wrapper. Xem wsgiref.util.FileWrapper để biết cách triển khai cụ thể giao thức này.

Ví dụ

Đây là một ứng dụng WSGI "Hello World" đang hoạt động, trong đó start_response có thể gọi phải tuân theo giao thức StartResponse

"""
Mỗi ứng dụng WSGI phải có một đối tượng ứng dụng - một đối tượng có thể gọi được
đối tượng chấp nhận hai đối số. Với mục đích đó, chúng ta sẽ
sử dụng một chức năng (lưu ý rằng bạn không bị giới hạn ở một chức năng, bạn có thể
sử dụng một lớp chẳng hạn). Đối số đầu tiên được truyền cho hàm
là một từ điển chứa các biến môi trường kiểu CGI và
biến thứ hai là đối tượng có thể gọi được.
"""
từ wsgiref.simple_server nhập make_server


def hello_world_app(environ, start_response):
    trạng thái = "200 OK" # HTTP Trạng thái
    tiêu đề = [("Loại nội dung", "văn bản/thuần túy; bộ ký tự=utf-8")] # HTTP Tiêu đề
    start_response(trạng thái, tiêu đề)

    đối tượng trả về # The sẽ được in
    return [b"Xin chào thế giới"]

với make_server("", 8000, hello_world_app)  httpd:
    print("Phục vụ trên cổng 8000...")

    # Serve cho đến khi quá trình bị hủy
    httpd.serve_forever()

Ví dụ về ứng dụng WSGI phục vụ thư mục hiện tại, chấp nhận thư mục và số cổng tùy chọn (mặc định: 8000) trên dòng lệnh:

"""
Máy chủ web dựa trên wsgiref nhỏ. Có một con đường để phục vụ từ và một
số cổng tùy chọn (mặc định là 8000), sau đó cố gắng phân phát tệp.
Các loại MIME được đoán từ tên file, lỗi 404 xuất hiện
nếu tập tin không được tìm thấy.
"""
nhập  phỏng
hệ điều hành nhập khẩu
hệ thống nhập khẩu
từ wsgiref nhập simple_server, sử dụng


ứng dụng def (môi trường, phản hồi):
    # Get tên tệp và loại MIME
    fn = os.path.join(path, environ["PATH_INFO"][1:])
    nếu "." không  trong fn.split(os.path.sep)[-1]:
        fn = os.path.join(fn, "index.html")
    mime_type = mimetypes.guess_file_type(fn)[0]

    # Return 200 OK nếu tệp tồn tại, nếu không thì 404 Not Found
    nếu os.path.exists(fn):
        phản hồi ("200 OK", [("Loại nội dung", mime_type)])
        trả về util.FileWrapper(open(fn, "rb"))
    khác:
        reply("Không tìm thấy 404", [("Loại nội dung", "văn bản/thuần túy")])
        trả về [b"không tìm thấy"]


nếu __name__ == "__main__":
    # Get đường dẫn và cổng từ đối số dòng lệnh
    path = sys.argv[1] if len(sys.argv) > 1 else os.getcwd()
    port = int(sys.argv[2]) if len(sys.argv) > 2 else 8000

    # Make và khởi động máy chủ cho đến khi control-c
    httpd = simple_server.make_server("", cổng, ứng dụng)
    print(f"Đang cung cấp {path} trên cổng {port}, control-C dừng")
    thử:
        httpd.serve_forever()
    ngoại trừ Bàn phímInterrupt:
        print("Tắt.")
        httpd.server_close()