I would like some advice. I have encountered the following error in Python 2.6:
Traceback (most recent call last):
File "<pyshell#20>", line 1, in <module>
s.Search(query)
File "/usr/lib/python2.6/xmlrpclib.py", line 1199, in __call__
return self.__send(self.__name, args)
File "/usr/lib/python2.6/xmlrpclib.py", line 1489, in __request
verbose=self.__verbose
File "/usr/lib/python2.6/xmlrpclib.py", line 1253, in request
return self._parse_response(h.getfile(), sock)
File "/usr/lib/python2.6/xmlrpclib.py", line 1392, in _parse_response
return u.close()
File "/usr/lib/python2.6/xmlrpclib.py", line 838, in close
raise Fault(**self._stack[0])
Fault: <Fault 1: "<type 'exceptions.TypeError'>:dictionary key must be string">
My code is serving up part of a mini search engine using Django. In Python 3 everything runs like a dream, but Django is not available for Python 3 so I need to backdate my code, which is where the problem comes from.
My code (client.py):
# -*- coding: utf-8 -*-
from __future__ import unicode_literals # This was suggested elsewhere
import xmlrpclib
s = xmlrpclib.ServerProxy('http://localhost:11210')
data = s.Search('מלאכא') # tried prefixing with 'u'
print data
My code (Server.py):
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import pickle, sys, xmlrpclib
from SimpleXMLRPCServer import SimpleXMLRPCServer
from SimpleXMLRPCServer import SimpleXMLRPCRequestHandler
from collections import defaultdict
docscores = pickle.load(open("docscores.pkl", "rb"))
print ("Everything loaded. No errors.")
# Restrict to a particular path.
class RequestHandler(SimpleXMLRPCRequestHandler):
rpc_paths = ('/RPC2',)
# Create server
server = SimpleXMLRPCServer(("localhost", 11210), requestHandler=RequestHandler)
server.register_introspection_functions()
def Search(query):
results = docscores[query]
return results
server.register_function(Search, 'Search')
# Run the server's main loop
server.serve_forever()
As you can see it's pretty simple, but I get a 'dictionary key must be string' when parsing the unicode string across to the server from the client. However, the server seems quite happy and produces the following feedback, which shows it has accessed my pickled dictionary (returning a doc number and count of the ngram):
{160: 3, 417: 1, 35: 1, 133: 1, 376: 1, 193: 1, 380: 1, 363: 1, 364: 1, 126: 1, 47: 1, 145: 1, 147: 1, 382: 1, 246: 3, 121: 4, 440: 1, 441: 1, 444: 1, 280: 1}
localhost.localdomain - - [09/Aug/2011 13:32:23] "POST /RPC2 HTTP/1.0" 200 -
If I do:
type(query)
The result is:
I've also tried reload(sys)
, prefixing u'unicode_string'
, u"".join(unicode_string)
, and query
.decode('utf-8')`, but still get this error, or end up with more errors relating to unicode/ascii decoding.
Does anyone have any ideas how I can get around this error? Or is there an alternative to XMLPRPCServer for serving data between a server instance and a client in Python 2.6?
Many thanks in advance.