Swantewit
Swantewit

Reputation: 1076

String indices must be integers in api wrapping in Python

I am trying to wrap the weather api from https://www.visualcrossing.com/ to get humidity and temperature for the exact hour, based on this query: https://weather.visualcrossing.com/VisualCrossingWebServices/rest/services/timeline/Poborka%20Wielka%2C%20Poland/2022-09-03/2022-09-03?unitGroup=metric&key=YourKey&contentType=json

The JSON I get back looks like this: https://jsfiddle.net/KubaHKM/veg7bfpt/2/

To get humidity and temperature for the exact hour I tried to approach it that way:

def generate_response(place, day, hour):

    ctx = {
        "date": day,
        "hour": hour,
        "temperature": 0,
        "humidity": 0
    }

    response = wr.get_weather_report(place, day)

    try:
        for hours in response["days"]:
            for h in hours:
                if h["datetime"] == hour:
                    ctx["finalResponse"].append({
                        "hour": h["datetime"],
                        "temperature": h["temp"],
                        "humidity": h["humidity"]
                    })
                else:
                    pass
    except (KeyError, IndexError) as e:
        print(e)
    ctx["msg"] = {
        "type": "error",
        "content": "Cloud connection error"
        }

    print (ctx)

where wr.get.weather is a function passing the arguments and parameters to a request and calling the API.

As mentioned in the title, I get: TypeError: string indices must be integers on line: if h["datetime"] == hour:

I know what the error is about but I really don't know how to push the solution closer to what I need, since the debugger shows that hours value is my JSONs value, so the thing that I needed. I would really much appreciate your help in understanding how to get to the exact data I need.

Upvotes: 0

Views: 46

Answers (1)

J_H
J_H

Reputation: 20550

You wrote

> def generate_response(place, day, hour):

but you might equivalently have said

> def generate_response(place: str, day: str, hour: str):

That is, the initial line of the function could safely

        assert isinstance(hour, str)

Later you create a dictionary:

                   ... {
                        "hour": hour["datetime"],
                        "temperature": hour["temp"],
                        "humidity": hour["humidity"]
                    } ...

That's three hour[foo] expressions. But hour is a str rather than a dict. You might try subscripting hours[foo], but it seems much more likely that you intended h[foo] in those three spots.


I know what the error is about ...

From what you wrote, it isn't clear to me that you know what it's about.

We can talk about integer subscript 'abc'[1], but not 'abc'['def']. You typically would need to be dereferencing a dict for the string subscript to work.

You mentioned an if hour['datetime'] == hour statement, but the posted code does not contain that statement.

tl;dr: Looks like a typo / syntax issue.

EDIT

Let's define a dictionary d, containing integer values. We can dereference it using any of its keys.

Notice that dereferencing it with integer subscripts won't work. Such subscripts will work fine on other containers, such as a str or a list.

>>> d = dict(abcd=1, efgh=5, ijkl=9)
>>> d
{'abcd': 1, 'efgh': 5, 'ijkl': 9}
>>> 
>>> list(d.values())
[1, 5, 9]
>>> 
>>> list(d.keys())
['abcd', 'efgh', 'ijkl']
>>>
>>> d[1]  # fail!
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 1
>>>  
>>> d['abcd']
1
>>> d['efgh']
5
>>>
>>>
>>> 'abcd'[2]
'c'
>>>
>>> list(d.values())[2]
9

Upvotes: 1

Related Questions