<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Model My Watershed (MMW) API Demo
Emilio Mayorga, University of Washington, Seattle. 2018-5-10. Demo put together using as a starting point instructions from Azavea  from October 2017.
Introduction
The Model My Watershed API allows you to delineate watersheds and analyze geo-data for watersheds and arbitrary areas. You can read more about the work at WikiWatershed or use the web app.
MMW users can discover their API keys through the user interface, and test the MMW geoprocessing API on either the live or staging apps. An Account page with the API key is available from either app (live or staging). To see it, go to the app, log in, and click on "Account" in the dropdown that appears when you click on your username in the top right. Your key is different between staging and production. For testing with the API and key, go to https
Step1:  MMW staging (test) API Rapid Watershed Delineation (RWD) "watershed" endpoint
Step2:  2. Construct and issue the job request
Parameters passed to the RWD ("watershed") API request. This is a point in Salt Lake City
Step3:  3. Fetch the job result once it's confirmed as done
The job is not completed instantly and the results are not returned directly by the API request that initiated the job. The user must first issue an API request to confirm that the job is complete, then fetch the results. The demo presented here performs automated retries (checks) until the server confirms the job is completed, then requests the JSON results and converts (deserializes) them into a Python dictionary.
Step4:  4. Examine the results
Everything below is just exploration of the results.
Examine the content of the results (as JSON, GeoJSON, and Python dictionaries)
Step5:  The results (result) are made up of two dictionary items
Step6:  watershed
Step7:  Render the geospatial results on an interactive map
<ASSISTANT_TASK:>
Python Code:
import json
import requests
from requests.adapters import HTTPAdapter
from requests.packages.urllib3.util.retry import Retry
def requests_retry_session(
    retries=3,
    backoff_factor=0.3,
    status_forcelist=(500, 502, 504),
    session=None,
):
    session = session or requests.Session()
    retry = Retry(
        total=retries,
        read=retries,
        connect=retries,
        backoff_factor=backoff_factor,
        status_forcelist=status_forcelist,
    )
    adapter = HTTPAdapter(max_retries=retry)
    session.mount('http://', adapter)
    session.mount('https://', adapter)
    return session
s = requests.Session()
APIToken = 'Token YOURTOKEN'  # Replace YOURTOKEN with your actual token string/key
s.headers.update({
    'Authorization': APIToken,
    'Content-Type': 'application/json'
})
Explanation: Model My Watershed (MMW) API Demo
Emilio Mayorga, University of Washington, Seattle. 2018-5-10. Demo put together using as a starting point instructions from Azavea  from October 2017.
Introduction
The Model My Watershed API allows you to delineate watersheds and analyze geo-data for watersheds and arbitrary areas. You can read more about the work at WikiWatershed or use the web app.
MMW users can discover their API keys through the user interface, and test the MMW geoprocessing API on either the live or staging apps. An Account page with the API key is available from either app (live or staging). To see it, go to the app, log in, and click on "Account" in the dropdown that appears when you click on your username in the top right. Your key is different between staging and production. For testing with the API and key, go to https://modelmywatershed.org/api/docs/
The API can be tested from the command line using curl. This example uses the API to test the watershed endpoint:
bash
curl -H "Content-Type: application/json" -H "Authorization: Token YOUR_API_KEY" -X POST 
  -d '{ "location": [39.67185,-75.76743] }' https://modelmywatershed.org/api/watershed/
MMW API: Extract drainage area (watershed) from a point
1. Set up
End of explanation
post_url = 'https://modelmywatershed.org/api/watershed/'
Explanation: MMW staging (test) API Rapid Watershed Delineation (RWD) "watershed" endpoint:
End of explanation
payload = {
    'location': [40.746054, -111.847987], # [latitude, longitude]
    'snappingOn': True, 
    'dataSource': 'nhd'}
json_dat = json.dumps(payload)
post_req = requests_retry_session(session=s).post(post_url, data=json_dat)
json_out = json.loads(post_req.content)
json_out
Explanation: 2. Construct and issue the job request
Parameters passed to the RWD ("watershed") API request. This is a point in Salt Lake City
End of explanation
get_url = 'https://modelmywatershed.org/api/jobs/{job}/'.format
result = ''
while not result:
    get_req = requests_retry_session(session=s).get(get_url(job=json_out['job']))
    result = json.loads(get_req.content)['result']
Explanation: 3. Fetch the job result once it's confirmed as done
The job is not completed instantly and the results are not returned directly by the API request that initiated the job. The user must first issue an API request to confirm that the job is complete, then fetch the results. The demo presented here performs automated retries (checks) until the server confirms the job is completed, then requests the JSON results and converts (deserializes) them into a Python dictionary.
End of explanation
type(result), result.keys()
Explanation: 4. Examine the results
Everything below is just exploration of the results.
Examine the content of the results (as JSON, GeoJSON, and Python dictionaries)
End of explanation
input_pt_geojson = result['input_pt']
input_pt_geojson
Explanation: The results (result) are made up of two dictionary items: input_pt and watershed. Each one of those is a GeoJSON-like object already converted to a Python dictionary.
input_pt:
End of explanation
watershed_geojson = result['watershed']
watershed_geojson.keys(), watershed_geojson['geometry'].keys()
watershed_geojson['properties']
# watershed has just one feature -- a single polygon
print("Number of polygon features: {} \nFeature type: {} \nNumber of vertices in polygon: {}".format(
    len(watershed_geojson['geometry']['coordinates']), 
    watershed_geojson['geometry']['type'], 
    len(watershed_geojson['geometry']['coordinates'][0])
))
Explanation: watershed:
End of explanation
%matplotlib inline
import folium
# Initialize Folium map
m = folium.Map(location=[input_pt_geojson['properties']['Lat'], input_pt_geojson['properties']['Lon']], 
               tiles='CartoDB positron', zoom_start=12)
# Add RWD watershed and drainage point onto map
folium.GeoJson(watershed_geojson).add_to(m);
folium.GeoJson(input_pt_geojson).add_to(m);
m
Explanation: Render the geospatial results on an interactive map
End of explanation
<END_TASK>