Search code examples
pythonurllibput

TypeError: POST data should be bytes, an iterable of bytes, or a file object. It cannot be of type str while trying to pass PUT request in python


I am trying to pass a list of dictionaries(strings) to a for a put request. I am getting this error:

TypeError: POST data should be bytes, an iterable of bytes.

Is this the right way to make a put request with list of dictionaries(strings) in python.

list looks like the following:

list1 = ['{"id" : "","email" : "[email protected]","fullName": "John Lorang"}', '{"id" : "","email" : "[email protected]","fullName": "Lola Dsilva"}']


myData = json.dumps(list1)
myRestRequestObj = urllib.request.Request(url,myData)
myRestRequestObj.add_header('Content-Type','application/json')
myRestRequestObj.add_header('Authorization','Basic %s')
myRestRequestObj.get_method = lambda : 'PUT'
try:
  myRestRequestResponse = urllib.request.urlopen(myRestRequestObj)
except urllib.error.URLError as e:
        print(e.reason)

Solution

  • As you said in a comment, you cannot use requests (that's pretty sad to hear!), so I did another snippet using urllib (the short answer: you must .encode('utf-8') json.dumps and decode('utf-8') response.read()):

    import urllib.request
    import urllib.error
    import json
    
    url = 'http://httpbin.org/put'
    token = 'jwtToken'
    
    list1 = ['{"id" : "","email" : "[email protected]","fullName": "John Lorang"}', '{"id" : "","email" : "[email protected]","fullName": "Lola Dsilva"}']
    
    # Request needs bytes, so we have to encode it
    params = json.dumps(list1).encode('utf-8')
    headers = {
        'Content-Type': 'application/json',
        'Authorization': 'Basic {token}'.format(token=token)
    }
    
    # Let's try to create our request with data, headers and method
    try:
        request = urllib.request.Request(url, data=params, headers=headers, method='PUT')
    except urllib.error.URLError as e:
        # Unable to create our request, here the reason
        print("Unable to create youro request: {error}".format(error=str(e)))
    else:
        # We did create our request, let's try to use it
        try:
            response = urllib.request.urlopen(request)
        except urllib.error.HTTPError as e:
            # An HTTP error occured, here the reason
            print("HTTP Error: {error}".format(error=str(e)))
        except Exception as e:
            # We got another reason, here the reason
            print("An error occured while trying to put {url}: {error}".format(
                url=url,
                error=str(e)
            ))
        else:
            # We are printing the result
            # We must decode it because response.read() returns a bytes string
            print(response.read().decode('utf-8'))
    

    I did try to add some comments. I hope this solution help you!

    To help you learn a better way to learn python, you should read the Style Guide for Python Code