UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)
Question: I have a Python script which uses tinypng api to convert images recursively
and for some reason it does not work and I get:

> UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0:
> ordinal not in range(128)

What am I doing wrong?

    
    
    import os
    import base64
    from os.path import dirname
    from urllib2 import Request, urlopen
    from base64 import b64encode
    
    compress_png = True 
    compress_jpg = True
    import_dir = '666\product'
    output_dir = '666\product'
    tiny_png_key = 'xxxxxx'
    tiny_png_url = 'https://api.tinypng.com/shrink'
    
    img_count = 0
    file_count = 0
    compress_count = 0
    existing_count = 0
    
    
    def compressImage(filepath, filedest, overwrite = True):
        global compress_count
        global existing_count
        if not os.path.isfile(filedest) or overwrite: 
            status = ''
            request = Request(tiny_png_url, open(filepath, "rb").read())
            auth = b64encode(bytes("api:" + tiny_png_key)).decode("ascii")
            request.add_header("Authorization", "Basic %s" % auth)
            response = urlopen(request)
    
            if response.getcode() == 201:
                status = "success";
                headers = response.info()
                result = urlopen(headers["Location"]).read()
    
                if not os.path.exists(os.path.dirname(filedest)):
                    os.makedirs(os.path.dirname(filedest))
                open(filedest, "wb").write(result)
                compress_count += 1
            else:
                status = "failed"
            print 'Compressing: %s\nFile: %s\nStatus: %s\n'%(filepath, img_count, status)
        else:
            existing_count += 1
    
    
    # loop througs files in import_dir recursively 
    for subdir, dirs, files in os.walk(import_dir):
        for file in files:
            filepath = os.path.join(subdir, file)
            fileName, fileExtension = os.path.splitext(file)
            file_count += 1
            if(fileExtension == '.png' and compress_png) or (fileExtension == '.jpg' and compress_jpg):
                img_count += 1
                filedest = filepath.replace(import_dir, output_dir)
                compressImage(filepath, filedest)
    
    
    print '================'
    print 'Total Files: %s'%(file_count)
    print 'Total Images: %s'%(img_count)
    print 'Images Compressed: %s'%(compress_count)
    print 'Images Previously Compressed (Exist in output directory): %s'%(existing_count)
    

Full error:

    
    
    Traceback (most recent call last):
        File "C:\Users\Vygantas\Desktop\test.py", line 55, in <module> compressImage(filepath, filedest)
        File "C:\Users\Vygantas\Desktop\test.py", line 28, in compressImage response = urlopen(request)
        File "C:\Python27\lib\urllib2.py", line 126, in urlopen return _opener.open(url, data, timeout)
        File "C:\Python27\lib\urllib2.py", line 391, in open response = self._open(req, data)
        File "C:\Python27\lib\urllib2.py", line 409, in _open '_open', req)
        File "C:\Python27\lib\urllib2.py", line 369, in _call_chain result = func(*args)
        File "C:\Python27\lib\urllib2.py", line 1181, in https_open return self.do_open(httplib.HTTPSConnection, req)
        File "C:\Python27\lib\urllib2.py", line 1142, in do_open h.request(req.get_method(), req.get_selector(), req.data, headers)
        File "C:\Python27\lib\httplib.py", line 946, in request self._send_request(method, url, body, headers)
        File "C:\Python27\lib\httplib.py", line 987, in _send_request self.endheaders(body)
        File "C:\Python27\lib\httplib.py", line 940, in endheaders self._send_output(message_body)
        File "C:\Python27\lib\httplib.py", line 801, in _send_output msg += message_body UnicodeDecodeError: 'ascii' codec can't decode byte 0xff in position 0: ordinal not in range(128)
    


Answer: You have to encode the data but not the user name I would try something like:

    
    
    def compressImage(filepath, filedest, overwrite = True):
        global compress_count
        global existing_count
        if not os.path.isfile(filedest) or overwrite: 
            status = ''
            data = open(filepath, "rb").read()
            data = base64.b64encode(data)
            request = Request(tiny_png_url, data)
            request.add_header("Content-type", "application/x-www-form-urlencoded; charset=UTF-8")
            auth = "api:" + tiny_png_key
            request.add_header("Authorization", "Basic %s" % auth)
            response = urlopen(request)
    

