I'm unable to generate valid JWT token for the below endpoint:
https://prod-api.zephyr4jiracloud.com/connect/public/rest/api/1.0/cycle/cycleId/export?versionId=&exportType=&projectId=
I have the cycleId passed as parameter and rest query arguments too but unable to get a response.
I'm unsure about how to set the RELATVE_PATH for the above endpoint?
Example provided for python(link) shows:
RELATIVE_PATH = '/public/rest/api/1.0/cycle'
Tried using RELATIVE_PATH = '/public/rest/api/1.0/cycle/ 79655-XXX-XXXX/export' but no luck!
I got this resolved by maintaining an order of query parameters. Strangely, the query params should be sorted alphabetically.
This was a hit and try based on the reference provided here
Related
I'm want to make a CloudStack API call 'uploadVolume' as described in here.
I'm using python and my code works for all others API calls, excepted uploadVolume.
secretkey = 'EdKz8Po3zmFWacumfxirauUBPVcLEWKq0qRox1iqhzAsrmLnJaEJxL2IsyDfyPE2Oh5AODJG3ZGKZf6A08xQAw'
apikey = 'YIShhcJ1PaGF5awJlci46qyAqhEN8WYdtUodHAT2wp7-zpN21_fJpcy1POTiMXOlFH-f-rO3zAs3tYRGcFqxwg'
request['command']='uploadVolume'
request['format']='QCOW2'
request['name']='test'
request['url']='http://192.168.122.100/image.qcow2'
request['zoneid']='959416fc-71f0-461c-99f0-28449e098036'
request['response']='json'
request['apikey']= apikey
baseurl='http://192.168.122.250:8080/client/api?'
request_str='&'.join(['='.join([k,urllib.quote_plus(request[k])]) for k in request.keys()])
sig_str='&'.join(['='.join([k.lower(),urllib.quote_plus(request[k].lower().replace('+','%20'))])for k in sorted(request.iterkeys())])
sig=urllib.quote_plus(base64.encodestring(hmac.new(secretkey,sig_str,hashlib.sha1).digest()).strip())
url=baseurl+request_str+'&signature='+sig
The generated URL looks like this:
http://192.168.122.250:8080/client/api?apikey=YIShhcJ1PaGF5awJlci46qyAqhEN8WYdtUodHAT2wp7-zpN21_fJpcy1POTiMXOlFH-f-rO3zAs3tYRGcFqxwg&name=test&format=QCOW2&url=http%3A%2F%2F192.168.122.100%2Fimage.qcow2&zoneid=959416fc-71f0-461c-99f0-28449e098036&command=uploadVolume&response=json&signature=EKhoEWKIG3QcmFM9k6sVRruZvFs%3D
Response indicates that there is a signature problem:
{"uploadvolumeresponse":{"uuidList":[],"errorcode":401,"errortext":"unable to verify user credentials and/or request signature"}}
After some tests, I have identified that the signature error occurs because of the url parameter. If I replace the url with any string in this parameter the signature is done correctly, but (obviously) the command fails (since CloudStack will not find the image).
I think the problem is in the special characters that make up the url, but I'm not sure.
Does anyone have any idea how to solve this?
I'm using the pydocumentdb library to query document-db.
I get errors when trying to execute cross-partitions queries, which are... considering I use a primary key as partition-key... every query I do.
The error message mentions the parameter x-ms-documentdb-query-enablecrosspartition. Which is indeed a rest http header constant, but I don't find any way to add parameters to the headers neither in the document_client module.
Finally found it :
client_documentDB = document_client.DocumentClient(
config['ENDPOINT'],
{
'masterKey': config['MASTERKEY']
}
)
client_documentDB.default_headers['x-ms-documentdb-query-enablecrosspartition'] = True
I am looping over Google Analytics account profiles using the management().goals() API and discovering what goals are created for each, to know what I can fetch data for. Having got a valid service instance I can make requests against, the goals().list() fails complaining of missing webPropertyId parameter:
# not including the ServiceAccountCredentials setup here
from apiclient.discovery import build
service = build('analytics', 'v3', http=http)
service.management().goals().list(accountId=account_id, webPropertyId='~all', profileId=profile_id)
The last line fails with:
googleapiclient.errors.HttpError: <HttpError 400 when requesting https://www.googleapis.com/analytics/v3/management/accounts/nnnnnnnnn/webproperties/%7Eall/profiles/nnnnnnnnn/goals?alt=json returned "webPropertyId must be specified.">
[I replaced the account/profile numbers after /accounts/ and /profiles/ with nnnnnnnnn for this post, for privacy; the real error has numbers there]
The relevent bit: webPropertyId must be specified.
I'm definitely supplying the webPropertyId parameter, and if I remove it I get a different error:
TypeError: Missing required parameter "webPropertyId"
I can successfully make requests to pull other metadata and user information and analytics data from the management api. What might be going wrong here? Am I not allowed to use the ~all value here and must be more specific?
Works:
GET https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties/~all/profiles/~all/goals
Also works
GET https://www.googleapis.com/analytics/v3/management/accounts/~all/webproperties/~all/profiles/73835159/goals
Does not work.
GET https://www.googleapis.com/analytics/v3/management/accounts/41967536/webproperties/~all/profiles/73835159/goals
Response:
{"error":{"errors":[{"domain":"global","reason":"badRequest","message":"webPropertyId must be specified."}],"code":400,"message":"webPropertyId must be specified."}}
I am going to call this a bug Goals with ~all results in an error bug report filed i will bring it up with the team next week.
So, I am using API calls to get some json data, and I am using a for loop to execute the call using multiple ids which will return different data based on the user's id. So basically we need to update the permissions for some of our users so the json data looks somewhat like this for the users without permissions:
{"meta":{"httpStatus":"401 - Unauthorized","error":{"errorMessage":"Insufficient
permissions.","errorCode":"ARH_8.5"},"requestId":null}}
and this for users with the permissions:
{"result":{"elements":[{"id":"dslkjafsadl","name":"Test","ownerId"
:"sdfadfsfsda","lastModified":"2016","isActive":true},
{"id":"dsafsad","name":"Test","ownerId":"sdfasdfa","lastModified":"2016","isActive":true}],"nextPage":null},"meta":{"httpStatus":"200 - OK","requestId":"3242343"}}
so my question is if I have a big response with many results both with and without permissions how could I only pull the ids from the users with permissions, and exclude the ones without the permissions.
Say the response is stored in the variable "data" and the ids that I am looking for will be stored in "requestId" this is the code I tried:
requestId = request_id = [element['requestId'] for element in data['result']['elements']]
from this code I receive the a TypeError, and it doesn't recognize 'result' because the first response is a user without the correct permissions.
Best way is to check the http status code from the original request. Say you use the requests library to perform the GET to whatever resource, status_code of the requests object will contain 401 for permission denied.
Just relying on the code you already have, you can include a conditional statement as:
requestId = request_id = [element['requestId'] for element in data['result']['elements'] if element.get('meta').get('httpStatus') == '200 - OK']
which will basically only take elements where 'meta'.'httpStatus' is the desired one.
For the requests library, take a look here: http://docs.python-requests.org/
If you have control over your JSON:
One potential solution would be to consturct your json such that there's a parent node which describes the permissions of the returned result. For example:
{"permissions": false,
{"meta":{"httpStatus":"401 - Unauthorized","error":
{"errorMessage":"Insufficient permissions.","errorCode":"ARH_8.5"},
"requestId":null}
}
}
And
{"permissions": true,
{"result":{"elements":[{"id":"dslkjafsadl","name":"Test","ownerId"
:"sdfadfsfsda","lastModified":"2016","isActive":true},{"
id":"dsafsad","name":"Test","ownerId":"sdfasdfa","la
stModified":"2016","isActive":true}],"nextPage":null},"meta":{"h
ttpStatus":"200 - OK","requestId":"3242343"}}}
With this setup, just read the first value, and then structure your json-parsing code accordingly.
If your don't have control over the JSON:
In this case, you have to figure out which request you're receiving before you can really process it. One way to do this would be to read the names of the top keys.
In the case of the correct response, you could do something like this:
parsed_json = json.loads(json_string)
# The key "result" is only in the sucess response, not in the error response
if "result" in parsed_json:
# Success
else:
# Error
I am trying to get the contents of a list on I a board I created to understand some things about my work flow.
The API seems quite complex, and I have been at it for hours. I have an API key, as well as a Secret key.
I tried the following from their docs: https://api.trello.com/1/lists/4eea4ffc91e31d174600004a/cards?key=[application_key]&token=[optional_auth_token]
However, I am not sure where these letters/numbers are coming from: 4eea4ffc91e31d174600004a.
I read the following page: https://developers.trello.com/apis (which gave me the link to the url above), but there is no info on how to get 4eea4ffc91e31d174600004a.
I simply want to visit a url that gives me json or something of that vein, with all the contents of a list (e.g. the cards + their names). Then I can visit that link programmatically and do my analysis.
Edit: Using the trello developer sandbox: https://developers.trello.com/sandbox/ I found the id of a list, which I substituted into 4eea4ffc91e31d174600004a, but now I get the following: Taco says “invalid token”, but what does he know? He's just a dog.
I used the Secret key as the token, but I guess that's not the token. So the question boils down to how can I get a token?
Thanks
So the full answer is:
To get the cards in a list, three things are required:
API Key
List ID
Token
(Secret key isn't needed anywhere)
To get the List ID, the simplest way to do that is to use the developer sandbox https://developers.trello.com/sandbox/ then hit 'get lists' + 'execute' and obtain the id of the list of interest.
Note if you have multiple boards, you will need to specify the board id here: Trello.get('/boards/[board_id]/lists', success, error);. You can get the board id by hitting 'get boards' + 'execute', then looking for the id of interest.
To get a token, you need to go here: https://trello.com/1/connect?key=[application_key]&name=MyApp&response_type=token
Then you can make the call:
https://api.trello.com/1/lists/[list_id]/cards?key=[application_key]&token=[optional_auth_token]
I recently worked on Trello data using its RESTful API and using Python's py-trello. As the question is about accessing Trello list and its cards, will limit my solution to list access using Trello RESTful API and py-trello.
1. Using Trello RESTful API:
Following you need to form your URI to access the desired list and its cards JSON
i) API Key: You can get the key from https://trello.com/app-key
ii) Token: On the above page itself, you'll find link to the Token generation. Posting the snap shot below for convenience-
iii) list id: you can find this in the board JSON
Using these 3 items, below is how the RESTful URI to access a list is going to look like:
list_json_url = "https://api.trello.com/1/lists/replace_this_with_ur_list_id?cards=all&key=replace_this_with_ur_api_key&token=replace_this_with_your_token
Below is how i'm loading above list JSON in my Python program :
with urllib.request.urlopen(list_json_url) as fj:
data = json.load(fj)
2. Using py-trello:
There can be better ways to do this using py-trello's filtering features, i have just taken this from my entire multi-boards analysis code and added a condition to match a list id:
from trello import TrelloClient
API_KEY = "XXXXXXX"
API_TOKEN = "XXXXXXXXXX"
client = TrelloClient(api_key=API_KEY, token=API_TOKEN)
for board in client.list_boards():
for l in board.list_lists():
if l.id = "ur_list_id":
#do your list analysis here
That is the list id which you can get by an API call to the boards
You'll find details here.
https://developers.trello.com/apis#boards
Go to link: https://trello.com/app-key
Click in TOKEN
Click in Allow
Copy your token
DONE