How should I send HTTP request with custom method in python - python

I need to send HTTP request with custom method to a custom server. I've been googling about executing curl command in python, and mostly I've found:
Don't do that!
I need to execute the following curl command:
curl -X MUX -i -H "Connection-Service: API" -H "Service-Address: API" http://172.16.117.40
I've been trying with requests library in python with no luck.

I constructed this solution from various stackoverflow answers:
import httplib, urllib2
httplib.HTTPConnection._http_vsn = 10
httplib.HTTPConnection._http_vsn_str = 'HTTP/1.0'
opener = urllib2.build_opener(urllib2.HTTPHandler)
request = urllib2.Request(self.url)
request.add_header('Connection-Service', 'API')
request.add_header('Service-Address', 'API')
request.get_method = lambda: 'MUX'
url = opener.open(request)
url.info().getheader('API')
It works as curl command posted in the question and I don't need to mess with the actual command.

Related

Curl works but python requests doesn't

When I do curl, I get a response:
root#3d7044bac92f:/home/app/tmp# curl -H "Content-type: application/json" -X GET https://github.com/timeline.json -k
{"message":"Hello there, wayfaring stranger. If you\u2019re reading this then you probably didn\u2019t see our blog post a couple of years back announcing that this API would go away: http://git.io/17AROg Fear not, you should be able to get what you need from the shiny new Events API instead.","documentation_url":"https://developer.github.com/v3/activity/events/#list-public-events"}
However, when I do python requests to the same URL I get a status 410.
import requests
headers = {
'Content-type': 'application/json',
}
r = requests.get('https://github.com/timeline.json')
print r.json
root#3d7044bac92f:/home/app/tmp# python rest.py
<bound method Response.json of <Response [410]>>
What gives?
The host is a standard Ubuntu docker image and only installed Curl and some python modules. Python -V is 2.7
Note: I looked at this question but I can't telnet into above server so that solution doesn't apply to me:
Curl works but not Python requests
You've made at least two errors in your program.
1) You haven't specified the data= or headers parameters to the requests.get() call. Try this:
r = requests.get('https://github.com/timeline.json', data=data, headers=headers)
2) .json is a method, not a data attribute of the response object. As a method, it must be called in order to be effective. Try this:
print r.json()

How to send data on a curl redirect?

I have an API which is currently on HTTP, I moved the API using SSLify library in python flask.
Now when I send data using curl request
curl -v -k -H "Content-Type: application/json" -X POST \
--data '{"title":"foobar","body": "This body"}' \
-L http://X.Y.Z.W.us-west-2.compute.amazonaws.com/test
It returns an empty string to me by using request.data
If I make the request to begin with https it returns correct value. If there is a redirect how can I send data ?
SSLify issues a 301 or 302 redirect status code depending on your configuration. So you need to pass --post301 or --post302 to curl.
The reason for this can be found in the curl man page:
When curl follows a redirect and the request is not a plain GET (for
example POST or PUT), it will do the following request with a GET
if the HTTP response was 301, 302, or 303. If the response code was
any other 3xx code, curl will re-send the following request using
the same unmodified method.
You can tell curl to not change the non-GET request method to GET
after a 30x response by using the dedicated options for that: --post301, --post302 and -post303.

How to make curl post request from python

