So, I’m trying to capture and store wave height data and cache it in a file based on the fetch timestamp in local time.
I have hit an error with the last section.

Here is the error -

    d = sorted(data['hours'], key=lambda i: i['time'])
TypeError: list indices must be integers or slices, not str
I have tried to fix it but I have no idea how to.

Here is the full code -

import requests
import datetime
import calendar
from datetime import datetime as dt
import json

cache_file = 'response.json'
data = []

weekno = datetime.datetime.today().weekday() #to find date
if weekno < 5: #if weekno is weekday then print
 print("Pass")
else: #if weekno is weekend
    print("Attempting to load " + cache_file)
    with open(cache_file, 'r') as f:
        data = json.load(f)
    response = requests.get(
        'https://api.stormglass.io/v2/weather/point', #request from api
          params={
        'lat': 56.35556877325181,
        'lng': -2.8087042045836044,
        'params': 'waveHeight',
      },# params for finding data
      headers={
        'Authorization': ''
      } #auth key for api
      )
    #Save json response as array of dictionaries
    data = response.json()
    print("Writing Json cache to " + cache_file)
    # write data as json array to cache file
    with open(cache_file, 'w') as f:
        json.dump(data,f)

##try:
##    json_data = json.loads(str_json)
##except Exception as e:
##    print('error:', e)


# This has no error handling but if we got to this part
# data is an array of dictionaries with 'hours' and some request tracking
# the hours key is an array of time based objects

# The data seems to be sorted already, but to be sure we sort by time
d = sorted(data['hours'], key=lambda i: i['time'])
print(d[0])
if 'waveHeight' in d[0] and 'dwd' in d[0]['waveHeight'] and d[0]['waveHeight']['dwd'] >= 2.00:
    print('Found')

I apologise for all the random comments, I am a bit messy.

Here is a small exerpt from the API response to give an idea of the layout.

{"hours":[{"time":"2021-06-07T00:00:00+00:00","waveHeight":{"dwd":0.2,"fcoo":0.1,"icon":0.3,"meteo":0.09,"noaa":0.22,"sg":0.1}},{"time":"2021-06-07T01:00:00+00:00","waveHeight":{"dwd":0.19,"fcoo":0.1,"icon":0.3,"meteo":0.08,"noaa":0.2,"sg":0.1}},{"time":"2021-06-07T02:00:00+00:00","waveHeight":{"dwd":0.19,"fcoo":0.09,"icon":0.3,"meteo":0.07,"noaa":0.18,"sg":0.09}},{"time":"2021-06-07T03:00:00+00:00","waveHeight":{"dwd":0.2,"fcoo":0.09,"icon":0.3,"meteo":0.06,"noaa":0.16,"sg":0.09}},

Your comments on lines 41-43 say why you get an error on line 46. The data variable is a list, so data['hours'] is invalid. The error message says what you should already know...lists are indexed with numbers, not strings.

I don't have an authorization key to use for that API, so I can't look at any real data. If you wanted to sort a list of dictionaries, based on the 'hours' field in each dictionary, you don't need an index at all. Use sorted(data, key=lambda i:i['hours']) without the index.

Looking closer, it looks like you are using the variable data for two different purposes. You read the previously cached data into it on line 16, and then replace that with the API response data. That discards the cache file data before you even get a chance to use it. Think about using two different variable names here, like cached_data and response_data or something. Even if you meant to append the response data to the cached file data, it's probably a good idea to first read the response into a separate variable. That gives you an opportunity to check the response data for validity, non-duplication, etc. before adding it to the cached data.

If you know that the the response is going to be a list of dictionaries that's compatible with the list of dictionaries from the cache file, then you can simply append the response data with: data += response.json(). You could try that as a quick-fix, but I still recommend using separate variable names.

commented: Thank You! It works now, I am embarrassed that I didn't notice that sooner... +0
Be a part of the DaniWeb community

We're a friendly, industry-focused community of 1.21 million developers, IT pros, digital marketers, and technology enthusiasts learning and sharing knowledge.