2014-12-17 3 views
4

간단한 HTML 양식을 사용자에게 제공하는 응용 프로그램을 만든 다음 사용자가 양식을 제출할 때 함수를 호출하려고합니다. wsgiref.simple_server를 사용하여 HTML을 제공합니다. 서버에 오류가 발생하여 이유를 이해할 수 없습니다.WSGI로 html을 제공 할 때 오류가 발생했습니다.

#!/usr/bin/python3 
from wsgiref.simple_server import make_server 
from wsgiref.util import setup_testing_defaults 
import webbrowser # open user's web browser to url when server is run 
from sys import exc_info 
from traceback import format_tb 

# Easily serves an html form at path_to_index with style at path_to_style 
# Calls on_submit when the form is submitted, passing a dictionary with key 
# value pairs { "input name" : submitted_value } 
class SimpleServer: 
    def __init__(self, port=8000, on_submit=None, index_path="./index.html", css_path="./style.css"): 
     self.port = port 
     self.on_submit = on_submit 
     self.index_path = index_path 
     self.css_path = css_path 

    # Forwards request to proper method, or returns 404 page 
    def wsgi_app(self, environ, start_response): 
     urls = [ 
      (r"^$", self.index), 
      (r"404$", self.error_404), 
      (r"style.css$", self.css) 
     ] 

     path = environ.get("PATH_INFO", "").lstrip("/") 
     # Call another application if they called a path defined in urls 
     for regex, application in urls: 
      match = re.search(regex, path) 
      # if the match was found, return that page 
      if match: 
       environ["myapp.url_args"] = match.groups() 
       return application(environ, start_response) 
     return error_404(environ, start_response) 

    # Gives the user a form to submit all their input. If the form has been 
    # submitted, it sends the ouput of self.on_submit(user_input) 
    def index(self, environ, start_response): 
     # user_input is a dictionary, with keys from the names of the fields 
     user_input = parse_qs(environ['QUERY_STRING']) 

     # return either the form or the calculations 
     index_html = open(self.index_path).read() 
     body = index_html if user_input == {} else calculate(user_input) 
     mime_type = "text/html" if user_input == {} else "text/plain" 

     # return the body of the message 
     status = "200 OK" 
     headers = [ ("Content-Type", mime_type), 
        ("Content-Length", str(len(body))) ] 
     start_response(status, headers) 
     return [body.encode("utf-8")] 


    def start_form(self): 
     httpd = make_server('', self.port, ExceptionMiddleware(self.wsgi_app)) 
     url = "http://localhost:" + str(self.port) 
     print("Visit " + url) 
     # webbrowser.open(url) 
     httpd.serve_forever() 

if __name__ == "__main__": 
    server = SimpleServer() 
    server.start_form() 

내가 그것을 실행하면, 나는이 출력이 실제로 I에 대한 혼란 스러워요 내가 실행하고 스크립트를 포함하지 않는 오류를

127.0.0.1 - - [16/Dec/2014 21:15:57] "GET/HTTP/1.1" 500 0 
Traceback (most recent call last): 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 138, in run 
    self.finish_response() 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 180, in finish_response 
    self.write(data) 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 266, in write 
    "write() argument must be a bytes instance" 
AssertionError: write() argument must be a bytes instance 
127.0.0.1 - - [16/Dec/2014 21:15:57] "GET/HTTP/1.1" 500 59 
---------------------------------------- 
Exception happened during processing of request from ('127.0.0.1', 49354) 
Traceback (most recent call last): 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 138, in run 
    self.finish_response() 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 180, in finish_response 
    self.write(data) 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 266, in write 
    "write() argument must be a bytes instance" 
AssertionError: write() argument must be a bytes instance 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 141, in run 
    self.handle_error() 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 368, in handle_error 
    self.finish_response() 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 180, in finish_response 
    self.write(data) 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 274, in write 
    self.send_headers() 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 331, in send_headers 
    if not self.origin_server or self.client_is_modern(): 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 344, in client_is_modern 
    return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9' 
TypeError: 'NoneType' object is not subscriptable 

During handling of the above exception, another exception occurred: 

Traceback (most recent call last): 
    File "/usr/lib/python3.4/socketserver.py", line 305, in _handle_request_noblock 
    self.process_request(request, client_address) 
    File "/usr/lib/python3.4/socketserver.py", line 331, in process_request 
    self.finish_request(request, client_address) 
    File "/usr/lib/python3.4/socketserver.py", line 344, in finish_request 
    self.RequestHandlerClass(request, client_address, self) 
    File "/usr/lib/python3.4/socketserver.py", line 669, in __init__ 
    self.handle() 
    File "/usr/lib/python3.4/wsgiref/simple_server.py", line 133, in handle 
    handler.run(self.server.get_app()) 
    File "/usr/lib/python3.4/wsgiref/handlers.py", line 144, in run 
    self.close() 
    File "/usr/lib/python3.4/wsgiref/simple_server.py", line 35, in close 
    self.status.split(' ',1)[0], self.bytes_sent 
AttributeError: 'NoneType' object has no attribute 'split' 

을 얻을 다음과 같이 코드입니다. 이견있는 사람?

답변

1

코드를 보면이 오류의 직접적인 이유는 없습니다. 그러나 wsgi가 작동하는 방법을 배우거나 자신 만의 프레임 워크를 구현하는 방법을 배우려하지 않는 한 기존의 마이크로 프레임 워크를 사용해야합니다. WSGI는 응용 프로그램에서 직접 사용할 수 없습니다. 파이썬과 웹 서버간에 매우 얇은 인터페이스를 제공합니다.

멋지고 가벼운 프레임 워크는 bottle.py입니다. 모든 Python webapps에 사용합니다. 그러나 많은 다른 것들이 있습니다, https://wiki.python.org/moin/WebFrameworks에 "Non Full-Stack Frameworks"를 찾으십시오.

병의 장점은 단일 파일이므로 서버와 함께 배포하기 쉽습니다.

2

이 문제에 대한 해결책을 등록하기 만하면 문제가 len() 함수에서 발생합니다.

STR (LEN (몸))

그것은 잘못된 크기를 계산하고 서버 콘텐츠 길이를 반환 할 때, 그것은 필요 이상의 바이트를 기다립니다.

from io import StringIO 
stdout = StringIO() 
print("Hello world!", file=stdout) 
start_response("200 OK", [('Content-Type', 'text/plain; charset=utf-8')]) 
return [stdout.getvalue().encode("utf-8")] 
: 따라서

항상 UTF-8, 예를 들어 다음과 함께 버퍼를 이용하여 바이트가 보내

관련 문제