I am trying to make a post request using curl in python but the below script throws error
import os
first_name1 = "raj"
last_name1 = "kiran"
full_name = "raj kiran"
headline = "astd"
location1 = "USA"
current_company1 = "ss"
curl_req = 'curl -X POST -H "Content-Type: application/json" -d '{"first_name":"{0}","last_name":"{1}","current_company":"{2}","title":"{3}","campus":"","location":"{4}","display_name":"{5}","find_personal_email":"true"}' http://localhost:8090'.format(first_name1,last_name1,current_company1,headline,location1,full_name)
os.popen(curl_req)
Error:
SyntaxError: invalid syntax
How to make above program work?
The problem in your code is the quotes. Change it to:
curl_req = '''curl -X POST -H "Content-Type: application/json" -d '{"first_name":"{0}","last_name":"{1}","current_company":"{2}","title":"{3}","campus":"","location":"{4}","display_name":"{5}","find_personal_email":"true"}' http://localhost:8090'''.format(first_name1,last_name1,current_company1,headline,location1,full_name)
But, as mentioned in the comments, requests will always be a better choice.
Requests syntax:
import requests
post_data = {
# all the data you want to send
}
response = requests.post('http://localhost:8090', data=post_data)
print response.text
One good resource I've used for converting a cURL request to Python requests is curlconverter. You can enter your cURL request and it will format it for Python requests.
As a side note, it can also convert for PHP and Node.js.
Hope that helps!

Rest API authentication and access using Python Requests

I have been regularly accessing an API at work using curl. But now i need to do a bit of automation for the same.
Was trying to translate what i do with curl into python using the requests module.
But I keep receiving a 401 error.
My curl requests that i regularly are as below:
Step1: Session Authentication with cookies:
curl -b cookies -c cookies -v -X POST -H "Content-Type: application/json" --data-binary '{"auth":{"username":"aaa","password":"bbb"}}' http://api.xyz.at/auth
Step2: Access API URL for data retrieval
curl -b cookies -c cookies http://api.xyz.at/somepage?per_id=556677
Now using Python Requests, here is what I am doing
Step1: For Authentication
username = 'aaa'
password = 'bbb'
s = requests.Session()
s.post('http://api.xyz.at/auth',auth=('username','pasword'))
This "i think" works fine, and give me the below response
<Response [200]>
Step2: Access API URL for data retrieval
s.get('http://api.xyz.at/somepage?per_id=556677')
but this Step 2 keeps returning an error
<Response [401]>
The code is failing and not sure where.
My Python skills are visibly pedestrian. I have been looking at the Requests website. But unfortunately haven't been able to decipher.
Guidance would be appreciated :)
import urllib2, urllib
url = 'http://api.xyz.at/auth'
pm = urllib2.HTTPPasswordMgrWithDefaultRealm()
pm.add_password(None, url, 'user', 'password')
auth = urllib2.HTTPBasicAuthHandler(pm)
opener = urllib2.build_opener(auth)
urllib2.install_opener(opener)
request = urllib2.Request('http://api.xyz.at/somepage?per_id=556677', None)
handler = urllib2.urlopen(request)
handler.read()
Since you are getting a 401 error I guess you are not passing the authentication token which you get as response from login API. Use the same auth token to perform other options - Get-post-Delete.

How to use Python to execute a cURL command?

