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
print(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 requests
's json()
function to convert the servers response into a Python dictionary.
#Convert the response
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'])
#Loop thorough each observation and print the lat and long values
for observation in data['data']:
if(observation['geo'] == 'Yes'):
print (observation['decimalLatitude'],observation['decimalLongitude'])
#Loop thorough each observation and print the lat and long values
for observation in data['data']:
if(observation['geo'] == 'Yes'):
print (observation['decimalLatitude'],observation['decimalLongitude'])
Pandas can create a dataframe directly from dictionary values.
import pandas as pd
df = pd.DataFrame(data['data'])
df.head()
So now we can use our Panda's know-how to do some nifty analyses, including subsetting records for a specific provider.
#Generate a list of providers
df.provider.unique()
df.query("provider == 'iNaturalist.org'")
df.dtypes
University of Kansas Biodiversity Institute
?