I need to download the response of POST-request on https://www.avast.com/hackcheck/ site as JSON file. But my request to the site return an error 400. My code is:
URL = 'https://identityprotection.avast.com/v1/web/query/site-breaches/unauthorized-data'
params = {'emailAddresses':['xxx#x.ru']}
headers = {'Vaar-Version': '0'}
req = requests.post(URL, params, headers)
req
The request on the site works correctly
The request on the site works correctly
So what am I doing wrong?
Ideally you should include all the other parameters in your request header also (not just the Vaar-Version). See screenshot below of the full POST variables:
Note: Even then it may not necessarily work
Add the following in your header:
headers: {
Accept : "application/json",
}
Also, keep in mind where you put equals (=) and where you put semicolons.
Related
I am posting to an API that seems to insist on receiving XML data as multipart/form-data with the name (file name?) xml. It works in postman but I can't get it to work using Python's requests. This is my Python code (based on https://stackoverflow.com/a/24443309/1011724):
requests.post(callpro_url,
files={'xml':('data.xml',result)},
verify=False).text
where result is a string containing XML. If I try this code I get the response:
xml post field is empty
which is the response this API give if you don't use the multipart/form-data header.
If I generate code from the working postman post I get something like this (slightly redacted):
import requests
url = "https://blablabla.blablab.com/blabla/api.php"
querystring = {"mode":"import","hash":"redacted-hash","xml":"\"xml\""}
payload = "------WebKitFormBoundary7MA4YWxkTrZu0gW\r\nContent-Disposition: form-data; name=\"xml\"\r\n\r\n<?xml version=\"1.0\" ?>\n<importdata>\n --redacted-XML-- \n</importdata>\n\r\n------WebKitFormBoundary7MA4YWxkTrZu0gW--"
headers = {
'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
'cache-control': "no-cache",
'postman-token': "8d3ec8ee-784e-3a65-5240-cf1a9534d1c4"
}
response = requests.request("POST", url, data=payload, headers=headers, params=querystring)
print(response.text)
Executing this code in Python, it gives the correct response.
Note that the params=querystring part in the postman code is taken care of in the URL in my code.
I'm confused by the payload in the postman code. It adds things like Content-Disposition and name in the string. I assume that I can put this stuff in the tuple in the files parameter but I'm not sure how to to do it. I've tried files={'xml':('data.xml',result,'form-data')} for example and also files={'xml':('data.csv',result)} and {'xml':('xml',result)}.
Also, the postman code explicitly defines the header as
'content-type': "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW"
whereas the requests documentation say that I should never explicitly define the headers in that way. However the postman code works and my code does not.
Any suggestions?
I don't know if this is worth answering or if I should delete the question but what was needed was to name the file "xml" not xml. so this works:
requests.post(callpro_url,
files={'xml':('"xml"',result)},
verify=False).text
I'm relatively new to Python so would like some help, I've created a script which simply use the request library and basic auth to connect to an API and returns the xml or Json result.
# Imports
import requests
from requests.auth import HTTPBasicAuth
# Set variables
url = "api"
apiuser = 'test'
apipass = 'testpass'
# CALL API
r = requests.get(url, auth=HTTPBasicAuth(apiuser, apipass))
# Print Statuscode
print(r.status_code)
# Print XML
xmlString = str(r.text)
print(xmlString)
if but it returns a blank string.
If I was to use a browser to call the api and enter the cretentials I get the following response.
<Response>
<status>SUCCESS</status>
<callId>99999903219032190321</callId>
<result xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Dummy">
<authorFullName>jack jones</authorFullName>
<authorOrderNumber>1</authorOrderNumber>
</result>
</Response>
Can anyone tell me where I'm going wrong.
What API are you connecting to?
Try adding a user-agent to the header:
r = requests.get(url, auth=HTTPBasicAuth(apiuser, apipass), headers={'User-Agent':'test'})
Although this is not an exact answer for the OP, it may solve the issue for someone having a blank response from python-requests.
I was getting a blank response because of the wrong content type. I was expecting an HTML rather than a JSON or a login success. The correct content-type for me was application/x-www-form-urlencoded.
Essentially I had to do the following to make my script work.
data = 'arcDate=2021/01/05'
headers = {
'Content-Type': 'application/x-www-form-urlencoded',
}
r = requests.post('https://www.deccanherald.com/getarchive', data=data, headers=headers)
print(r.status_code)
print(r.text)
Learn more about this in application/x-www-form-urlencoded or multipart/form-data?
Run this and see what responses you get.
import requests
url = "https://google.com"
r = requests.get(url)
print(r.status_code)
print(r.json)
print(r.text)
When you start having to pass things in your GET, PUT, DELETE, OR POST requests, you will add it in the request.
url = "https://google.com"
headers = {'api key': 'blah92382377432432')
r = requests.get(url, headers=headers)
Then you should see the same type of responses. Long story short,
Print(r.text) to see the response, then you once you see the format of the response you get, you can move it around however you want.
I have an empty response only when the authentication failed or is denied.
The HTTP status is still ≤ 400.
However, in the header you can find :
'X-Seraph-LoginReason': 'AUTHENTICATED_FAILED'
or
'X-Seraph-LoginReason': 'AUTHENTICATED_DENIED'
If the request is empty, not even a status code I could suggest waiting some time between printing. Maybe the server is taking time to return the response to you.
import time
time.sleep(5)
Not the nicest thing, but it's worth trying
How can I make a time delay in Python?
I guess there are no errors during execution
EDIT: nvm, you mentioned that you got a status code, I thought you were literally geting nothing.
On the side, if you are using python3 you have to use Print(), it replaced Print
I am trying to write a python script that will make a request to a desktop application listening to 8080 port. The below is the code that I use to make the request.
import requests
payload = {"url":"abcdefghiklmnopqrstuvwxyz=",
"password":"qertyuioplkjhgfdsazxvnm=",
"token":"abcdefghijklmn1254786=="}
headers = {'Content-Type':'application/json'}
r = requests.post('http://localhost:9015/login',params = payload, headers=headers)
response = requests.get("http://localhost:9015/login")
print(r.status_code)
After making the request, I get a response code of 401.
However, when I try the same using the Postman app, I get a successful response. The following are the details I give in Postman:
URL: http://localhost:9015/login
METHOD : POST
Headers: Content-Type:application/json
Body: {"url":"abcdefghiklmnopqrstuvwxyz=",
"password":"qertyuioplkjhgfdsazxvnm=",
"token":"abcdefghijklmn1254786=="}
Can I get some suggestions on where I am going wrong with my python script?
You pass params, when you should pass data, or, even better, json for setting Content-Type automatically. So, it should be:
import json
r = requests.post('http://localhost:9015/login', data=json.dumps(payload), headers=headers)
or
r = requests.post('http://localhost:9015/login', json=payload)
(params adds key-value pairs to query parameters in the url)
I am trying to trigger some builds using a shell script by doing the following :
export url='http://test.com';
export job_name='MY_JOB_NAME';
jso="{\"parameter\": [{\"name\":\"BRANCH\",\"value\":\"master\"}, {\"name\":\"GITURL\",\"value\":\"https://github.test.com/test/test.git\"}]}";
curl $url/job/$job_name/build --data-urlencode json="$jso";
This works fine, but when I try to convert it to a python equivalent, it doesn't seem to trigger the URL:
import requests
import json
url='http://test.com/job/MY_JOB_NAME/build'
params={'name':'release_1.5', 'GITURL':'https://github.test.com/test/test.git'}
payload = json.dumps(params)
resp = requests.get(url=url, data=payload)
This executes without any error, but it does not trigger a build on my CI machine.
There are quite a few things you're doing wrong here. The first thing which I hope is apparent is that the JSON data you're sending is completely different.
Beyond that, the primary issue you're having here is that your curl is doing a POST with urlencoded data in the BODY, and your python request is doing a GET with urlencoded data as separate parameters in the url. Change your .get to a .post, and the params= to data= and you should be a whole lot closer to your intended goal.
resp = requests.post(url=url, data={'json':payload})
Also note, I embedded your payload into a key as json, as that's what is happening in your curl. I'm not fully aware of your implementation details, but I hope that this helped put you on the right track.
Add the content-type to the header of the request, i.e.:
headers = {'content-type': 'application/json'}
...
resp = requests.get(url=url, params=payload, headers=headers)
I'm trying to create a super-simplistic Virtual In / Out Board using wx/Python. I've got the following code in place for one of my requests to the server where I'll be storing the data:
data = urllib.urlencode({'q': 'Status'})
u = urllib2.urlopen('http://myserver/inout-tracker', data)
for line in u.readlines():
print line
Nothing special going on there. The problem I'm having is that, based on how I read the docs, this should perform a Post Request because I've provided the data parameter and that's not happening. I have this code in the index for that url:
if (!isset($_POST['q'])) { die ('No action specified'); }
echo $_POST['q'];
And every time I run my Python App I get the 'No action specified' text printed to my console. I'm going to try to implement it using the Request Objects as I've seen a few demos that include those, but I'm wondering if anyone can help me explain why I don't get a Post Request with this code. Thanks!
-- EDITED --
This code does work and Posts to my web page properly:
data = urllib.urlencode({'q': 'Status'})
h = httplib.HTTPConnection('myserver:8080')
headers = {"Content-type": "application/x-www-form-urlencoded",
"Accept": "text/plain"}
h.request('POST', '/inout-tracker/index.php', data, headers)
r = h.getresponse()
print r.read()
I am still unsure why the urllib2 library doesn't Post when I provide the data parameter - to me the docs indicate that it should.
u = urllib2.urlopen('http://myserver/inout-tracker', data)
h.request('POST', '/inout-tracker/index.php', data, headers)
Using the path /inout-tracker without a trailing / doesn't fetch index.php. Instead the server will issue a 302 redirect to the version with the trailing /.
Doing a 302 will typically cause clients to convert a POST to a GET request.