How to Run a Job Using Alteryx Server API and Python
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Notify Moderator
I'm really struggling to figure out how to make this work. I can successfully get my job to fire off using the interactive API documentation, but when it comes to putting it in a python script I can't get it to work. I keep getting 400 errors. Below is my code:
import requests
import json
#URL provided by interactive API documentation with id and key removed for online question
URL = 'http://dminform:80/gallery/api/v1/workflows/<id>/jobs/?oauth_timestamp=1539784724&oauth_signature_method=HMAC-SHA1&oauth_consumer_key=<Key>&oauth_version=1.0&oauth_nonce=7Ck8g&oauth_signature=TC1bpIecwPsMPO2Ui1l5O%2FwEhzU%3D'
#Response body provided by interactive API documentation
responseBody = {
"id": "<id>",
"appId": None,
"createDate": "2018-10-17T13:58:43.9759132Z",
"status": "Queued",
"disposition": "None",
"outputs": [],
"messages": [],
"priority": 0,
"workerTag": None
}
#Response header provided by interactive API documentation
responseHeaders = {
"Access-Control-Allow-Origin": "*",
"Date": "Wed, 17 Oct 2018 13:58:43 GMT",
"Access-Control-Max-Age": "1728000",
"Access-Control-Allow-Headers": "Content-Type, Accept, Authorization",
"Transfer-Encoding": "chunked",
"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
"Content-Type": "application/json"
}
r = requests.post(url = URL)
# r = requests.post(url = URL, headers = responseHeaders, data = json.dumps(responseBody))
# r = requests.post(url = URL, headers = responseHeaders, params = responseBody)
print(r)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Notify Moderator
@Jake_Jake_Jake The URL from the interactive documentation can't be copied over to python. They're just trying to show you an example so you can build your own. Here are my comments on specific pieces of your URL that you would have to create yourself:
1) oauth_timestamp: You will need to calculate the elapsed time. More details here.
2) oauth_nonce: You will need to create a random string. More details here.
3) oauth_signature: You will need to build your oauth_signature in python. That's the hardest part of the api, and it's a bummer the interactive documentation doesn't spell this out as well; however, they provide a link to the signing process. The signing process has a link to an appendix item which spells out an example of the data that is used to create the signature (along with the key). Notice that the signature includes a timestamp and nonce, which prohibits it from being re-used (and hence you'll need to build it like I mention above).
As for things I've stubbed my toe on,
1) the order can matter (ie to create the signature you have to properly order the several oauth_elements alphabetically).
2) Case matters (Get does not work but GET does)
3) Some things are url encoded and some things are not. (& in some spots and %26 in other spots)
4) Time zones and daylight savings can affect your timestamp. Luckily the api will respond that you have a bad timestamp if that's the issue.
For what it's worth, here is my functioning VBA code to do the signature generation process which may help point you in the right direction.
strBaseString = WorksheetFunction.EncodeURL(strUrl) & _
"&oauth_consumer_key%3D" & strKey & _
"%26oauth_nonce%3D" & Nonce & _
"%26oauth_signature_method%3DHMAC-SHA1" & _
"%26oauth_timestamp%3D" & Time & _
"%26oauth_version%3D1.0"
CreateNewSignature = Base64_HMACSHA1(UCase(getpost) & "&" & strBaseString, strSecret & "&")
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Notify Moderator
@patrick_digan Thanks for the help! You are right about the oauth_signature being the hard part.
I understand that how to generate the signature base string, but I'm not sure what to do with it next. Just putting it in the browser results in a google search instead of calling the website. How does one call send the request? Does the signature base string go directly in the URL for the post request?
This is the sanitized version of my signature base string.
GET&http%3%2%2gallery.<MySite>.com%2gallery%2api%2&oauth_consumer_key=<consumerKey>&oauth_nonce=<my generated uuid>&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1539870497&oauth_token=<secret>&oauth_version=1.0&size=original
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Notify Moderator
1) I think all of your oauth_xxxxx stuff needs encoded. The & after the GET can stay as well as the & before oauth_consumer_key, but the rest of the & and = need to be encoded ( %26 and %3D i believe)
2) I don't think the size=original at the end should be there.
3) I don't think oauth_token=<secret> part should be in there. Here is an example of a key I generate using alteryx tools:
GET&<encoded URL>&oauth_consumer_key%3D<key>%26oauth_nonce%3D818945583%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1539871608%26oauth_version%3D1.0
4) With your signature base string, you would need to then need to hash it using the specified hmac-sha1 algorithm. Your 2 inputs would be the signature base string and your secret. Your secret will need to have an & at the end.
5) You would need to base64 encode your output from step 4. this is the signature you pass in the next step
6) You can now make a GET request to this URL:
<normal URL>?oauth_consumer_key=<key>&oauth_nonce=373116378&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1539872288&oauth_version=1.0&oauth_signature=<base 64 encoded signature>
I'm attaching a macro that I got from another post on the community and slightly modified. If you're not in the Eastern US time zone, you'll need to adjust the timestamp calculation in the macro. Formula (66) is currently adding 4 hours to my computer's time since I'm 4 hours behind GMT.
