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.
https://bison.usgs.gov/api/search.json?species=Bison bison&type=scientific_name&start=0&count=1
#First, import the wonderful requests module
import requests
# Construct the service URL as two components: the service URL and the request parameters
url = 'http://bison.usgs.gov/api/search.json'
params = {'species':'Bison bison',
'type':'scientific_name',
'start':'0',
'count':'500'
}
requests.get()
function to send our request off to the server at the address provided, storing the servers response as a variable called response
.#Send the request to the server and store the response as a variable
response = requests.get(url,params)
#View the reponse in text format
response.text
Yikes, that's much less readable than the NWIS output!
Well, that's because the response from the BISON server is in JSON format. JSON, short for JavaScript Object Notation, is a text document that stores information in key
:value
pairs, much like a Python dictionary. Still, it's a raw text object, but one that we convert into a Python dictionary using Python's json package.
#Import the module
import json
#Convert the response
data = json.loads(response.text)
type(data)
Note: we could also convert this to JSON using the
json
function of theresponse
object...
The code below has the exact same results as the one above.
data=response.json()
type(data)
#List the keys in the returned JSON object
data.keys()
#Show the value associated with the `data` key
data['data']
#Display the first "data" value
data['data'][0]
decimalLatitude
item value...#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 generated from the JSON response to our API request. (Phew!)
#Loop thorough each observation and print the lat and long values
for observation in data['data']:
print (observation['decimalLatitude'],observation['decimalLongitude'])
► If the above throws an error, can you debug it? HINT: the geo
tag indicates whether coordinate info exist for the record...
Pandas can create a "data frame" from dictionary values. We'll talk about this soon, but can be quite useful!
import pandas as pd
df = pd.DataFrame(data['data'])
df.head()
And Pandas allows us to do some nifty analyses, including subsetting records for a specific provider.
#Generate a list of providers
df.provider.unique()
df.query("provider == 'Denver Museum of Nature & Science'")
University of Kansas Biodiversity Institute
?