jsonpython-3.xapifor-looplimesurvey

for loop in API call returns same result in each loop


I have written a loop to retrieve data from an API (Limesurvey) based on a list of ids and fill a row of a dataframe with the result of each loop.

I have a list with ids like this:

 # list of ids

 ids = ['1','427',... ,'847']

My code to query the API based on each item of the list looks as follows:

method = "get_participant_properties"
params = OrderedDict([
            ("sSessionKey", api.session_key),
            ("iSurveyID", 12345),
            ("aTokenQueryProperties", t), 
])

# loop through API query with the 'aTokenQueryProperties' stored in the list 'tids'.

attributes = []

for t in ids:
    attributes.append(api.query(method=method, params=params))

pd.DataFrame(attributes)

Unfortunately, the result is a dataframe with 158 rows, and each row is the same, i.e. the query result of the last id in my list (847).


Solution

  • You are not passing in the t from the loop. The t in the params definition is unrelated; if I were to run your code now I'd get a NameError exception because t hasn't been set at that point. The t expression in the params mapping is not live, it is not updated each loop iteration.

    Set the 'aTokenQueryProperties' key in the loop:

    method = "get_participant_properties"
    params = OrderedDict([
                ("sSessionKey", api.session_key),
                ("iSurveyID", 12345),
                ("aTokenQueryProperties", None), 
    ])
    
    attributes = []
    
    for t in ids:
        params["aTokenQueryProperties"] = t
        attributes.append(api.query(method=method, params=params))
    

    Setting "aTokenQueryProperties" to None in the params OrderedDict object at the start is optional; you'd only need to do this if reserving its exact location in the params order is important and even then, because in your example it is the last element in the mapping, you'd end up with the same output anyway.