mlabenski
mlabenski

Reputation: 33

Using Flask as an API to filter a dictionary

I have converted a dataframe to a dictionary so I can implement an API through flask. I'm struggling to append the column name to every index in the dictionary and therefore cannot run the code:

@app.route('/api/v1/resources/names', methods=['GET'])
def api_name():
    if 'name' in request.args:
        name = str(request.args['name'])
    else:
        return "Error: No name was provided, Please specify a first and last name"
    results = []

    for index['Name] in main_data:
        if (index == name):
            results.append(index)
    results = str(results)
    return jsonify(results)

And when I attempt to call the API

http://127.0.0.1:5000/api/v1/resources/names?name=John%20Doe
TypeError: string indices must be integers

I figured that is due to my dictionary not having any column headers, I wish to convert the dictionary from

{
  "John Doe": {
    "2020-09-01": "4:00PM", 
    "2020-09-03": "8:00AM", 
    "2020-09-04": "2:00PM", 
    "2020-09-14": "8:00AM", 
    "2020-09-16": "6:00PM", 
    "2020-09-22": "5:00PM", 
    "2020-09-23": "2:00PM", 
    "2020-09-25": "1:00PM", 
    "2020-09-30": "5:00PM", 
    "2020-10-01": "8:00PM", 
    "2020-10-05": "5:00PM", 
    "2020-10-08": "1:00PM", 
    "2020-10-09": "5:00PM", 
    "2020-10-10": "4:00PM", 
    "2020-10-12": "5:00PM", 
    "2020-10-14": "7:00PM"
  }, 
  "Firstname Lastname": {
    "2020-08-20": "11:00AM", 
    "2020-08-21": "10:00AM", 
    "2020-08-22": "10:00AM", 
    "2020-08-23": "11:00AM", 
    "2020-08-24": "10:00AM", 
    "2020-08-25": "11:00AM", 
    "2020-08-26": "2:00PM", 
    "2020-08-27": "4:00PM", 
    "2020-08-28": "2:00PM", 
    "2020-08-29": "1:00PM"
  }
}

to:

{Name: "John Doe": {Date: "2020-09-01": Time:"4:00PM" }}

The code I used in pandas to initally convert the dataframe to a dictionary looks like this

def buildDictionary():
    main_data = pd.read_csv('output.csv', delimiter=",", encoding='cp1252')
    nameDictionary = (main_data.groupby('Name')
       .apply(lambda x: dict(zip(x['Date'],x['Time'])))
       .to_dict())
    return nameDictionary

Here is some of the csv data aswell

Name    Time    Date
FName LName 12:00PM     10/5/20
FName LName 12:00PM     10/5/20
FName LName 12:00PM     10/5/20
FName LName 12:00PM     10/5/20
FName LName 12:00PM     10/5/20
FName LName 12:00PM     10/5/20
FName LName 12:00PM     10/5/20

I'd like for it to return

  "John Doe": {
    "2020-09-01": "4:00PM", 
    "2020-09-03": "8:00AM", 
    "2020-09-04": "2:00PM", 
    "2020-09-14": "8:00AM", 
    "2020-09-16": "6:00PM", 
    "2020-09-22": "5:00PM", 
    "2020-09-23": "2:00PM", 
    "2020-09-25": "1:00PM", 
    "2020-09-30": "5:00PM", 
    "2020-10-01": "8:00PM", 
    "2020-10-05": "5:00PM", 
    "2020-10-08": "1:00PM", 
    "2020-10-09": "5:00PM", 
    "2020-10-10": "4:00PM", 
    "2020-10-12": "5:00PM", 
    "2020-10-14": "7:00PM"
  } 

but in order to do that, i need to index every column in the dictionary.

Upvotes: 0

Views: 413

Answers (1)

Jasmijn
Jasmijn

Reputation: 10462

This should do the trick:

@app.route('/api/v1/resources/names', methods=['GET'])
def api_name():
    if 'name' in request.args:
        name = str(request.args['name'])
    else:
        return "Error: No name was provided, Please specify a first and last name"

    return jsonify({name: main_data[name]})

The reason why you got that error is that that for-loop is equivalent to:

for key in main_data.keys(): #looping over a dict is equivalent to looping over its keys
    index['Name'] = key
    if index == name:
        results.append(index)

... and apparently you have a global variable named index that is a string somewhere.

If you fixed that, you would get:

for key in main_data():
    if key == name:
        results.append(key)

... which is the same as doing:

results = [name]

... which you then convert to a string, and serialize that string to JSON, which means that your request would return "['John Doe']" (the quote characters included!)

Upvotes: 1

Related Questions