2

I'm trying to do a XMP-RPC using xmlrpclib python's lib, but i'm getting

xml.parsers.expat.ExpatError: XML or text declaration not at start of entity: line 1, column 1

Here is the dict with parameters:

{'cliente_chave': 'hUi238sh328sjk37Hms8Kisjeg9',
     'cliente_codigo': 164,
     'imovel_bairro': u'Renascen\xe7a',
     'imovel_banheiros': u'5',
     'imovel_cidade': u'S\xe3o Lu\xeds - MA',
     'imovel_codigo_imobiliaria': u'757',
     'imovel_descricao': u'\n\t\t\t\n\t\t\tCasa em otima localiza\xe7\xe3o ideal tanto para empresas quanto para moradia tendo:\r\nTerra\xe7o\r\nSala Ampla para 03 ambientes\r\nLavabo\r\nHall\r\n03 su\xedtes\r\nEscritorio\r\nCozinha\r\nQuintaL\r\n\xc1rea de Servi\xe7o\r\nDCE\r\nGaragem coberta para 02 carros\r\nPort\xe3o eletronico\r\nCisterna\r\nNascente',
     'imovel_estado': 'MA',
     'imovel_negociacao': 'venda',
     'imovel_novo': False,
     'imovel_quartos': u'3',
     'imovel_subtipo': u'padr\xe3o',
     'imovel_suites': u'3',
     'imovel_tipo': u'casa',
     'imovel_vagas': u'2',
     'imovel_valor': u' 480.000,00',
     'url': 'http://www.estiloma.com.br/imoveis/para-venda/em-sao-luis/no-bairro-renascenca/casa-padrao/id-774.html'}

And here is the Traceback to the Exception:

Traceback (most recent call last):
      File "/Library/Python/2.7/site-packages/Twisted-12.2.0-py2.7-macosx-10.8-intel.egg/twisted/internet/defer.py", line 551, in _runCallbacks
        current.result = callback(current.result, *args, **kw)
      File "/Users/bslima/Documents/Aptana Studio 3 Workspace/aqueleimovel/aqueleimovel/pipelines.py", line 31, in process_item
        result = server.salvar_imovel(dict(item))
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 1224, in __call__
        return self.__send(self.__name, args)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 1575, in __request
        verbose=self.__verbose
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 1264, in request
        return self.single_request(host, handler, request_body, verbose)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 1297, in single_request
        return self.parse_response(response)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 1467, in parse_response
        p.feed(data)
      File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/xmlrpclib.py", line 557, in feed
        self._parser.Parse(data, 0)
    xml.parsers.expat.ExpatError: XML or text declaration not at start of entity: line 1, column 1

I'm only using UTF-8 for strings and i've tried to encode or decode to UTF-8 if no luck. I also tried to google it but with no sucsess. Is somebody have seen this ?

Ow, here's the client code:

server = ServerProxy(uri=settings.RPC_SERVER, verbose=True)
server.salvar_imovel(item)

Thanks for the help in advance.

As i commented, the ExpatError was in the response object. Thanks

bslima
  • 1,097
  • 2
  • 15
  • 17
  • I noticed in the traceback, that the problem is in the response, not in the request. I'll investigate the response to see what's going on. Thanks @danodonovan – bslima Mar 03 '13 at 22:53

2 Answers2

6

[SOLVED] The response was sent with spaces in the beginning. I had to extend the Transport class from xmlrpc and simply strip the response.

from xmlrpc.client import SafeTransport, Transport
from xmlrpc.client import GzipDecodedResponse

is_https = False
if is_https:
    BaseTransport = SafeTransport
else:
    BaseTransport = Transport

class CustomTransport(BaseTransport):
    def parse_response(self, response):
        # read response data from httpresponse, and parse it

        # Check for new http response object, else it is a file object
        if hasattr(response,'getheader'):
            if response.getheader("Content-Encoding", "") == "gzip":
                stream = GzipDecodedResponse(response)
            else:
                stream = response
        else:
            stream = response

        p, u = self.getparser()

        while 1:
            data = stream.read(1024)
            data = data.strip()
            if not data:
                break
            if self.verbose:
                print "body:", repr(data)
            p.feed(data)

        if stream is not response:
            stream.close()
        p.close()

        return u.close()
Dan Loewenherz
  • 10,879
  • 7
  • 50
  • 81
bslima
  • 1,097
  • 2
  • 15
  • 17
  • 2
    Small remark: to invoke a method on a HTTPS server, I had to pass SafeTransport instead of Transport, otherwise the call was to the http:// URL, not https://. And to use this, do not forget to import Transport (or SafeTransport) and GzipDecodedResponse from xmlrpclib. In my case, this allowed me to strip the extra "\n" at the start of a Drupal XML-RPC response. – FGM Aug 29 '14 at 10:15
1

You seem to be passing a dict object to something expecting XML - this line

server.salvar_imovel(dict(item))

If you really must pass the dict in, you might try serializing the dict first. There is some example code here.

danodonovan
  • 19,636
  • 10
  • 70
  • 78
  • I noticed in the traceback, that the problem is in the response, not in the request. I'll investigate the response to see what's going on. Thanks @danodonovan – bslima Mar 05 '13 at 02:23