Python's request.get only show 200 status - python

I'm trying to workd with the Cisco Prime API, and it seems to work when using Postman (the output is an xml file). However, when I try to reproduce the same with Python:
request.get(url, verify=False, auth=credentials)
print(response)
the only response I get is <Response [200]> (and a warning for disabling SSL, but that's not relevant)... I use requests.auth.HTTPBasicAuth to generate the "crdentials" variable

You need to get with
print(response.json())
Or
print(response.text)

Well, of course, it's just after posting this that I found the answer: first, you need to search for the json, not the xml and second, when you want to cast the json, you need do
response.json()

do like this to get a response as text
response = request.get(url, verify=False, auth=credentials)
print response.text
that's it best luck

Related

Request returns hidden characters

I am using requests.get to read a JSON object. The string downloaded is just a URL to download. I try to feed it in using requests.get(), but I get a 404 error. However, when I hardcode the value and run a requests.get(), I get a 200 response. Here is the pseudocode:
response = requests.get(repository, headers=headers, data=data)
pod_map = json.loads(response.text)['locationMap']
for key in pod_map.keys():
url = pod_map["key"] #url should be something like http://mylink.com
response = requests.get(url)
print response.status_code
The problem is that I when I run the code like this, I get a 404. However, when I just copy/paste url into a variable, I get a 200. Is there something I am missing with regards to encoding/decoding the JSON?

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

Using requests in Python to process GET request

I posted another question but made a bit of a mess of it in the comments section. Basically, I am trying to use the requests library in Python in order to accomplish what I normally would by using CURL in order to process a GET request to an API. From what I have learned from a very helpful person here, I can process the request, as well as the authorisation header by doing the following:
Original CURL Command that I would normally use:
curl -X GET -H 'Authorization: exapi:111:58d351234e1a:LA2' 'http://api.example.com/v1.14/user?id=1234'
This is the Python code I am using for my script:
import requests
import json
url = "http://api.example.com/v1.14/user?id=1234"
headers = {"Authorization": "exapi:111:58d351234e1a:LA2"}
response = requests.get(url, headers=headers)
print response.json
However, when I run my code, I receive bound method response.json of <response [200]> instead of data that I was expecting from the GET. Can someone help me figure out what I am doing wrong here? I am guessing that I am doing something wrong with my header but I am not sure.
As #juanpa.arrivilaga has already mentioned and as the printed message clearly says, you need to call the bound json method. The source of confusion is likely from content, which is an attribute.
response.json() # method
response.content # attribute
How about using json module explicitly:
data = json.loads(response.text)
print data

Python REST API Issues

I am working on a tool that queries a number of APIs, one of which is a RESTful API. All of the other functions (API calls) of my program work fine with requests.get(), however with the REST API, I do not seem to be able to access the actual content of the response, only the status code. i.e. when I simply print the response, (not response.status_code) I get: <Response [200]> output to the screen. Any ideas?
Snippet of code:
# The URL is correct in my program, For sure.
url = ('http://APIurl/%s' % entry)
try:
response = requests.get(url)
# prints <Response [200]>
print response
# Fails, expecting JSON that isn't there
results.append(response.json())
print the response object's attributes to see what it has available:
print response.__dict__
response.text is your friend, if the content is not valid json.
You need to print response.context or response.text. Your data is probably there.
Sometimes when your request is wrong, the API returns the whole error page (in HTML). So if you're getting a bunch of HTML code, make sure you're request parameters are ok.

Executing URLs in Python similar to curl in Linux - JenkinsAPI

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)

Categories

Resources