Unable to set payload to match with required format by server - python

I'm trying to download a excel file using a python request.
Below is the actual payload pass by web browser when I download required excel file manually.
I'm using below python code to do the same via automation.
import requests
import json
s = requests.Session()
response = s.get(url)
if response.status_code!=200:
return 'loading error!'
collectionId = response.content['collectionId']
payload = {
"collectionId": collectionId
}
response = s.post(url, json=payload)
Here I'm getting status code 400.
Can someone please help me to set payload to match with below snapshot.

Related

Python requests module working in postman but on with python Invalid request body/header

I am using the postman tool to send the requests to the api server and trying to get the code snip-it from code section of postman, but somehow the same code is not working with python
this is the code :
import requests
import json
url = "http://127.0.0.1:3333/api/v1/solve"
payload={'FileLocation': '/var/opt/rcm_dms/reg'}
files=[
('regChallengeFile',('gudsgtcnsrk_reg_challenge.json',open('/home/system/Music/gudsgtcnsrk_reg_challenge.json','rb'),'application/json'))
]
headers = {
'Content-Type': 'application/json'
}
response = requests.request("POST", url, headers=headers, data=payload, files=files)
print(response.text)
output : {"statusCode":"DM-6-4002","statusMessage":"Invalid request body/header"}\n
I am using the postman tool to send the requests to the api server and trying to get the code snip-it from code section of postman, but somehow the same code is not working with python
this is the code :
output : {"statusCode":"DM-6-4002","statusMessage":"Invalid request body/header"}\n
What is wrong in this example , any suggestions
Single quotes should be on both side of key FileLocation payload={'FileLocation': '/var/opt/rcm_dms/reg'} instead of payload={FileLocation': '/var/opt/rcm_dms/reg'}.
If you still get the error, check the format of value assigned in files variable i.e.,[('regChallengeFile',('gudsgtcnsrk_reg_challenge.json',open('/home/system/Music/gudsgtcnsrk_reg_challenge.json','rb'),'application/json'))]

How do you update DynamoDB from Jupyter Notebook via API Gateway?

I'm building a personal webscraper and I'm still in dev phase, but I want to start saving data. The problem is, I cannot PUT or POST from the notebook level, which also means I cannot iterate through a big list of dictionaries/json objects.
I can however to it manually via Postman by just pasting the body and sending it.
Below is my code, which currently returns:
The pastebin URL is:{"message": "Could not parse request body into json: Unrecognized token 'ID': was expecting 'null', 'true', 'false' or NaN\n at [Source: (byte[])"ID=0&District=London"; line: 1, column: 4]"}
import requests
# defining the api-endpoint
API_ENDPOINT = ##############
# data to be sent to api
body = {
"ID": 0,
"District": "London"
}
# sending post request and saving response as response object
r = requests.post(url = API_ENDPOINT, data = body)
# extracting response text
pastebin_url = r.text
print("The pastebin URL is:%s"%pastebin_url)
Related question - can I use urllib instead of requests here?
You can try the following:
r = requests.post(url = API_ENDPOINT, json = body)
or
import json
r = requests.post(url = API_ENDPOINT, headers={"Content-Type":"application/json"}, data = json.dumps(body))

HTTPS authentication in Python 2.7

we are trying to pass the Virustotal API through our proxy which is getting denied. HTTP websites are accessible using the code but HTTPS is not going through. Request any of you to post few sample codes which would help us. 
import postfile
host = "www.virustotal.com"
selector = "https://www.virustotal.com/vtapi/v2/file/scan"
fields = [("apikey", "-- YOUR API KEY --")]
file_to_send = open("test.txt", "rb").read()
files = [("file", "test.txt", file_to_send)]
json = postfile.post_multipart(host, selector, fields, files)
print json
Two ideas to try
1) without HTTPS you can post to http://www.virustotal.com/vtapi/v2/file/scan
2) try the python requests library
import requests
params = {'apikey': '-YOUR API KEY HERE-'}
files = {'file': ('myfile.exe', open('myfile.exe', 'rb'))}
response = requests.post('https://www.virustotal.com/vtapi/v2/file/scan', files=files, params=params)
json_response = response.json()

