Search code examples
pythonjsonpython-3.xpython-requestsgetjson

Simplify a streamed request.get and JSON response decode


I have been working on some code that will grab emergency incident information from a service called PulsePoint. It works with software built into computer controlled dispatch centers.

This is an app that empowers citizen heroes that are CPR trained to help before a first resonder arrives on scene. I'm merely using it to get other emergency incidents.

I reversed-engineered there app as they have no documentation on how to make your own requests. Because of this i have knowingly left in the api key and auth info because its in plain text in the Android manifest file.

I will definitely make a python module eventually for interfacing with this service, for now its just messy.

Anyhow, sorry for that long boring intro.

My real question is, how can i simplify this function so that it looks and runs a bit cleaner in making a timed request and returning a json object that can be used through subscripts?

import requests, time, json
def getjsonobject(agency):
    startsecond = time.strftime("%S")
    url = REDACTED
    body = []
    currentagency = requests.get(url=url, verify=False, stream=True, auth=requests.auth.HTTPBasicAuth(REDACTED, REDCATED), timeout = 13)
    for chunk in currentagency.iter_content(1024):
        body.append(chunk)
        if(int(startsecond) + 5 < int(time.strftime("%S"))): #Shitty internet proof, with timeout above
            raise Exception("Server sent to much data")
    jsonstringforagency = str(b''.join(body))[2:][:-1] #Removes charecters that define the response body so that the next line doesnt error
    currentagencyjson = json.loads(jsonstringforagency) #Loads response as decodable JSON
    return currentagencyjson

currentincidents = getjsonobject("lafdw")
for inci in currentincidents["incidents"]["active"]:
    print(inci["FullDisplayAddress"])

Solution

  • Requests handles acquiring the body data, checking for json, and parsing the json for you automatically, and since you're giving the timeout arg I don't think you need separate timeout handling. Request also handles constructing the URL for get requests, so you can put your query information into a dictionary, which is much nicer. Combining those changes and removing unused imports gives you this:

    import requests
    
    params = dict(both=1,
                  minimal=1,
                  apikey=REDACTED)
    
    url = REDACTED
    
    def getjsonobject(agency):
        myParams = dict(params, agency=agency)
        return requests.get(url, verify=False, params=myParams, stream=True,
                auth=requests.auth.HTTPBasicAuth(REDACTED, REDACTED),
                timeout = 13).json()
    

    Which gives the same output for me.