views:

36

answers:

1

I am consuming a webservice (written in java) - that basically returns a byte[] array (the SOAP equivalent is base64 encoded binary data).

I am using the python suds library and the following code works for me on my mac (and on cygwin under windows), but the decoding does not work on vanilla windows (python 2.6.5). I am primarily a java developer so any help will be really helpful.

from suds.client import Client
import base64,os,shutil,tarfile,StringIO

u = "user"
p = "password"

url = "https://xxxx/?wsdl"

client = Client(url, username=u, password=p)

bin =  client.service.getTargz("test")

f = open("tools.tar.gz", "w")

f.write(base64.b64decode(bin.encode('ASCII')))

f.close()

print "finished writing"

tarfile.open("tools.tar.gz").extractall()

Works great on a mac - but on windows gives me this error:

C:\client>python client.py
xml
Getting the sysprep file from the webservice
finished writing
Traceback (most recent call last):
  File "client.py", line 28, in 
    tarfile.open("tools.tar.gz").extractall()
  File "C:\Python26\lib\tarfile.py", line 1653, in open
    return func(name, "r", fileobj, **kwargs)
  File "C:\Python26\lib\tarfile.py", line 1720, in gzopen
    **kwargs)
  File "C:\Python26\lib\tarfile.py", line 1698, in taropen
    return cls(name, mode, fileobj, **kwargs)
  File "C:\Python26\lib\tarfile.py", line 1571, in __init__
    self.firstmember = self.next()
  File "C:\Python26\lib\tarfile.py", line 2317, in next
    tarinfo = self.tarinfo.fromtarfile(self)
  File "C:\Python26\lib\tarfile.py", line 1235, in fromtarfile
    buf = tarfile.fileobj.read(BLOCKSIZE)
  File "C:\Python26\lib\gzip.py", line 219, in read
    self._read(readsize)
  File "C:\Python26\lib\gzip.py", line 271, in _read
    uncompress = self.decompress.decompress(buf)
zlib.error: Error -3 while decompressing: invalid distance too far back
+3  A: 

Try

f = open("tools.tar.gz", "wb")

It's crucial to tell Python that it's a binary file (in Py3, it also becomes crucial on Unixy systems, but in Py2 it's not strictly needed on them, which is why your code works on MacOSX): the default is text, which, on Windows, translates each \n written into \r\n on disk upon writing.

Alex Martelli
Thanks very much Alex - changing it to "wb" works great. I kept playing with the encoding/decoding which I thought was tripping up the system. A very basic mistake - which hopefully I will never make again.
Pranay Ahlawat
@Pranay, you're welcome, and, don't feel too bad about it: we all do slip up like this from time to time esp. if we usually program on Unixy systems (inc. Macs) and once in a while need to code for Windows instead;-)... that's why the problem was easy for me to spot, I've made it and fixed so many times;-).
Alex Martelli