1

Good morning; I'm trying to pull some key values from the URL generated JSON file.

I'm able to pull the JSON from the URL without issues (line 8 is printed for reference)

def get_url():
    api_conditions_url = 'http://magicseaweed.com/api/' + API_KEY + '/forecast/?spot_id=' + PUTSBOROUGH_SPOT_ID
    print('Collecting data from - ' + api_conditions_url)
    try:
        f = urlopen(api_conditions_url)
    except:
        return []
    json_currently = f.read()
    print(json_currently)
    f.close()
    return json.loads(json_currently)

def main():
    curr_conditions = get_url()
    if ("absMinBreakingHeight" not in curr_conditions["swell"]):
        print ("Error #001 JSON call failed, check your query is correct!]\n")
        exit()
    else:
        print('it worked')

if __name__ == "__main__":
    main()

The JSON file looks like the below:


{  
      "timestamp":1564617600,
      "localTimestamp":1564617600,
      "issueTimestamp":1564617600,
      "fadedRating":0,
      "solidRating":0,
      "swell":{  
         "absMinBreakingHeight":1.3,
         "absMaxBreakingHeight":2.03,
         "probability":100,
         "unit":"ft",
         "minBreakingHeight":1,
         "maxBreakingHeight":2,
         "components":{  
            "combined":{  
               "height":3,
               "period":6,
               "direction":75.97,
               "compassDirection":"WSW"
            },
            "primary":{  
               "height":2.5,
               "period":6,
               "direction":65.06,
               "compassDirection":"WSW"
            },
            "secondary":{  
               "height":1.1,
               "period":6,
               "direction":160.71,
               "compassDirection":"NNW"
            }
         }
      },
      "wind":{  
         "speed":5,
         "direction":127,
         "compassDirection":"NW",
         "chill":60,
         "gusts":6,
         "unit":"mph"
      },
      "condition":{  
         "pressure":1017,
         "temperature":61,
         "weather":"10",
         "unitPressure":"mb",
         "unit":"f"
      },
      "charts":{  
         "swell":"https:\/\/charts-s3.msw.ms\/archive\/wave\/750\/1-1564617600-1.gif",
         "period":"https:\/\/charts-s3.msw.ms\/archive\/wave\/750\/1-1564617600-2.gif",
         "wind":"https:\/\/charts-s3.msw.ms\/archive\/gfs\/750\/1-1564617600-4.gif",
         "pressure":"https:\/\/charts-s3.msw.ms\/archive\/gfs\/750\/1-1564617600-3.gif",
         "sst":"https:\/\/charts-s3.msw.ms\/archive\/sst\/750\/1-1564617600-10.gif"
      }
   },

I receive the following error when trying to parse the JSON file -

if ("absMinBreakingHeight" not in curr_conditions["swell"]):

TypeError: list indices must be integers or slices, not str"

9
  • Looks like curr_conditions is a list and you only showed us part of it. Commented Aug 1, 2019 at 9:33
  • 3
    Is it possible that f = urlopen(api_conditions_url) in your try and except block fails and the get_url function returns an empty list? Commented Aug 1, 2019 at 9:34
  • @AlexHall - How do I change this from a list to something I can call. I used the same code to pull a different JSON file without issues. I've compared the two JSON files, and look the same. Commented Aug 1, 2019 at 9:35
  • 2
    Please share the full JSON Commented Aug 1, 2019 at 9:35
  • 1
    I think your json might be list of dicts i.e. [{}, {}] and you might need to iterate over it and check. i.e.curr_conditions[0]["swell"] Commented Aug 1, 2019 at 9:36

3 Answers 3

3

Got it. The JSON is a list of dicts (see below)
See https://magicseaweed.com/developer/forecast-api

You’ll receive a JSON array consisting of a series of data representing the forecast for specific timeframes, looking like this:

So you code should do a for loop over it.

for forecast in forecasts:
    # your logic goes here

JSON

[{
timestamp: 1366902000,
localTimestamp: 1366902000,
issueTimestamp: 1366848000,
fadedRating: 0,
solidRating: 0,
swell: {
    minBreakingHeight: 1,
    absMinBreakingHeight: 1.06,
    maxBreakingHeight: 2,
    absMaxBreakingHeight: 1.66,
    unit: "ft",
    components: {
         combined: {
         height: 1.1,
         period: 14,
         direction: 93.25,
         compassDirection: "W"
    },
    primary: {
         height: 1,
         period: 7,
         direction: 83.37,
         compassDirection: "W"
    },
    secondary: {
         height: 0.4,
         period: 9,
         direction: 92.32,
         compassDirection: "W"
    },
    tertiary: {
         height: 0.3,
         period: 13,
         direction: 94.47,
         compassDirection: "W"
     }
     }
},
wind: {
     speed: 10,
     direction: 85,
     compassDirection: "W",
     chill: 15,
     gusts: 13,
     unit: "mph"
},
condition: {
     pressure: 1020,
     temperature: 18,
     unitPressure: "mb",
     unit: "c"
},
charts: {
    swell: "http://cdn.magicseaweed.com/wave/750/1-1366902000-1.gif",
    period: "http://cdn.magicseaweed.com/wave/750/1-1366902000-2.gif",
    wind: "http://cdn.magicseaweed.com/gfs/750/1-1366902000-4.gif",
    pressure: "http://cdn.magicseaweed.com/gfs/750/1-1366902000-3.gif",
    sst: "http://cdn.magicseaweed.com/sst/750/1-1366902000-10.gif"
}
}]
Sign up to request clarification or add additional context in comments.

Comments

0

You must convert string to dict, change your main function like this.

import ast 

def main():
    curr_conditions = get_url()
    curr_conditions = ast.literal_eval(curr_conditions) # add this sentence
    if ("absMinBreakingHeight" not in curr_conditions["swell"]):
        print ("Error #001 JSON call failed, check your query is correct!]\n")
        exit()
    else:
        print('it worked')





Comments

-1

Thanks to all for their input. I tried all the methods and all were correct - The JSON was a list of dict's. Applying a "[0]" to section "" curr_conditions[0]["swell"]) "" allowed me to pull the value from the JSON.

def get_url():
    api_conditions_url = 'http://magicseaweed.com/api/' + API_KEY + '/forecast/?spot_id=' + PUTSBOROUGH_SPOT_ID
    print('Collecting data from - ' + api_conditions_url)
    try:
        f = urlopen(api_conditions_url)
    except:
        return []
    json_currently = f.read()
    print(f)
    f.close()
    return json.loads(json_currently)

def main():
    curr_conditions = get_url()
    if ("absMinBreakingHeight" not in curr_conditions[0]["swell"]):
        print ("Error #001 JSON call failed, check your query is correct!]\n")
        exit()
    else:
        print(curr_conditions[0]["swell"]["absMinBreakingHeight"])

if __name__ == "__main__":
    main()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.