Wsgiref Error: AttributeError: 'NoneType' object has no attribute 'split'
Asked Answered
C

5

11

I am trying to implement my own version of wsgiref for learning purpose and I ended up here:

from wsgiref.simple_server import make_server

class DemoApp():
    def __init__(self, environ, start_response):
        self.environ = environ
        self.start = start_response

    def __iter__(self, status):
        self.status = '200 OK'
        response_headers = [('Content-type','text/plain')]
        self.start(status, response_headers)
        return ["Hello World"]


if __name__ == '__main__':
    httpd = make_server('', 1000, DemoApp)
    print("Serving on port 1000")
    httpd.serve_forever()

When I go to port 1000, I am getting the attribute error.

AttributeError: 'NoneType' object has no attribute 'split'

Where am I leaving mistakes?

Stacktrace:

Serving on port 1000
Traceback (most recent call last):
  File "C:\Python27\lib\wsgiref\handlers.py", line 86, in run
    self.finish_response()
  File "C:\Python27\lib\wsgiref\handlers.py", line 131, in finish_response
    self.close()
  File "C:\Python27\lib\wsgiref\simple_server.py", line 33, in close
    self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
127.0.0.1 - - [11/Jan/2014 12:40:09] "GET / HTTP/1.1" 500 59
Traceback (most recent call last):
  File "C:\Python27\lib\SocketServer.py", line 295, in _handle_request_noblock
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 54469)
    self.process_request(request, client_address)
  File "C:\Python27\lib\SocketServer.py", line 321, in process_request
    self.finish_request(request, client_address)
  File "C:\Python27\lib\SocketServer.py", line 334, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "C:\Python27\lib\SocketServer.py", line 649, in __init__
    self.handle()
  File "C:\Python27\lib\wsgiref\simple_server.py", line 124, in handle
    handler.run(self.server.get_app())
  File "C:\Python27\lib\wsgiref\handlers.py", line 92, in run
    self.close()
  File "C:\Python27\lib\wsgiref\simple_server.py", line 33, in close
    self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
Coburg answered 11/1, 2014 at 7:5 Comment(3)
I tried your code and it executed without errors. Can you post the full stack trace?Silviasilviculture
Post the full stack trace of the AttributeError, please.Ingeingeberg
@skoll, You need to access the page after running the server.Biannual
C
3

How about this, you need to yield the output than returning it.

from wsgiref.simple_server import make_server

class DemoApp:

    def __init__(self, environ, start_response):
        self.environ = environ
        self.start = start_response

    def __iter__(self):
        status = '200 OK'
        response_headers = [('Content-type', 'text/plain')]
        self.start(status, response_headers)
        yield 'Hello world!'


if __name__ == '__main__':
    httpd = make_server('', 1000, DemoApp)
    print("Serving HTTP on port 1000...")
    httpd.serve_forever()
Coburg answered 11/1, 2014 at 7:27 Comment(1)
The same error, I figured what is the problem in my case, it is related to Python 3 strings, see my answerKarolkarola
K
10

You should encode the returned body to utf-8

return ["Hello World".encode("utf-8")]

This code works fine with me, I am using Python 3.3.3:

from wsgiref.simple_server import make_server


def app(env, start_response):
    body = "Hello"
    status = "200 OK"
    headers = [("Content-Type", "text/plain; charset=utf-8")]
    start_response(status, headers)
    return [body.encode("utf-8")]

port = 9080
httpd = make_server("localhost", port, app)
print("Server started on port: ", port)
httpd.serve_forever()
Karolkarola answered 18/5, 2014 at 12:20 Comment(1)
Encoding the returned body to utf-8 works for me. However I don't understand why as the reference in the wsgi tutorial does not encode to utf-8. @Karolkarola care to explain why?Gurrola
B
5

DemoApp is called; The return value of DemoApp.__init__ is used.

DemoApp.__init__ returns nothing (You can't return anything in constructor).

Try following instead of DemoApp class:

def DemoApp(environ, start_response):
    response_headers = [('Content-type','text/plain')]
    start_response('200 OK', response_headers)
    return ["Hello World"]

Using class (Use __call__ instead of __iter__):

from wsgiref.simple_server import make_server

class DemoApp:
    def __call__(self, environ, start_response):
        response_headers = [('Content-type','text/plain')]
        start_response('200 OK', response_headers)
        return ["Hello World"]


if __name__ == '__main__':
    httpd = make_server('', 1000, DemoApp()) # Don't forget instantiate a class.
    #                                    ^^
    print("Serving on port 1000")
    httpd.serve_forever()
Biannual answered 11/1, 2014 at 7:13 Comment(1)
I know this, this is given docs also. How to write it using classes ?Coburg
C
3

How about this, you need to yield the output than returning it.

from wsgiref.simple_server import make_server

class DemoApp:

    def __init__(self, environ, start_response):
        self.environ = environ
        self.start = start_response

    def __iter__(self):
        status = '200 OK'
        response_headers = [('Content-type', 'text/plain')]
        self.start(status, response_headers)
        yield 'Hello world!'


if __name__ == '__main__':
    httpd = make_server('', 1000, DemoApp)
    print("Serving HTTP on port 1000...")
    httpd.serve_forever()
Coburg answered 11/1, 2014 at 7:27 Comment(1)
The same error, I figured what is the problem in my case, it is related to Python 3 strings, see my answerKarolkarola
P
0

adding .encode("utf-8") solved the problem for me Python 3.4.2

Philter answered 17/1, 2015 at 11:53 Comment(0)
R
-1

I had the same issue.

I solved it by setting: DATA_UPLOAD_MAX_NUMBER_FIELDS = 10000 in settings.py.

Django 2.2

Reaction answered 14/7, 2019 at 15:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.