OAuth1Session Encoding of URL Django - django

Alright, I need some assistance with what I think is an easy question, but after digging for quite a while I'll leave it to you brilliant people to show me why I'm not!
I'm attempting to access a provider api, with the URL I'm attempting to access being: .../proposals/AnotherTestProposal/city_furniture/items?filter=description$CONT"Ag" :: this is the way they want it passed, and it should return all items who's descriptions contain the string "Ag". I know I have two of those currently.
I'm using Django 1.9.4, and requests_oauthlib to create an OAuth1Session, I'm doing this successfully also, because I can access resources without URL params. The trouble is I can't get the "?filter=description..." part to encode properly and it's giving me a 401.
When I render the .contents to HTML I get:
{"status": 404, "message": "", "data": [], "arguments": {"id": "items?filter=description$CONT\"Ag\"", "collection": "city_furniture"}}
which is telling telling me that the "AG" part is being escaped, which I don't want. As in: I don't want \"Ag\", I want "Ag".
So, my question: how can I pass the URL, with params, so they are not containing the slashes as these are causing the URL to be invalid and therefore keeping me from accessing the data correctly?
Other, possibly irrelevant info:
The params part of the URL string I'm passing to the OAuth1Session object now is: '/city_furniture/items%3Ffilter%3Ddescription%24CONT%22Ag%22'
An example of filtering from the API's website: proposals/master/roads/items?filter=description$CONT"highway"
I tried passing an 'encoding' arg to .get (in order to change the encoding used by to_native_string) but requests rejected it saying it was an invalid arg
Per comments, some additional code.
Using a function name get_protected_code() to get the OAuth info passed correctly, then in views.py:
api_filter_url = settings.IW_API_MODEL_COLLECTION + '/' + model_id + '/' + settings.IW_API_PROPOSAL_COLLECTION + '/' + proposal_name + '/city_furniture/items%3Ffilter%3Ddescription%24CONT%22Ag%22'
json_model_info_pull = get_protected_data(api_filter_url)
find_vendor = json_model_info_pull.content
def get_protected_data(url_str):
## ...stuffs to create OAuth1Session...
adsk_pull = OAuth1Session(key,
client_secret=secret,
resource_owner_key=oauth_token_use,
resource_owner_secret=oauth_token_secret_use,
)
headers = {'accept': 'application/vnd.autodesk.infraworks-v1+json'}
api_url = settings.ADSK_IW_INFO_BASE_URL + url_str
json_model_info_pull = adsk_pull.get(api_url, headers=headers)
return json_model_info_pull

Looks like you're passing the parameters incorrectly by appending them to the end of the URL in URL-encoding, which requests is respecting as intentional, and the API endpoint is translating in an unintended manner.
From the documentation for requests, you should provide a params keyword argument to requests.get: a dict containing the key-value pairs that should be encoded and sent as the query string for the request. For example, to run a query against the GitHub API, we can pass an API token as a query parameter:
requests.get('http://api.github.com/user',
params={ 'access_token' : MY_OAUTH_TOKEN })
The resultant request will contain a query string with an access_token parameter set to the value stored in MY_OAUTH_TOKEN and escaped properly, as needed. (Such tokens typically contain = characters, for example, that are invalid inside query string values.)

Related

How to create a collection variable from response in postman

Selecting a value and right-clicking enables me to save it as a Global variable.
But there is no option to save it as a collection variable.
In the environments section as well. I can see Globals but my collection is not available.
But as I go through blogs/ articles online I can see some variables that are scoped to a collection.
Can I know a way to achieve this?
Tests tab is all you need
Considering the Stackoverflow GetUser API for Reference.
NOTE: The below-shown response is a part of the original response.
Response:
{
"items": [
{
"user_type": "registered",
"user_id": 12345678,
}
]
}
In the above response let's say we need user_type, and user_id in another API's URL / body / headers.
Before accessing we need to store these variables after receiving the response. This can be done in the Tests tab in postman request.
const jsonData = JSON.parse(responseBody);
const userType = jsonData?.items?.[0]?.user_type;
const userId = jsonData?.items?.[0]?.user_id;
if(userType){
pm.collectionVariables.set("userType",userType)
}
if(userId){
pm.collectionVariables.set("userId", userId)
}
Points to Note:
Postman tests are written in Javascript.
Optional chaining in line 2,3 is to avoid console errors. Possible Scenario: When API fails and returns an error response.
The IF Statements are to avoid null values in case of an Error Response. If statements are not mandatory. In fact without using if statements you will get to know clearly that something went wrong.
How to use collection variables
Once you make a request with the above tests. Postman IntelliSense suggests available collection variables. ( Refer to the image attached )
We are sending the body as a raw JSON in this Test Endpoint. Note that userType is surrounded by double quotes "" whereas userId is not. ( JSON syntax )

Unable to send a GET request containing "." query parameter using Lambda

I created an API Gateway which contains multiple query parameters.
When I try to invoke its URL on Postman it works very well:
'https://xxx.execute-api.eu-central-1.amazonaws.com/stage/getfile/test.csv/.'
But, when I simulate the same request on Lambda, I get a Missing Authentication Token error.
headers = { 'Content-Type': 'application/json'}
url= 'https://xxx.execute-api.eu-central-1.amazonaws.com/stage/getfile/test.csv/.'
r=requests.request("GET",url,headers=headers)
r.text
'{"message":"Missing Authentication Token"}'
Replacing the dot "." by another character in the URL makes the error disappear but I need to send a dot.
No solution is possible for this kind of problem. I had to replace "." with dot and manage it with my code.

