How to fetch JSON data from API, format / encode / write to a file?
Question: I need to fetch some data from a weather API, extract certain info and send it
to std. output (in my case this is the console/terminal; I am playing around
with python API scripting and do not yet have a web site/app do show fetched
data).

**Example Python code from the API provider (simple to understand and
works):**

    
    
    import urllib2
    import json
    
    API_KEY='mysuperawesomekey'
    
    
    f = urllib2.urlopen('http://api.wunderground.com/api/' + API_KEY + '/geolookup/conditions/q/IA/Cedar_Rapids.json')
    
    json_string = f.read()
    parsed_json = json.loads(json_string)
    location = parsed_json['location']['city']
    temp_f = parsed_json['current_observation']['temp_f']
    
    print "Current temperature in %s is: %s" % (location, temp_f)
    
    f.close()
    

Since I am on a free plan, I don't want to use up my API requests but rather
fetch the JSON data, save it to a file and use in another script to practice.
I found a couple of solutions here on
[StackOverflow](http://stackoverflow.com/questions/12309269/how-do-i-write-
json-data-to-a-file-in-python) but neither seem to work completely (nice
formatting of the file):

**Attempt 1. to save the fetched data, add. to the orig. code above:**

    
    
    import io
    import codecs
    
    with open('data.json', 'w') as outfile:
    json.dump(json_string, outfile, indent=4, sort_keys=True, separators=(",", ':'))
    

**Attempt 2:**

    
    
    with codecs.open('data.json', 'w', 'utf8') as jasonfile:
      jasonfile.write(json.dumps(parsed_json, sort_keys = True, ensure_ascii=False))
    

Both of my attempts work ("kind of") as I do get a **.json** file. But, upon
inspecting it in my editor (Atom) I am seeing this (first few soft-break
lines):

**Output:**

    
    
    "\n{\n  \"response\": {\n  \"version\":\"0.1\",\n\"termsofService\":\"http://www.wunderground.com/weather/api/d/terms.html\",\n  \"features\": {\n  \"geolookup\": 1\n  ,\n  \"conditions\": 1\n  }\n\t}\n\t\t,\t\"location\": {\n\t\t\"type\":\"CITY\",\n\t\t\"country\":\"US\",\n\t\t\"country_iso3166\":\"US\",\n\t\t\"country_name\":\"USA\",\n\t\t\"state\":\"IA\",\n\t\t\"city\":\"Cedar Rapids\",\n\t\t\"tz_short\":\"CDT\",\n\t\t\"tz_long\":\"America/Chicago\",\n\t\t\"lat\":\"41.97171021\",\n\t\t\"lon\":\"-91.65871429\",\n\t\t\"zip\":\...
    

It is all on one line, with newlines and tabs showing. I have a couple of
questions:

  1. How can I check what format / kind of data-type API is returning? (FOr example is it just a raw string which needs to be JSON-iffied?)
  2. Is my JSON not written in a human readable format because of encoding, delimiters fault?
  3. Line `json_string = f.read()` from example code seems to "mimic" working with a "real" internal file object, is this correct?

Many thanks!


Answer: Seems that it was quite a simple solution. In my original code, I was saving a
"non-parsed" variable to a file:

    
    
    import urllib2
    import json
    
    API_KEY='key'
    
    f = urllib2.urlopen('http://api.wunderground.com/api/' 
    + API_KEY + '/geolookup/conditions/q/IA/Cedar_Rapids.json')
    
    # Saving the below variable into a .json file gives all the JSON data
    # on a single line
    json_string = f.read()
    
    with open('data.json', 'w') as outfile:
        json.dump(json_string, outfile, indent=4, sort_keys=True, separators=(",", ':'))
    

which, of course, resulted in a file with JSON data on a single line. What I
should have been doing is saving the **parsed** variable:

    
    
    import urllib2
    import json
    
    API_KEY='key'
    
    f = urllib2.urlopen('http://api.wunderground.com/api/' + API_KEY + '/geolookup/conditions/q/IA/Cedar_Rapids.json')
    
    json_string = f.read()
    
    # THIS one is correct!
    parsed_json = json.loads(json_string)
    
    with open('data.json', 'w') as outfile:
      json.dump(parsed_json, outfile, indent=4, sort_keys=True, separators=(",", ':'))
    

