pythonwsgiref

Python a bytes-like object is required, not 'str'


I am new to Python. I am running following simple web server:

from wsgiref.simple_server import make_server
from io import BytesIO

def message_wall_app(environ, start_response):
    output = BytesIO()
    status = '200 OK' # HTTP Status
    headers = [('Content-type', 'text/html; charset=utf-8')]
    start_response(status, headers)
    print(b"<h1>Message Wall</h1>",file=output)
##    if environ['REQUEST_METHOD'] == 'POST': 
##        size = int(environ['CONTENT_LENGTH'])
##        post_str = environ['wsgi.input'].read(size)
##        print(post_str,"<p>", file=output)
##    print('<form method="POST">User: <input type="text" '
##          'name="user">Message: <input type="text" '
##          'name="message"><input type="submit" value="Send"></form>', 
##           file=output)         
    # The returned object is going to be printed
    return [output.getvalue()]     

httpd = make_server('', 8000, message_wall_app)
print("Serving on port 8000...")

# Serve until process is killed
httpd.serve_forever()

Unfortunately i get following error:

Traceback (most recent call last):
  File "C:\Users\xxx\Python36\lib\wsgiref\handlers.py", line 137, in run
    self.result = application(self.environ, self.start_response)
  File "C:/xxx/Python/message_wall02.py", line 9, in message_wall_app
    print("<h1>Message Wall</h1>".encode('ascii'),file=output)
TypeError: a bytes-like object is required, not 'str'....

Please suggest what i am doing wrong. thanks.


Solution

  • You can't use print() to write to binary files. print() converts arguments to str() before writing to a text file object.

    From the print() function documentation:

    Print objects to the text stream file, separated by sep and followed by end. [...]

    All non-keyword arguments are converted to strings like str() does and written to the stream, separated by sep and followed by end.

    Bold emphasis mine. Note that the file object must be a text stream, not a binary stream.

    Either write to a TextIOWrapper() object wrapping your BytesIO() object, call .write() on the BytesIO() object to write bytes objects directly, or write to a StringIO() object and encode the resulting string value at the end.