Getting unexpected '#' error under postman Test tab

I am a learner in postman and do not have much experience in programming/scripting.
Here the issue.
Used POST api request - For getting the access token;
Used POST api request - To create an account;
Used POST api request - To cancel an account with CancellationReason
Need to crosscheck the cancellation details (some fields like cancellationReason) in web application.
In order to avoid manually check, i have used GET request api like below
by passing all the mapped fields (as per web application) in the GET request end url
(i.e. by sending the details in fetch_xml query parameter in the end url) in order to get those required fields returned.
Now i got a successful response with status code.
After that i want to compare the fetched values (from the response body) ... VS.... to the data i passed while cancelling the account (i.e. in POST api request - To cancel the account) and make sure both are same.
After that under Test tab - I have updated query like below, however it throwing an Unexpected '#' error (as the below query contains '#' in middle of the field name)
tests["Verify the CancellationReason matches"] = pm.expect(data._usr_cancellationReason_value#OData.Community.Display.V1.FormattedValue).to.eql("CancellationReason");
Can someone please help me to understand whether i should remove this #symbol or should replace with something else ?
Here is the response body:
{
"#odata.context": "https://hfrdcompanies.integrationdev01.crm3.cs.com/api/data/v9.1/$metadata#hfrd_workorders(_usr_cancellationchannel_value,usr_CancellationChannel,_usr_workorderreason_value,usr_WorkOrderReason,hfrd_workorderid,usr_cancellationuser,_usr_cancellationsource_value,usr_CancellationSource,hfrd_name,usr_CancellationChannel(),usr_AccountReason(),usr_CancellationSource())",
"value": [
{
"#odata.etag": "W/\"2345234523\"",
"_usr_cancellationchannel_value#OData.Community.Display.V1.FormattedValue": "Mobile App",
"_usr_cancellationchannel_value": "acefsdflin89-f9jf07-e969f1-a245nk11-00jnfnafn9799fc2a",
"_usr_Accountreason_value#OData.Community.Display.V1.FormattedValue": "Customer Inactive",
"_usr_Accountreason_value": "bde1234522-d45662-e2711-a84561-0007354a2d5c2a",
"hfrd_Accountid": "89025sf3-c668f-e7811-a4331-00asdhh3ab9bd1c",
"usr_cancellationuser": "Testuser08 ABC",
"_usr_cancellationsource_value#OData.Community.Display.V1.FormattedValue": "MOBILE",
"_usr_cancellationsource_value": "6c23asdf-c562-e411-a841-00asdfa",
"hfrd_name": "FP-WK-1000000642"
}
]
}
I want to validate the bold row

Why does this request return an empty string?

I have the following function which makes a get request to a url.
def fetch_data(session = None):
s = session or requests.Session()
url = 'http://www.moldelectrica.md/utils/load4.php'
response = s.get(url)
print response.status_code
data = response.text
return data
I expect to get a string back in the form.
169,26,0,19,36,151,9,647,26,15,0,0,0,0,0,150,7,27,-11,-27,-101,-19,-32,-78,-58,0,962,866,96,0,50.02
But instead I get an empty unicode string. The status code returned is 200.
I've looked at the request headers but nothing in them suggests that any headers will require being set manually. Cookies are used but I think the session object should handle that.
Figured it out. As I said this url provides data for a display so it wouldn't normally be visited directly. Usually it would be requested by the display page and that page would provide a cookie.
So the solution is to make a request to the display url then reuse the session and make another request to the data url.

Postman: Is it possible to update url of postman request in the pre-requisite script

Is it possible to update url of postman request in the pre-requisite script.
I want to edit the url based on dynamic environment input.
For example:
if (environment.someValue) {
request.url = request.url + "\" + environment.someValue
if (environment.anotherValue) {
request.url = request.url + "\" + environment.anotherValue
}
}
console.log(request.url);
The above code gives me prefect console log:
e.g. if url is https://someServer/someRequest, environment.someVar is x and environment.anotherVar is y the console.log(request.url) above prints:
https://someServer/someRequest/x/y
But the problem is (say if i am requesting a Get), even after logging the overridden request url, it only calls https://someServer/someRequest and does not override to https://someServer/someRequest/x/y.
Any ideas how to modify the url as asked above.
if your url in your request is set as a global, it should work.
ie. I have a get request :
GET http://{{myurl}}/etc. with myurl set as a global variable
In my prerequest script I do pm.globals.set("myurl", <new url>);
when I launch my request, it tries to do the GET request on my new url.
So it is possible to do it but you have to use global or environment variables to dynamically update your request:
set your 'someRequest' as a global that you can update in your prescript (instead of request.url), then it will be interpreted when you launch your request
https://someServer/{{someRequest}}
pm.request.url= "dynamic value"
you and update url using the above single line in postman prerequisite step
pm.request.url returns a object with fields host,path and params . But you can replace it with string.
Thanks for the tips: I used these lines of code to manipulate two values that appear in a RESTful API route:
// Ensure Payroll ID and Employee ID in request URL are correctly padded with zeros
pm.request.url.path[pm.request.url.path.indexOf("{{PayrollID}}")] = data.PayrollID.toString().padStart(6, '0');
pm.request.url.path[pm.request.url.path.indexOf("{{EmployeeID}}")] = data.EmployeeID.toString().padStart(7, '0');