WikiWatershed / model-my-watershed

The web application front end for Model My Watershed.
https://modelmywatershed.org
Apache License 2.0
57 stars 31 forks source link

Reword API Documentation to Clarify Inclusion of "Token" in Authorization Header #3380

Open SRGDamia1 opened 3 years ago

SRGDamia1 commented 3 years ago

I'm attempting to delineate watersheds using the API end point and I'm getting an error "Authentication credentials were not provided."

I'm grabbing my account token from the ModelMW account settings page and using that in the "Authorization" header.

I'm using requests in python

import requests
mmw_api_key =  "myKeyHere"
auth_header = {"Authorization": mmw_api_key}
payload = {
    "location": [lat, long],
    "snappingOn": True,
    "simplify": 0,
    "dataSource": "drb",  # use either 'drb' or 'nhd'
}
r = requests.post(
        "https://modelmywatershed.org/api/watershed/", headers=auth_header, data=payload
)

I get the same result in Postman.

I can get data using the swagger interactive documentation if I use the Django login but not if I only use the token.

rajadain commented 3 years ago

As it says in the documentation, you have to prefix the "Authorization" header's value with the word "Token".

So the following works for me:

>>> import requests
>>> MMW_API_KEY = 'XXX'
>>> TEST_LOCATION = [39.67185, -75.76742]
>>> payload = { 'location': TEST_LOCATION, 'snappingOn': True, 'simplify': 0, 'dataSource': 'drb' }
>>> headers = { 'Authorization': f'Token {MMW_API_KEY}' }
>>> res = requests.post('https://modelmywatershed.org/api/watershed/', headers=headers, json=payload)
>>> res.json()
{'status': 'started', 'job': 'cba11838-cea2-4108-af64-1289a8505a5f'}

These instructions appear in the introductory paragraph of the API Docs:

image

https://github.com/WikiWatershed/model-my-watershed/blob/19626d37d99ea480ec48857ce07b8291592202ae/src/mmw/mmw/settings/base.py#L325

And also in the popup Authorization dialog:

image

https://github.com/WikiWatershed/model-my-watershed/blob/19626d37d99ea480ec48857ce07b8291592202ae/src/mmw/mmw/settings/base.py#L342-L350

If you have any recommendations for improving this documentation and making this clearer, please offer suggestions and we will incorporate them.

SRGDamia1 commented 3 years ago

I'm sorry, I did not follow that bit at all. Re-reading it after you explained it I understand, but I definitely didn't get it right the first time. Doh. I'll try to think of something clearer.

I did manage to get everything I wanted just fine using the Django log-in flow from python/requests. Doing it that way, I also was able to access the modeling endpoint and start and get results from GWLF-E. It's pretty amazing. I started with a list of 100+ lat/longs and was able to delineate a watershed from them, get all kinds of analytical data, and run models on all of them. Adding in delays to let each finish in turn and not overload the system it took a few hours for it to all run, but given all the work happening, it's pretty mind-boggling.

aufdenkampe commented 3 years ago

@SRGDamia1 & @rajadain, perhaps a good way forward might be to linked to and improve the Jupyter Notebook examples using our API that @emiliom developed and shared in https://github.com/WikiWatershed/model-my-watershed/tree/develop/doc.

@SRGDamia1, perhaps you could add to or improve on those example notebooks?

@rajadain, perhaps you could add links to these example notebooks in the intro paragraphs of https://modelmywatershed.org/api/docs/?

SRGDamia1 commented 3 years ago

@aufdenkampe I didn't use the Jupyter notebooks at all.

skp703 commented 2 years ago

I had the same issue. It works with Token keyword. The curl command generated by the webpage at https://modelmywatershed.org/api/docs/ doesn't have token keyword in it.

image

It gave me: curl -X POST "https://modelmywatershed.org/api/watershed/" -H "accept: application/json" -H "Authorization: dummytoken" -H "Content-Type: application/json" -H "X-CSRFToken: AGZ6r1ghSkfRa08QJwfeYqTbunwxR3X7YJw57IKfUja4PkWUCje2MH0tSNruA8G5" -d "{ \"location\": [ 39.67185812402583, -75.76742706298828 ], \"snappingOn\": true, \"simplify\": 0.0001, \"dataSource\": \"drb\"}"

skp703 commented 2 years ago

Also it may be useful to have the server return a 401 instead of 403. 403 Error code threw me off, https://stackoverflow.com/questions/3297048/403-forbidden-vs-401-unauthorized-http-responses

just a suggestion :). Works for me now.

rajadain commented 2 years ago

Hi Saurav, thanks for pointing out the 401 vs 403 distinction. I'll look into that.

For the API documentation, if you paste in "Token xyz" in the box as instructed, you get correctly generated curl requests:

image

image

aufdenkampe commented 2 years ago

@skp703, thanks for posting your experience and suggestion! I'm glad things are now working for you.

@rajadain, thanks for the quick response!