"AssertionError: write() argument must be a bytes instance" when running WSGISOAPHandler

5.6k Views Asked by At

I have a SOAP server with pysimplesoap in Python 3.

Code

from wsgiref.simple_server import make_server

application = WSGISOAPHandler(dispatcher)
wsgid = make_server('', 8008, application)
wsgid.serve_forever()

I don't know why am I get the following error.

Error

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
5

There are 5 best solutions below

1
Jordi Salom On BEST ANSWER
+++ pysimplesoap/server.py  

                     e['name'] = k
                     if array:
                         e[:] = {'minOccurs': "0", 'maxOccurs': "unbounded"}
-                    if v in TYPE_MAP.keys():
-                        t = 'xsd:%s' % TYPE_MAP[v]
-                    elif v is None:
+
+                    # check list and dict first to avoid
+                    # TypeError: unhashable type: 'list' or
+                    # TypeError: unhashable type: 'dict'
+                    if v is None:
                         t = 'xsd:anyType'
                     elif isinstance(v, list):
                         n = "ArrayOf%s%s" % (name, k)
                         n = "%s%s" % (name, k)
                         parse_element(n, v.items(), complex=True)
                         t = "tns:%s" % n
+                    elif v in TYPE_MAP.keys():
+                        t = 'xsd:%s' % TYPE_MAP[v]
                     else:
                         raise TypeError("unknonw type v for marshalling" % str(v))
                     e.add_attribute('type', t)
0
Nna.L On

in "handlers.py" line 180

self.write(data.encode()) instead of self.write(data)

0
TheSaGe On

It's all because of WSGI is made for Python 2, so you can face some troubles using it in Python 3. If you dont want to change library's behavior like in first answer, workaround is to encode() all text data like:

def application(environ,start_response):
    response_body = 'Hello World'
    return [response_body.encode()]
0
Narayan Bhat On

Wsgi framework is built around Python 2. Therefore, if there is stuff in your program that does not include Python 3 dependencies, run the app with Python 2.

0
Robin Stewart On

In my case the problem turned out to be that I was unintentionally outputting an object instead of a string. Fixed by encoding my result as a string via json.dumps(obj).