I want to execute a curl command in Python.
Usually, I just need to enter the command in the terminal and press the return key. However, I don't know how it works in Python.
The command shows below:
curl -d #request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere
There is a request.json file to be sent to get a response.
I searched a lot and got confused. I tried to write a piece of code, although I could not fully understand it and it didn't work.
import pycurl
import StringIO
response = StringIO.StringIO()
c = pycurl.Curl()
c.setopt(c.URL, 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere')
c.setopt(c.WRITEFUNCTION, response.write)
c.setopt(c.HTTPHEADER, ['Content-Type: application/json','Accept-Charset: UTF-8'])
c.setopt(c.POSTFIELDS, '#request.json')
c.perform()
c.close()
print response.getvalue()
response.close()
The error message is Parse Error. How to get a response from the server correctly?
For the sake of simplicity, you should consider using the Requests library.
An example with JSON response content would be something like:
import requests
r = requests.get('https://github.com/timeline.json')
r.json()
If you look for further information, in the Quickstart section, they have lots of working examples.
For your specific curl translation:
import requests
url = 'https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere'
payload = open("request.json")
headers = {'content-type': 'application/json', 'Accept-Charset': 'UTF-8'}
r = requests.post(url, data=payload, headers=headers)
Use curlconverter.com. It'll convert almost any curl command into Python, Node.js, PHP, R, Go and more.
Example:
curl -X POST -H 'Content-type: application/json' --data '{"text":"Hello, World!"}' https://hooks.slack.com/services/asdfasdfasdf
becomes this in Python
import requests
json_data = {
'text': 'Hello, World!',
}
response = requests.post('https://hooks.slack.com/services/asdfasdfasdf', json=json_data)
curl -d #request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere
its Python implementation looks like this:
import requests
headers = {
'Content-Type': 'application/json',
}
params = {
'key': 'mykeyhere',
}
with open('request.json') as f:
data = f.read().replace('\n', '')
response = requests.post('https://www.googleapis.com/qpxExpress/v1/trips/search', params=params, headers=headers, data=data)
Check this link, it will help convert cURL commands to Python, PHP and Node.js
import requests
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
data = requests.get(url).json
maybe?
if you are trying to send a file
files = {'request_file': open('request.json', 'rb')}
r = requests.post(url, files=files)
print r.text, print r.json
ahh thanks #LukasGraf now i better understand what his original code is doing
import requests,json
url = "https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere"
my_json_data = json.load(open("request.json"))
req = requests.post(url,data=my_json_data)
print req.text
print
print req.json # maybe?
My answer is WRT python 2.6.2.
import commands
status, output = commands.getstatusoutput("curl -H \"Content-Type:application/json\" -k -u (few other parameters required) -X GET https://example.org -s")
print output
I apologize for not providing the required parameters 'coz it's confidential.
I had this exact question because I had to do something to retrieve content, but all I had available was an old version of Python with inadequate SSL support. If you're on an older MacBook, you know what I'm talking about. In any case, curl runs fine from a shell (I suspect it has modern SSL support linked in) so sometimes you want to do this without using requests or urllib.request.
You can use the subprocess module to execute curl and get at the retrieved content:
import subprocess
# 'response' contains a []byte with the retrieved content.
# use '-s' to keep curl quiet while it does its job, but
# it's useful to omit that while you're still writing code
# so you know if curl is working
response = subprocess.check_output(['curl', '-s', baseURL % page_num])
Python 3's subprocess module also contains .run() with a number of useful options.
I use os library.
import os
os.system("sh script.sh")
script.sh literally only contains the curl.
PYTHON 3
Only works within UNIX (Linux / Mac) (!)
Executing a cURL with Python 3 and parsing its JSON data.
import shlex
import json
import subprocess
# Make sure that cURL has Silent mode (--silent) activated
# otherwise we receive progress data inside err message later
cURL = r"""curl -X --silent POST http://www.test.testtestest/ -d 'username=test'"""
lCmd = shlex.split(cURL) # Splits cURL into an array
p = subprocess.Popen(lCmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate() # Get the output and the err message
json_data = json.loads(out.decode("utf-8"))
print(json_data) # Display now the data
Sometimes you also need to install these dependencies on UNIX if you experience strange errors:
# Dependencies
sudo apt install libcurl4-openssl-dev libssl-dev
sudo apt install curl
use requests lib.. this code is :
curl -LH "Accept: text/x-bibliography; style=apa" https://doi.org/10.5438/0000-0C2G
equal to this:
import requests
headers = {
'Accept': 'text/x-bibliography; style=apa',
}
r = requests.get('https://doi.org/10.5438/0000-0C2G', headers=headers)
print(r.text)
if you os supporting curl you can do something like this:
import os
os.system("curl -d #request.json --header "Content-Type: application/json" https://www.googleapis.com/qpxExpress/v1/trips/search?key=mykeyhere")
I'm using this way... And I think you can use this too!
by the way.. the module "os" is auto-installing when you install python.
soo, you don't need to install packages ;)
This is one approach:
Import os
import requests
Data = os.execute(curl URL)
R= Data.json()

Categories

Resources