Python Requests API call not working - python

I'm having an issue converting a working cURL call to an internal API to a python requests call.
Here's the working cURL call:
curl -k -H 'Authorization:Token token=12345' 'https://server.domain.com/api?query=query'
I then attempted to convert that call into a working python requests script here:
#!/usr/bin/env python
import requests
url = 'https://server.domain.com/api?query=query'
headers = {'Authorization': 'Token token=12345'}
r = requests.get(url, headers=headers, verify=False)
print r
I get a HTTP 401 or 500 error depending on how I change the headers variable around. What I do not understand is how my python request is any different then the cURL request. They are both being run from the same server, as the same user.
Any help would be appreciated

Hard to say without knowing your api, but you may have a redirect that curl is honoring that requests is not (or at least isn't send the headers on redirect).
Try using a session object to ensure all requests (and redirects) have your header.
#!/usr/bin/env python
import requests
url = 'https://server.domain.com/api?query=query'
headers = {'Authorization': 'Token token=12345'}
#start a session
s = requests.Session()
#add headers to session
s.headers.update(headers)
#use session to perform a GET request.
r = s.get(url)
print r

I figured it out, it turns out I had to specify the "accept" header value, the working script looks like this:
#!/usr/bin/env python
import requests
url = 'https://server.domain.com/api?query=query'
headers = {'Accept': 'application/app.app.v2+json', 'Authorization': 'Token token=12345'}
r = requests.get(url, headers=headers, verify=False)
print r.json()

Related

Post requests in python vs curl

Can someone please suggest the correct syntax for calling the below using python?
curl "https://sometest.api.token" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=client_credentials&client_id={client_id}&client_secret={client_secret}"
My attempt:
import requests
import json
credentials='1111'
secret='2222'
url = 'https://sometest.api.token'
body = {'client_credentials':credentials,'client_secret':secret}
headers = {'Content-type': 'application/x-www-form-urlencoded'}
r = requests.post(url, data=json.dumps(body), headers=headers)
Due to documentation, if you want to send some form-encoded data, you simply pass a dictionary to the data argument.
So you have to try:
import requests
import json
credentials='1111'
secret='2222'
url = 'https://sometest.api.token'
body = {'client_credentials':credentials, 'client_secret':secret}
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
r = requests.post(url, data=body, headers=headers)
And also your parameters in python code are different from parameters in curl, maybe you have to check it.

how to fetch data from API using python

I have to get data from rest api using python. how to send headers to retrieve data from API. is there any module for requesting data from API.
Try requests it has two method get() and post()
Please try:
import requests
import json
res = requests.get('paste your link here')
response = json.loads(res.text)
Previous answers have covered the idea behind how to fetch data from an API using python. Requests library is a natural selection if you want to achieve this.
Documentation and ref: https://requests.readthedocs.io/en/master/
Installation: pip install requests or https://requests.readthedocs.io/en/master/user/install/#install
Coming to the last part - how to send headers to retrieve data from API?
You can pass headers as dictionary to the request.
url = 'https://api.github.com/some/endpoint'
headers = {'user-agent': 'my-app/0.0.1'}
response = requests.get(url, headers=headers)
Now you have the response object in response variable; now it's up to you what you want to achieve. e.g. If you want to see what is the response body as String;
print(response.text)
Yes python has requests lib to make a call to POST and GET methods
e.g.
import requests
url = 'web address'
params = {'key':'value'}
r = requests.get(url = url, params = params)
response = r.json()

How to add headers and body to a python request

I created a GET request in Python for an API and I would like to add headers and body
import urllib2
import os
proxy = 'http://26:Do#proxy:8080'
os.environ['http_proxy'] = proxy
os.environ['https_proxy'] = proxy
os.environ['HTTP_PROXY'] = proxy
os.environ['HTTPS_PROXY'] = proxy
contents = urllib2.urlopen("https://xxxx/lista?zile=50 ").read()
I tried in Postman and I received a response and I would like to receive the same response in python. How can I add headers and body ?
Thanks in advance
You can use the urlopen function with a Request object:
https://docs.python.org/2/library/urllib2.html#urllib2.urlopen
This Request object can contain headers and body:
https://docs.python.org/2/library/urllib2.html#urllib2.Request
Example: https://docs.python.org/2/howto/urllib2.html#data
P.S: HTTP GET requests don't have a body. Maybe you meant POST or PUT?
the best way is to use the request library which is pretty simple to use. https://realpython.com/python-requests/
example:
import requests
headers = {'Content-Type': 'application/json'}
data_json = {"some_key": "some_value"}
response = requests.post("https://xxxx/lista?zile=50", headers=headers, json=data_json)

How to use Python requests module and TeamCity API to trigger a build?

There is a cURL example in section Triggering a Build of TeamCity 9.x Documentation:
curl -v -u user:password http://teamcity.server.url:8111/app/rest/buildQueue --request POST --header "Content-Type:application/xml" --data-binary #build.xml
I'd like to know how to convert it into an equivalent Python script (using POST request from the requests module)?
BTW, I tried the following Python script but got such a response code 400 (Bad Request):
url = "http://myteamcity.com:8111/httpAuth/app/rest/buildQueue/"
headers = {'Content-Type': 'application/json'}
data = json.dumps({'buildTypeId': 'MyTestBuild'})
r = requests.post(url, headers=headers, data=data, auth=("username", "password"), timeout=10)
print "r = ", r
>> r = <Response [400]>
If change the Content-Type in headers into Accept, got another response code 415 (Unsupported Media Type):
headers = {'Accept': 'application/json'}
>> r = <Response [415]>
The documentation for triggering a build shows you need to send XML, not JSON:
<build>
    <buildType id="buildConfID"/>
</build>
The TeamCity REST API is a bit of a mixed bag; some methods accept both XML and JSON, some only accept XML. This is one of those latter methods. They'll respond with either XML or JSON, based on what you set the Accept header to.
Send the above with your required build ID; for an XML document that simply you could use templating:
from xml.sax.saxutils import quoteattr
template = '<build><buildType id={id}/></build>'
url = "http://myteamcity.com:8111/httpAuth/app/rest/buildQueue/"
headers = {'Content-Type': 'application/xml'}
build_id = 'MyTestBuild'
data = template.format(id=quoteattr(build_id))
r = requests.post(url, headers=headers, data=data, auth=("username", "password"), timeout=10)
Note that I used the xml.sax.saxutils.quotattr() function to make sure the value of build_id is properly quoted for inclusion as a XML attribute.
This'll produce XML; add 'Accept': 'application/json' to the headers dictionary if you want to process a JSON response.
FYI json request works in TeamCity 10.
Since this question was written & answered, a contemporary OSS alternative now exists: pyteamcity.
Pip command to install (or add pyteamcity to requirements.txt, etc.)
pip install pyteamcity
Code:
from pyteamcity import TeamCity
tc = TeamCity('username', 'password', 'server', 'port')
result = tc.trigger_build('build_id')
print(f'Build triggered. Web URL: {result['webUrl']}')

BLS API data using cURL and requests library?

All, I'm trying to implement a curl request to get data from the BLS. Following their example here (they show the curl request), my code looks like this:
import requests
headers = {'Content-type': 'application/json'}
params = {"seriesid":["LEU0254555900", "APU0000701111"],"startyear":"2002", "endyear":"2012"}
p = requests.post('http://api.bls.gov/publicAPI/v1/timeseries/data/', params = params,headers = headers)
print p.url
print p.content
I'm getting the following (error) output:
http://api.bls.gov/publicAPI/v1/timeseries/data/?seriesid=LEU0254555900&seriesid=APU0000701111&endyear=2012&startyear=2002
{"status":"REQUEST_FAILED","responseTime":0,"message":["Sorry, an
internal error occurred. Please check your input parameters and try
your request again."],"Results":null}
Anyone had to deal with the BLS api and python?
Is the requests library the best for this?
You need to send the data as json, not pass it as a params dict. params sets the url parameters, which is not what you want, you need to pass it as data.
This should work:
import requests
import json
headers = {'Content-type': 'application/json'}
data = json.dumps({"seriesid":["LEU0254555900", "APU0000701111"],"startyear":"2002", "endyear":"2012"})
p = requests.post('http://api.bls.gov/publicAPI/v1/timeseries/data/', data=data, headers=headers)
print p.url
print p.content

Categories