Not able to handle multiple request by Django - django

I am trying to send multiple json object in one request , but I am not able to extract values from it.
def config(request):
print "type",type(request)
print "request in config",request.body
if request.method == 'POST':
print "In Handler"
print "Request Body is ",request.body
data = simplejson.loads(request.body)
for i in data:
print "REQUEST is ____",i
z = json.dumps(i)
rew = retResp(z)
proID = request.data["proId"]
For request 1 can find proID but for request 2 I am not able to get proID.
req1 = curl -X POST http://192.168.2.242:8080/server/config/ -d '{"confMsgReqId": 2,"proId":"123"}' -H "Content-Type: application/json"
req2 = curl -X POST http://192.168.2.242:8080/server/config/ -d '[{"confMsgReqId": 2,"proId":"123"},{"confMsgReqId": 2,"proId":"345"}]' -H "Content-Type: application/json"

The data in the first request is a dictionary, so you can access data['proID'].
The data in the second request is a list of two dictionaries, so you can access data[0]['proID'] or data[1]['proID'].
You'll find it easier if you use an array for the first request as well as the second. It's possible to make an api that can handle a single element of a list, but it makes the code more complicated.
req1 = curl -X POST http://192.168.2.242:8080/server/config/ -d '[{"confMsgReqId": 2,"proId":"123"}]' -H "Content-Type: application/json"
Looking at your code, you might want to access the id inside the loop. It's not clear why you are decoding the json manually instead of using request.data.
for d in request.data:
d["proId"]

Related

Integrating Sagepay (Opayo) with Django - How to create a merchant session key

I am trying to integrate Opayo (SagePay) with Django and I am having problems generation the merchant session key (MSK).
From sagepays docs they say to use the below curl request and that I should receive the key in the response
curl https://pi-test.sagepay.com/api/v1/merchant-session-keys \
-H "Authorization: Basic aEpZeHN3N0hMYmo0MGNCOHVkRVM4Q0RSRkxodUo4RzU0TzZyRHBVWHZFNmhZRHJyaWE6bzJpSFNyRnliWU1acG1XT1FNdWhzWFA1MlY0ZkJ0cHVTRHNocktEU1dzQlkxT2lONmh3ZDlLYjEyejRqNVVzNXU=" \
-H "Content-type: application/json" \
-X POST \
-d '{
"vendorName": "sandbox"
}'
I have tried to implement this in my Django view with the following code but I receive a 422 response (Unprocessable Entity response).
import requests
def BasketView(request):
headers = {
"Authorization": "Basic aEpZeHN3N0hMYmo0MGNCOHVkRVM4Q0RSRkxodUo4RzU0TzZyRHBVWHZFNmhZRHJyaWE6bzJpSFNyRnliWU1acG1XT1FNdWhzWFA1MlY0ZkJ0cHVTRHNocktEU1dzQlkxT2lONmh3ZDlLYjEyejRqNVVzNXU=",
"Content-type": "application/json",
}
data = {"vendorName": "sandbox"}
r = requests.post("https://pi-test.sagepay.com/api/v1/merchant-session-keys", headers=headers, params=data)
print(r)
Any ideas where I may be going wrong with this?
You are passing the wrong parameter to requests.post() you should use jsoninstead of params:
r = requests.post(
"https://pi-test.sagepay.com/api/v1/merchant-session-keys",
headers=headers,
json=data
)
By doing so, there is no need to specify the Content-Type header, it is added automatically.

Django 2.2.4 with DRF 3.9.4 - Not supporting GET method JSON body?

