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
Related
Why I'm getting different responses when i use urllib.request.urlopen and requests.get
import requests
r = requests.get('https://upload.wikimedia.org/wikipedia/commons/1/14/Sunset_Boulevard_%281950_poster%29.jpg')
r.status_code
response 403
from urllib.request import urlopen
r = urlopen('https://upload.wikimedia.org/wikipedia/commons/1/14/Sunset_Boulevard_%281950_poster%29.jpg')
r.getcode()
response 200
First you could check print( r.content ) to see what you get from server.
Usually you can get some explanation which can help to see problem.
For your code it shows problem with header User-Agent
Wikipedia: User-Agent policy
Some servers check header User-Agent to send different content for different systems/browsers/devices. They use it also to detect scripts/bots/spamers/hackers and block them.
If I use header from real browser (or at least short Mozilla/5.0) then it works.
import requests
headers = {'User-Agent': 'Mozilla/5.0'}
url = 'https://upload.wikimedia.org/wikipedia/commons/1/14/Sunset_Boulevard_(1950_poster).jpg'
#url = 'https://upload.wikimedia.org/wikipedia/commons/1/14/Sunset_Boulevard_%281950_poster%29.jpg'
r = requests.get(url, headers=headers)
print(r.status_code)
print(r.content[:100])
with open('image.jpg', 'wb') as fh:
fh.write(r.content)
EDIT:
After running code few times it start working for me even without User-Agent. Maybe they checked it for some different reason.
This works fine, I can get data returned:
r = urllib2.Request("http://myServer.com:12345/myAction")
data = json.dumps(q) #q is a python dict
r.add_data(data)
r=urllib2.urlopen(r)
But doing the same with requests package fails:
r=requests.get("http://myServer.com:12345/myAction", data=q)
r.text #This will return a message that says method is not allowed.
It works if I make it a post request: r=requests.post("http://myServer.com:12345/myAction", data=json.dumps(q))
But why?
According to the urllib2.urlopen documentation:
the HTTP request will be a POST instead of a GET when the data parameter is provided.
This way, r=urllib2.urlopen(r) is also making a POST request. That is why your requests.get does not work, but requests.post does.
Set up a session
import session
session = requests.Session()
r = session.get("http://myServer.com:12345/myAction", data=q)
print r.content (<- or could us r.raw)
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.
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 tried to connect HP QC using python to create defects and attach files, but I am not able to connect with HP QC. Here is my code:
domain='DEFAULT_773497139'
project='773497139_DEMO'
import requests
url = "https://almalm1250saastrial.saas.hpe.com/qcbin/"
querystring = {"username":"user#gmail.com","password":"password"}
headers = {
'cache-control': "no-cache",
'token': "5d33d0b7-1d04-4989-3349-3005b847ab7f"
}
response = requests.request("POST", url, headers=headers, params=querystring)
#~ print(response.text)
print response.headers
new_header = response.headers
new_url = url+ u'rest/domains/'+domain+u'/projects/'+project
new_querystring = {
"username":"user#gmail.com",
"password":"password",
"domain":'DEFAULT_773497139',
"project":'773497139_DEMO'
}
print new_url
response = requests.request("POST", new_url, headers=new_header, params=new_querystring)
print(response.text)
Now login works fine, but when try other API it asks for, I would get this message:
Authentication failed. Browser based integrations - to login append '?login-form-required=y' to the url you tried to access
If the parameter has been added, then it goes back to login page.
Seems that your urls are not well builded:
base_url ='https://server.saas.hpe.com/qcbin/'
base_url + '/qcbin/rest/domains/
you will get:
..../qcbin/qcbin/...
qcbin twice
The way I do it is to based on python request Sessions. First I create a session, then post my credentials to ../authentication-point/alm-authenticate/ (or sth like this, you should check it) and then using this session I can get, post or do whatever I want.
So:
s = requests.Session()
s.post(`../authentication-point/alm-authenticate/`, data=credentials)
# now session object is authenticated and recognized
# you can s.post, s.get or whatever
I think it's a good url, but I can't check it right now :)
Session issue has beensolved by LWSSO cookie (LWSSO_COOKIE_KEY).
Just send a unicode string to your server and use the header for the basic Authorization as specified by the HP REST API:
login_url = u'https://almalm1250saastrial.saas.hpe.com/qcbin/authentication-point/authenticate'
username,password = user,passwd
logs = base64.b64encode("{0}:{1}".format(username, password))
header['Authorization'] = "Basic {}".format(logs)
POST by using the requests module in python is quite easy:
requests.post(login_url, headers=header)
That's it...now you are authenticated and you can proceed with next action :-) To check on that you can "GET" on:
login_auth = u'https://almalm1250saastrial.saas.hpe.com/qcbin/rest/is-authenticated
you should get a code 200 --> That means you are authenticated.
Hope this help you. Have a nice day and let me know if something is still not clear.
p.s.: to send REST msg in python I am using requests module. It is really easy! You can create a session if you want to send multiple actions--> then work with that sessions--> ALM = requests.session(), then use ALM.post(whatever) and so on :-)