The USGS provides an API for accessing species observation data. https://bison.usgs.gov/doc/api.jsp
This API is much better documented than the NWIS API and we'll use it to dig a bit deeper into how the requests package can faciliate data access via APIs.
We'll begin by replicating the example API call they show on their web page:
https://bison.usgs.gov/api/search.json?species=Bison bison&type=scientific_name&start=0&count=1
In [ ]:
#First, import the wonderful requests module
import requests
In [ ]:
#Now, we'll deconstruct the example URL into the service URL and parameters, saving the paramters as a dictionary
url = 'http://bison.usgs.gov/api/search.json'
params = {'species':'Bison bison',
'type':'scientific_name',
'start':'0',
'count':'10'
}
In [ ]:
response = requests.get(url,params)
print(response.content)
Yikes, that's much less readable than the NWIS output!
Well, that's because the response from the BISON server is in JSON format. We can use Python's build in json module to convert this raw JSON text to a handy dictionary (of dictionaries) that we can [somewhat] easily manipulate...
In [ ]:
#Import the module
import json
#Convert the response
data = json.loads(response.content)
type(data)
In [ ]:
#Ok, if it's a dictionary, what are it's keys?
data.keys()
In [ ]:
#What are the values of the 'data' key
data['data']
In [ ]:
#Oh, it's a list of occurrences! Let's examine the first one
data['data'][0]
#We see it's a dictionary too
In [ ]:
#We can get the latitude of the record from it's `decimalLatitude` key
data['data'][0]['decimalLatitude']
So we see the Bison observations are stored as list of dictionaries which are accessed within the data key in the results dictionary genrated from the JSON response to our API request. (Phew!)
With a bit more code we can loop through all the data records and print out the lat and long coordinates...
In [ ]:
#Loop thorough each observation and print the lat and long values
for observation in data['data']:
print observation['decimalLatitude'],observation['decimalLongitude']
Or we can witness Pandas cleverness again! Here, we convert the collection of observations into a data frame
In [ ]:
import pandas as pd
df = pd.DataFrame(data['data'])
df.head()
And Pandas allows us to do some nifty analyses, including subsetting records where the provider is 'iNaturalist.org'
In [ ]:
df[df.provider == 'iNaturalist.org']