1
votes

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
1

1 Answers

7
votes

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.