this:
curl "http://localhost:8000/v1/post" \
-H 'Content-Type: application/json' \
-H 'Accept-Encoding: gzip' \
-d $'{
"url": "/my-test-url"
}'
with this:
class PostView(APIView):
def get(self, request, format=None):
print(request.data['url'])
result = {}
return Response(result)
crashes on the print line...
KeyError: 'url'
However, changing the GET into a POST:
curl -X "POST" "http://localhost:8000/v1/post" \
-H 'Content-Type: application/json' \
-H 'Accept-Encoding: gzip' \
-d $'{
"url": "/my-test-url"
}'
class PostView(APIView):
def post(self, request, format=None):
print(request.data['url'])
result = {}
return Response(result)
will print it fine.
/my-test-url
[26/Nov/2019 22:00:42] "POST /v1/post HTTP/1.1" 200 2
This causes me to believe either Django can't handle GET request body payload and that I must use URL parameters instead with GET --- or that I'm missing something.
What am I doing wrong here?
GET requests have no body, that's why data is empty.
If you wanted to pass something using a GET request you would need to use querystring params (eg: http://localhost:8000/v1/post?url=myurl), then you can get them back using request.query_params rather than request.data (eg: request.query_params['url']).
Take a look to the DRF Request Parsing documentation for further details.
Can you try this:
curl -X GET http://localhost:8000/v1/post -H 'Content-Type: application/json' -H 'Accept-Encoding: gzip' -d '{"url": "/my-test-url"}'

Trying to get a session value from a post call in Postman: TypeError: postman.getResponseHeader is not a function

In Postman, I am trying to retrieve a session value returned from a post call and use it in another get call.
I mean, I called via Postman:
curl -X POST \
https://skyscanner-skyscanner-flight-search-v1.p.rapidapi.com/apiservices/pricing/v1.0 \
-H 'Accept: */*' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-H 'Host: skyscanner-skyscanner-flight-search-v1.p.rapidapi.com' \
-H 'Postman-Token: xxxx' \
-H 'User-Agent: PostmanRuntime/7.15.0' \
-H 'accept-encoding: gzip, deflate' \
-H 'cache-control: no-cache' \
-H 'content-length: 177' \
-d 'inboundDate=2019-11-25&cabinClass=economy&children=0&infants=0&Country=BR&Currency=BRL&locale=pt-BR&originPlace=GRU-sky&destinationPlace=MCZ-sky&outboundDate=2019-11-19&adults=2'
It returned in Header among others keys:
Location →http://partners.api.skyscanner.net/apiservices/pricing/uk2/v1.0/b5b906e9-164e-4f1d-b5ce-9085b8a3506d
Now, I want to call another API and I must use the session id returned in previous call. It is after /v1.0/. In this case it is b5b906e9-164e-4f1d-b5ce-9085b8a3506d
The first steps is getting the Location key value but I am getting the error mentioned in this question title (see picture attached for more details).
So my straight question is how can I retrieve the Location value from another post request? Well, a complementary and helpfull coment will be how to parse and get only the session id but naturally firsly I have to fix how retrieve the whole Location value.
It is more or less this what I am trying:
var sessionKey = JSON.parse(postman.getResponseHeader('Location') );//maybe here applying some regular expression to get only the value after the last "/"
pm.environment.set("sessionkey", postman.getResponseHeader("sessionkey"));
My question is somehow close to In POSTMAN how do i get substring of response header item? but here the question author is able to use postman.getResponser and it seems he didn't get a final answer at the end.
My Postman version is 7.3.4 (Latest) (I have just updated it).
*** edited after first sugestion
*** another tentative failling
var locationHeader = pm.response;
console.log(pm.response); //Print successfully all response including body and header
var jsonData = JSON.parse(pm.response); //exception: There was an error in evaluating the Pre-request Script: JSONError: Unexpected token u in JSON at position 0
console.log("Location = " + jsonData.Location);
PS. it is interesting that
pm.request.headers.add({key: 'X-RapidAPI-Host', value: 'skyscanner-skyscanner-flight-search-v1.p.rapida.com'})
works properly in my collection Pre-request scripts. It is obvious to have pm.request.headers.get, isn't it? But it doesn't have.
*** edited
I also added this question in https://community.getpostman.com/t/trying-to-get-a-session-value-from-a-post-call-in-postman-typeerror-postman-getresponseheader-is-not-a-function/6804
*** edited
Just in case someone get interested, my final implementation is
var locationHeader = pm.response.headers.get("Location").split('/');
var locationPosition = locationHeader.length-1;
var sessionKey = locationHeader[locationPosition];
pm.environment.set("sessionkey", sessionKey);
in Test tab while calling POst Create Session
Add the following script in the first request test, it will set sessionkey value that you can use for later calls.
var locationHeader = postman.getResponseHeader("Location").split('/');
var sessionKey = locationHeader[locationHeader.length-1];
pm.environment.set("sessionkey", sessionKey);

Retrieving data from Streamsets Data Collector (SDC) protected by Kerberos

I am trying to retrieve data from the SDC API protected by Kerberos. Initially i am posting the credentials to the SCH login page and then using the cookies generated to access the SDC rest api. However, i am not able to post the credentials. Response code is 401 and hence not able to access api.
dpm_auth_creds = {"userName":"", "password":"" }
headers = {"Content-Type": "application/json", "X-Requested-By": "SDC"}
auth_request = requests.post("https://url:18641/sch/security/users" , data=json.dumps(dpm_auth_creds), headers=headers, verify="file.pem")
cookies = auth_request.cookies
print(auth_request.status_code)
print(auth_request.headers)
url = requests.get("https://url:18641/jobrunner/rest/v1/sdcs", cookies=cookies)
print(url.text)
Response code is 401: for auth_request.status_code
This is from the REST API page in Control Hub:
# login to Control Hub security app
curl -X POST -d '{"userName":"DPMUserID", "password": "DPMUserPassword"}' https://cloud.streamsets.com/security/public-rest/v1/authentication/login --header "Content-Type:application/json" --header "X-Requested-By:SCH" -c cookie.txt
# generate auth token from security app
sessionToken=$(cat cookie.txt | grep SSO | rev | grep -o '^\S*' | rev)
echo "Generated session token : $sessionToken"
# Call SDC REST APIs using auth token
curl -X GET https://cloud.streamsets.com/security/rest/v1/currentUser --header "Content-Type:application/json" --header "X-Requested-By:SCH" --header "X-SS-REST-CALL:true" --header "X-SS-User-Auth-Token:$sessionToken" -i
So your Python code should be more like:
dpm_auth_creds = {"userName":"", "password":"" }
headers = {"Content-Type": "application/json", "X-Requested-By": "SDC"}
auth_request = requests.post("https://url:18641/security/public-rest/v1/authentication/login" , data=json.dumps(dpm_auth_creds), headers=headers, verify="file.pem")
cookies = auth_request.cookies
print(auth_request.status_code)
print(auth_request.headers)
# Need to pass value of SS-SSO-LOGIN cookie as X-SS-User-Auth-Token header
headers = {
"Content-Type":"application/json",
"X-Requested-By":"SCH",
"X-SS-REST-CALL":"true",
"X-SS-User-Auth-Token":auth_request.cookies['SS-SSO-LOGIN']
}
url = requests.get("https://url:18641/jobrunner/rest/v1/sdcs", headers=headers)
print(url.text)

posting a parameter with integer value using requests lib

I have a curl command that was given to me that I have to convert using requests.
curl --request POST "https://www.example.com" --data "user_id=200" --data "user_data=je93jfe92dj220,39fjid20djd93f302,93jfieheio02hfne,902jfoienfieshiu202" --header "Authorization: Bearer [TOKEN]"
using requests, the call should be
hdr = {'Content-Type': 'Content-type: application/json',
'Authorization': 'Bearer TOKEN' }
payload = {"user_id":200,"records":"je93jfe92dj220,39fjid20djd93f302,93jfieheio02hfne,902jfoienfieshiu202"
requests.post('https://www.example.com', headers=hdr, data=json.dumps(payload))
This isn't working as I'm getting an error returned that the 'user_id' param must be an integer. Not sure how to ensure that, as aren't all parameters formatted as strings when sent? The curl command does work, however.
Im not really sure the reason, but to make this work, just change data=json.dumps(payload) to json=json.dumps(payload). This worked just fine for me.