How to set Rest request Headers parameters in pydocumentdb - python

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

Related

Not able to generate JWT token for python zephyr

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

Getting "INVALID_TOKEN_FORMAT The security token format does not conform to expected schema." docusign legacy auth header

I'm trying to write a request using Python Requests which sends a request to Docusign. I need to use the legacy authorization header, but unfortunately it seems most documentation for this has been removed. When I send the request I get an error as stated in the title.
From research, I found that special characters in the password can cause this issue, so I've confirmed that my password has no special characters, and that my API key is correct. I am currently sending the header as a stringified dictionary as shown below. I have tried it several other ways, and this seems to be the closest, but it still results in the error. Other ways I've tried include attempting to write out the header as a single string (not forming a dictionary first), but that didn't seem to work any better.
docusign_auth_string = {}
docusign_auth_string["Username"] = docusign_user
docusign_auth_string["Password"] = docusign_password
docusign_auth_string["IntegratorKey"] = docusign_key
docusign_auth_string = str(docusign_auth_string)
headers = {'X-DocuSign-Authentication': docusign_auth_string}
response = requests.post(docusign_url, headers=headers, data=body_data)
The above code returns a 401 with the message, INVALID_TOKEN_FORMAT "The security token format does not conform to expected schema." The header I am sending looks as follows:
{'X-DocuSign-Authentication': "{'Username': 'test#test.com', 'Password': 'xxxxxxxxxx', 'IntegratorKey': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'}"}
When I send the request via Postman, it works just fine. In Postman I enter the header name as X-Docusign-Authentication, and the value as: {"Username":"{{ds_username}}","Password":"{{ds_password}}","IntegratorKey":"{{ds_integrator_key}}"} (subbing the same variable values as in the python code).
Therefore it definitely has something to do with the way Requests is sending the header.
Does anyone know why I might be getting the above error?
I'm able to reproduce this behavior: It looks like DocuSign doesn't accept Single Quotes around the sub-parameters of the x-DocuSign-Authentication header value.
Your example fails:
{'Username': 'test#test.com', 'Password': 'xxxxxxxxxx', 'IntegratorKey': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'}
This has more success:
{"Username": "test#test.com", "Password": "xxxxxxxxxx", "IntegratorKey": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"}
I'm not familiar enough with Python to advise if there's a different code structure you can follow to use double quotes instead of single. Worst case scenario, you may need to manually set the Header Value to follow that format.
I found a solution to this issue. The response that mentioned double quotes is correct, but in Python I was unable to send a string with the proper format for docusign to understand. Next I found the following Stack overflow question, which ultimately provided the solution:
How to send dict in Header as value to key 'Authorization' in python requests?
I used json.dumps and that resolved the issue. My code is as follows:
docusign_auth_string = {}
docusign_auth_string["Username"] = docusign_user
docusign_auth_string["Password"] = docusign_password
docusign_auth_string["IntegratorKey"] = docusign_key
headers = {"X-DocuSign-Authentication": json.dumps(docusign_auth_string), "Content-Type": "application/json"}
Since you are having success using Postman, it will help to get exactly what is being sent via your request. For this use:
response = requests.get(your_url, headers=your_headers)
x = response.request.headers()
print(x)
This will show you exactly what requests is preparing and sending off. If you post that response here id be happy to help more.
How can I see the entire HTTP request that's being sent by my Python application?
The 2nd answer shows all the possible parameters of your response object.

API error handling

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

How to INSERT all triples from an RDFlib graph into another repository without iterating through every triple?

This question is related to What URI to use for a Sesame repository while executing a SPARQL ADD query.
I'm trying to INSERT all triples from a Sesame repository into another (Dydra). There are a couple of ways to do it, such as using SERVICE clause or Dydra's GUI. However, Dydra restricts the use of SERVICE and I want an efficient way to insert the data programmatically. This is the code I have right now:
queryStringUpload = 'INSERT {?s ?p ?o} WHERE GRAPH %s {?s ?p ?o}' % dataGraph
sparql = SPARQLWrapper(dydraSparqlEndpoint)
sparql.setCredentials(key,key)
sparql.setQuery(queryStringUpload)
sparql.method = 'POST'
sparql.query()
The code results in the following error:
client error: failed to parse after 'GRAPH' at offset 24 on line 1.
INSERT {?s ?p ?o} WHERE GRAPH [a rdfg:Graph;rdflib:storage [a rdflib:Store;rdfs:label 'IOMemory']]. {?s ?p ?o}
.
Basically, I understand that I'm incorrectly using string formatting. What is the correct way to execute the query?
One way to programmatically do this is by iterating through every triple in dataGraph and individually INSERTing them. I've tried this approach. While the code works, not all of the data is ported. That's the reason I'm looking for a way to bulk port the data.
UPDATE 1
This is the code I tried for implementing the suggested answer:
sesameURL = 'http://my.ip.ad.here:8080/openrdf-sesame/repositories/rep_name/statements'
payloadPOST = {
'url': sesameURL,
# 'account[login]':key,
# 'account[password]':'',
# 'csrfmiddlewaretoken':csrfToken_new,
# 'next':'/',
}
headersPOST = {
'User-Agent': 'python',
'Content-Type': 'application/n-quads',
# 'Referer': dydraLogin,
}
paramsPOST = {
'auth_token': key,
#'url': sesameURL
}
# print payload
try:
q = s.post(dydraUrl,data=payloadPOST, params=paramsPOST, headers=headersPOST)
print "q.text: " + q.text
print "q_status_code: " + str(q.status_code)
except requests.exceptions.RequestException as e:
print e
This is the error:
q_status_code: 400
However, if I comment out the 'url' attribute, I get this:
q_status_code: 201
Any ideas on how to resolve will be very helpful.
UPDATE 2
Now, irrespective of whether 'url' is under headersPOST or paramsPOST, I get the following as output:
q_status_code: 201
However, the data that I want to post doesn't get POSTed. How do I need to do differently?
I'm not gonna bother answering why you get that syntax error on that SPARQL update, since it seems immaterial to what you actually want to know. I'm also not going to bother answering how to upload an RDFLib graph to Dydra, since that also seems immaterial to what you want to know. What I'll answer here is how you can upload data from a Sesame store to a Dydra store, programmatically, without having to iterate over all triples, and without use of the SERVICE clause.
Dydra's REST API is basically identical to the Sesame REST API, so most REST operations you can do on a Sesame store you can also execute on a Dydra store.
You can do a HTTP POST request to your Dydra store's REST API URL for statements: repository/<ACCOUNT_ID>/<REPO_ID>/statements (see here in the Dydra docs for more details). Add a parameter url which points to the URL of your source Sesame store URL for statements: (repository/<REPO_ID>/statements). Also make sure you specify a Content-Type HTTP header in your POST request that specifies the MIME-type of an RDF syntax format supported by Dydra (a good pick is something like TriG or N-Quads, since these formats support named graphs).
You don't even need RDFLib for any of this. Presumably you know how to do a simple HTTP request from Python, if not I'm sure there's examples aplenty as it's a fairly generic thing to do.

Making get requests to list of dictionary

i'm working with python and requests. My api data looks like as shown below :
[
{
'id_list' = [{'id':1,'name' = 's1'},{'id':2,'name' = 's2'}], 'username'='oiyio'
}
{
'id_list' = [{'id':3,'name' = 's3'},{'id':4,'name' = 's4'}], 'username'='oiyio2'
}
]
I can make request as the following :
http://api.example.com/users?username=oiyio
However, i need to check key "id" and retrieve the one with id=1 for example. How to do that?
I tried below one but it did not work as i have expected.
http://api.example.com/users?id_list?id=1
Thanks in advance.
Since it is an API response, you need to modify the API code to return results as per the parameters requested by the client. If you cannot alter the API code, you have to change the code on the client side before consuming it. So, in your case:
for item in response:
for data in item.getlist("id_list"):
if data.get("id") == 1:
print data
And if you have control over the API, you can always modify the API. You need to read the documentation of the API to know what all requests it caters to.

Categories