Sending a JSON string as a post request

rocksteady's solution worked
He did originally refer to dictionaries. But the following code to send the JSON string also worked wonders using requests:
import requests
headers = {
'Authorization': app_token
}
url = api_url + "/b2api/v1/b2_get_upload_url"
content = json.dumps({'bucketId': bucket_id})
r = requests.post(url, data = content, headers = headers)
I'm working with an API that requires me to send JSON as a POST request to get results. Problem is that Python 3 won't allow me to do this.
The following Python 2 code works fine, in fact it's the official sample:
request = urllib2.Request(
api_url +'/b2api/v1/b2_get_upload_url',
json.dumps({ 'bucketId' : bucket_id }),
headers = { 'Authorization': account_authorization_token }
)
response = urllib2.urlopen(request)
However, using this code in Python 3 only makes it complain about data being invalid:
import json
from urllib.request import Request, urlopen
from urllib.parse import urlencode
# -! Irrelevant code has been cut out !-
headers = {
'Authorization': app_token
}
url = api_url + "/b2api/v1/b2_get_upload_url"
# Tested both with encode and without
content = json.dumps({'bucketId': bucket_id}).encode('utf-8')
request = Request(
url=url,
data=content,
headers=headers
)
response = urlopen(req)
I've tried doing urlencode(), like you're supposed to. But this returns a 400 status code from the web server, because it's expecting pure JSON. Even if the pure JSON data is invalid, I need to somehow force Python into sending it.
EDIT: As requested, here are the errors I get. Since this is a flask application, here's a screenshot of the debugger:
Screenshot
Adding .encode('utf-8') gives me an "Expected string or buffer" error
EDIT 2: Screenshot of the debugger with .encode('utf-8') added
Since I have a similar application running, but the client still was missing, I tried it myself.
The server which is running is from the following exercise:
Miguel Grinberg - designing a restful API using Flask
That's why it uses authentication.
But the interesting part: Using requests you can leave the dictionary as it is.
Look at this:
username = 'miguel'
password = 'python'
import requests
content = {"title":"Read a book"}
request = requests.get("http://127.0.0.1:5000/api/v1.0/projects", auth=(username, password), params=content)
print request.text
It seems to work :)
Update 1:
POST requests are done using requests.post(...)
This here describes it well : python requests
Update 2:
In order to complete the answer:
requests.post("http://127.0.0.1:5000/api/v1.0/projects", json=content)
sends the json-string.
json is a valid parameter of the request and internally uses json.dumps()...

how to Download file over https python requests

I am trying to download a file over https using python requests. I wrote a sample code for this. When i run my code it doesnot download the pdf file given in link. Instead downloads the html code for the login page. I checked the response status code and it is giving 200. To download the file login is necessary. How to download the file?
My code:
import requests
import json
# Original File url = "https://seller.flipkart.com/order_management/manifest.pdf?sellerId=8k5wk7b2qk83iff7"
url = "https://seller.flipkart.com/order_management/manifest.pdf"
uname = "xxx#gmail.com"
pwd = "xxx"
pl1 = {'sellerId':'8k5wk7b2qk83i'}
payload = {uname:pwd}
ses = requests.Session()
res = ses.post(url, data=json.dumps(payload))
resp = ses.get(url, params = pl1)
print resp.status_code
print resp.content
I tried several solutions including Sending a POST request with my login creadentials using requests' session object then downloading file using same session object. but it didn't worked.
EDIT:
It still is returning the html for login page.
Have you tried to pass the auth param to the GET? something like this:
resp = requests.get(url, params=pl1, auth=(uname, pwd))
And you can write resp.content to a local file myfile.pdf
fd = open('myfile.pdf', 'wb')
fd.write(resp.content)
fd.close()

Categories