0

I'm writing a small Python 2.x app which grabs images from URLs, converts them to base64, then submits them using requests to an API server as parameters of a POST request. My admittedly amateurish code is as follows:

import csv
import json
import requests
import base64
import getpass

f = raw_input("Enter CSV filename: ")
global clientCode
clientCode = raw_input("Enter customer code: ")
username = raw_input("Enter username: ")
password = getpass.getpass("Enter password: ")
global url
url = "https://" + clientCode + ".redacted.com/api"

def getSessionKey():
    querystring = {"request":"verifyUser","username":username,"password":password,"clientCode":clientCode}
    response = requests.request("GET", url, params=querystring, timeout=10)
    jr = json.loads(response.text)
    # print(response.text) 
    global sessionKey
    sessionKey = jr['records'][0]['sessionKey']
    errorCode =  jr['status']['errorCode']

with open(f, 'rb') as myfile:
    reader = csv.reader(myfile)
    rownum = 0
    getSessionKey()
    for row in reader:
        productID = row[0]
        imageURL = row[1]
        dlimage = requests.get(imageURL, stream=True, timeout=10)
        encodedImage = base64.encodestring(dlimage.content)
        imagequery = {'clientCode':clientCode,'sessionKey':sessionKey,'request':'saveProductPicture','productID':productID,'picture':encodedImage}
        response = requests.post(url, data=imagequery, timeout=10)
        print response.status_code
        ir = json.loads(response.text)
        errorCode =  ir['status']['errorCode']
        print errorCode
        rownum = rownum + 1

Now, if I change the response line to response = requests.get(url, params=imagequery, timeout=10), it works. But since this is a GET request, the server throws an HTTP 414 error for any images larger than about 1kb. If I run the code as above, the API server gives an error which indicates it's not seeing the clientCode parameter, so it would stand to reason that it's not seeing any of the data. What am I doing wrong?

Thanks for helping me learn by doing.

  • What encoding does the server use for the data? By default, requests uses form-encoded data - maybe it requires something else, e.g. json instead? – Penguin Brian Mar 08 '17 at 04:01
  • I tried headers specifying both form-encoded and json, both gave the same result. Which is to say the server couldn't see the clientCode parameter. – Geoff Evans Mar 08 '17 at 04:04
  • Do you have docs for this API? What is the exact error you're getting? Hard to help you debug a problem about API use when we have no idea whether you're using the API correctly., – pvg Mar 08 '17 at 04:04
  • unrelated but you also don't need all that `global` abuse, that's not what it means in python. Take a look at http://stackoverflow.com/questions/4693120/use-of-global-keyword-in-python – pvg Mar 08 '17 at 04:09
  • Thanks for the tip about globals. I'll review them once I've got the core functionality working. – Geoff Evans Mar 08 '17 at 04:14
  • As for the API documentation, I do have access to it, but it's very lean. I'd prefer not to share it, since I don't want our company devs showing up and making fun of me or something. The error code I'm getting is 1001, which means clientCode not found. – Geoff Evans Mar 08 '17 at 04:16
  • You can just delete every line that says 'global'. Beyond that, I'm afraid it's hard to tell what you're doing wrong with a completely unknown API. We wouldn't be helping, we'd be guessing. – pvg Mar 08 '17 at 04:18
  • Is there a way I can get the app to output the POST request onscreen? I bet I can figure out what's wrong if I can see what it's sending. – Geoff Evans Mar 08 '17 at 04:30

1 Answers1

0

I'm still not sure why requests was behaving the way it was, but I rewrote the code to use httplib instead, and it works.