Requests POST data not being appended to url - python

I am trying to send a simple POST request to a server using requests. I am doing (I think at least) exactly what the quickstart (http://docs.python-requests.org/en/master/user/quickstart/) is saying to do. The POST request seems to be ignoring the data= tag and not appending the data to the end of the url. This is what I have:
import requests, json
url = 'http://localhost:5000/todo/api/v1.0/tasks'
payload = (('key1', 'value1'), ('key1', 'value2'))
r=requests.post(url, data=payload)
print 'url is: ', r.url
and the output is:
url is: http://localhost:5000/todo/api/v1.0/tasks
I don't know if it is relevant or not, but if I use the GET tag params=, the url is assembled as I expect:
r=requests.post(url, params=payload)
url is: http://localhost:5000/todo/api/v1.0/tasks/?key1=value&key1=value2
Anyone see anything wrong? Thanks in advance

Try to dump payload to json and use a dict
payload = {}
payload[key1] = value1
payload[key2] = value2
payload_data = json.dumps(payload)
r=requests.post(url, data=payload_data)

POST data is passed in the body of the request, not the URL. A POST HTTP request looks something like this
POST /login HTTP/1.1
Host: example.com
Content-Length: <length>
firstname=john&lastname=doe
So as you can see the URL does not get passed these parameters and this is important for a lot of reasons that I won't mention in this answer. However, if for some reason you do need to pass these parameter in the URL instead of the body of the request then here is oh you might do it.
import requests, urllib
url = 'http://localhost:5000/todo/api/v1.0/tasks'
payload = (('key1', 'value1'), ('key1', 'value2'))
request_data = urllib.urlencode(payload) # Turns it into key1=value1&key1=value2
response = requests.post(url + "?" + request_data)
That will craft the request in the same way that you see it in the GET request that you have at the bottom of your answer, but instead as a POST request.

Related

Web-scraping on Python

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.

Parse values in the url not working(HTTP Error 405: Method Not Allowed)

Greetings Team Good Day,
I am using the urlib code to print the response data but getting the HTTP error, I have attached the error screenshot and the code in the post, request your advise.
enter image description here
import urllib.parse
import urllib.request
url = 'https://www.google.com/search'
values = {'q': 'python programming tutorials'}
data = urllib.parse.urlencode(values)
data = data.encode('utf-8')
request = urllib.request.Request(url, data)
response = urllib.request.urlopen(request)
HTTPError: HTTP Error 405: Method Not Allowed
You're using a POST method, which is not allowed in this url:
>> request.get_method()
'POST'
Google search expects a GET.
Every time you include the data in the request, it will automatically be a POST. But instead, you can do this directly:
response = urllib.request.urlopen('{0}?{1}'.format(url, data))

Python request resulting in blank response

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

API Post Python

I am trying to make a post request within the Matchbook API.
I have logged in and I got below "Session- Tocken":
{"session-token":"xxxx_b0b8a6f22a82396b6afcfa344f3022","user-id":xx685,"role":"USER"}
However, I am not sure how to make the post request. See below code used:
headers = {"session-token" : "xxxx_b0b8a6f22a82396b6afcfa344f3022"}
r = requests.post('https://api.matchbook.com/edge/rest/reports/v1/offers/current/?odds-type=DECIMAL&exchange-type=binary&currency=EUR, headers = headers')
print r.text
Below is the error message that I got. It does not make sense to me because I logged in successfully and got the above session-token in response.
{"errors":[{"messages":["You are not authorised to access this resource. Login to continue."]}]}
Am I properly indicating the session-token in the header information of the post request?
You need to pass headers argument in post function.
headers = {"session-token" : "xxxx_b0b8a6f22a82396b6afcfa344f3022"}
response = requests.post('https://api.matchbook.com/edge/rest/reports/v1/offers/current/?odds-type=DECIMAL&exchange-type=binary&currency=EUR', headers=headers)
also if you need to get an json response, just call json() function on response variable.
something like response.json()

Making a successful Python HTTP POST Request

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)

Categories

Resources