Make POST request using Python - python

I am trying to make a POST request But getting this error :
Traceback (most recent call last):
File "demo.py", line 7, in <module>
r = requests.post(url, data=payload, headers=headers)
File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 87, in post
return request('post', url, data=data, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/api.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 266, in request
prep = req.prepare()
File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 215, in prepare
p.prepare_body(self.data, self.files)
File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 338, in prepare_body
body = self._encode_params(data)
File "/usr/local/lib/python2.7/dist-packages/requests/models.py", line 74, in _encode_params
for k, vs in to_key_val_list(data):
ValueError: too many values to unpack
This is my program :
import requests
url = 'http://www.n-gal.com/index.php?route=openstock/openstock/optionStatus'
payload = {'var:1945,product_id:1126'}
headers = {'content-type': 'application/x-www-form-urlencoded'}
r = requests.post(url, data=payload, headers=headers)
I have tried the same POST request through Advanced rest client using following data :
URL : http://www.n-gal.com/index.php?route=openstock/openstock/optionStatus
payload : var=1945&product_id=1126
Content-Type: application/x-www-form-urlencoded
And it is working fine can anyone help me please...

You have made payload a set, not a dictionary. You forgot to close the string.
Change:
payload = {'var:1945,product_id:1126'}
To:
payload = {'var':'1945','product_id':'1126'}
As it is a set, the request will thus fail.

Try this :
import requests
url = 'http://www.n-gal.com/index.php?route=openstock/openstock/optionStatus'
payload = 'var=1945&product_id=1126'
headers = {'content-type': 'application/x-www-form-urlencoded'}
r = requests.post(url, data=payload, headers=headers)
print r.json()

import requests
import json
url = 'http://www.n-gal.com/index.php?route=openstock/openstock/optionStatus'
payload = {'var:1945,product_id:1126'}
headers = {'content-type': 'application/x-www-form-urlencoded'}
r = requests.post(url, data=json.dumps(payload), headers=headers)

I know this is a really old question, but I had the same problem when using Docker recently, and managed to solve it by including the requests library in the requirements (or just update the library with pip install requests --upgrade).
When using the original version of the requests library, it raised that very same error on Python3.8, which only stopped after upgrading it.

Related

How to fix Python code returning TypeError: 'str' object is not callable?

i've been trying to send a POST HTTP request using Python (first time using it) and it keeps returning a TypeError: 'str' object is not callable
My code:
import requests
import json
c100 = "100";
url ="http://api.orange.com/smsmessaging/v1/outbound/tel+21654614211/requests"
payload = {
"outboundSMSMessageRequest": {
"address": "tel+21653424499",
"outboundSMSTextMessage": {
"message": "Capteur "+ c100 +" est en incendie"
},
"senderAddress": "tel+21654614211",
"senderName": "GCI"
}
}
headers = {'content-type': 'application/json'}
r = requests.post(url, auth=('Basic <omitted>'), data=json.dumps(payload), headers=headers)
output:
Traceback (most recent call last):
File "main.py", line 18, in <module>
r = requests.post(url, auth=('Basic U0cwUE1aeGZmZ0JLbUkzWUV2ZWlsM0xBdEt0UVZ4Q1k6SVRqWXQxRU5nWlV4SGM5OQ=='), data=payload, headers=headers)
File "/usr/lib/python3/dist-packages/requests/api.py", line 88, in post
return request('post', url, data=data, **kwargs)
File "/usr/lib/python3/dist-packages/requests/api.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 433, in request
prep = self.prepare_request(req)
File "/usr/lib/python3/dist-packages/requests/sessions.py", line 371, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/usr/lib/python3/dist-packages/requests/models.py", line 291, in prepare
self.prepare_auth(auth, url)
File "/usr/lib/python3/dist-packages/requests/models.py", line 470, in prepare_auth
r = auth(self)
TypeError: 'str' object is not callable
your Authentication is wrong, and also the question is: do You need authentication at all?
Basic Authentication Many web services that require authentication accept HTTP Basic Auth. This is the simplest kind, and Requests
supports it straight out of the box.
Making requests with HTTP Basic Auth is very simple:
>>> from requests.auth import HTTPBasicAuth
>>> requests.get('https://api.github.com/user', auth=HTTPBasicAuth('user', 'pass'))
<Response [200]>
In fact, HTTP Basic Auth is so common that Requests provides a handy
shorthand for using it:
>>> requests.get('https://api.github.com/user', auth=('user', 'pass'))
<Response [200]>
Providing the credentials in a tuple like this is exactly the same as
the HTTPBasicAuth example above.
NOTE:
if you have token probably you need something like:
import requests
auth_token='sdasadadsadas'
head = {'Authorization': 'Bearer ' + auth_token}
payload = {
"outboundSMSMessageRequest": {
"address": "tel+21653424499",
"outboundSMSTextMessage": {
"message": "Capteur "+ c100 +" est en incendie"
},
"senderAddress": "tel+21654614211",
"senderName": "GCI"
}
}
url = 'http://api.orange.com/smsmessaging/v1/outbound/tel+21654614211/requests'
response = requests.post(url, json = payload, headers=head)
The authentication parameter in your original code is wrong. If you remove it, it will work.
r = requests.post(url, data=json.dumps(payload), headers=headers)

Correct way to return JSON response from POST request with web.py

I have a web.py server.
I handle post requests like this:
class Endpoint(object):
def POST(self):
received_payload = web.data()
# Do things with the payload (a JSON) --- I receive the payload correctly
response = {"Response": "Good"}
# I also tried returning the dictionary directly and building my own requests.Response object
return json.dumps(response)
I am able to correctly receive and process the payload I send to the server, but I do not receive the response.
On the client side, I do this:
s = requests.Session()
s.headers.update({ 'Content-Type': 'application/json' })
response = s.post(url=url, json=payload)
The request reaches the server, and delivers the payload correctly. However, I get this error:
response = s.post(url=url, json=payload)
File "/Library/Python/2.7/site-packages/requests/sessions.py", line 511, in post
return self.request('POST', url, data=data, json=json, **kwargs)
File "/Library/Python/2.7/site-packages/requests/sessions.py", line 468, in request
resp = self.send(prep, **send_kwargs)
File "/Library/Python/2.7/site-packages/requests/sessions.py", line 576, in send
r = adapter.send(request, **kwargs)
File "/Library/Python/2.7/site-packages/requests/adapters.py", line 426, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', BadStatusLine("''",))
I did some research, finding this and this
I tried the approach suggested in the first link, but I get the same error. It might be because I am using Python 2.7 while the original post is about Python 3. I also tried, based on the second link, to set the output field in web.ctx however, I get the same error.
What is the correct way to return a JSON as a response to a POST request?

Having trouble uploading files with Box.com API

I am new to programming and learning python, so please bear with me, I appreciate the help....
I am working on a project where I need to upload files to storage services and I am currently trying to use the box API. I am trying to work with the code on this page:
how to use python's Request library to make an API call with an attachment and a parameter
import requests
import json
#the user access token
access_token = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
#the name of the file as you want it to appear in box
filename = 'box_file'
#the actual file path
src_file = "C:\Python\Wildlife.wmv"
#the id of the folder you want to upload to
parent_id = '0'
headers = { 'Authorization: Bearer {0}'.format(access_token)}
url = 'https://upload.box.com/api/2.0/files/content'
files = { 'filename': (filename, open(src_file,'rb')) }
data = { "parent_id": parent_id }
response = requests.post(url, data, files, headers)
file_info = response.json()
I have tried a number of different things that really haven't gotten me any closer, so I am posting my slight adaptation of their code. Currently I am getting this error:
Traceback (most recent call last):
File "transfer2.py", line 18, in <module>
response = requests.post(url, data, files, headers)
TypeError: post() takes from 1 to 3 positional arguments but 4 were given
I have also had issues with the file_info = response.json()" in some of my other experiments. If someone could help me to get this working I would greatly appreciate it.
I am using python 3 if that helps.
edit 4/6
As requested, I changed this line:
response = requests.post(url, data=data, files=files, headers=headers)
This is the error I now get:
Traceback (most recent call last):
File "transfer2.py", line 18, in <module>
response = requests.post(url, data=data, files=files, headers=headers)
File "C:\Python34\lib\site-packages\requests\api.py", line 108, in post
return request('post', url, data=data, json=json, **kwargs)
File "C:\Python34\lib\site-packages\requests\api.py", line 50, in request
response = session.request(method=method, url=url, **kwargs)
File "C:\Python34\lib\site-packages\requests\sessions.py", line 450, in request
prep = self.prepare_request(req)
File "C:\Python34\lib\site-packages\requests\sessions.py", line 381, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "C:\Python34\lib\site-packages\requests\models.py", line 305, in prepare
self.prepare_headers(headers)
File "C:\Python34\lib\site-packages\requests\models.py", line 410, in prepare_headers
self.headers = CaseInsensitiveDict((to_native_string(name), value) for name, value in headers.items())
AttributeError: 'set' object has no attribute 'items'
In the requests library for request.post(), headers and files are both keyword arguments only, I would also make data a keyword argument, e.g.:
response = requests.post(url, data=data, files=files, headers=headers)
from boxsdk import Client, OAuth2
oauth = OAuth2( client_id="dlpjkcxxxxxxxxxxxxxxxxxxxxcom",client_secret="xxxxxxxxxxxxxxxxxxxxxxxxx", access_token="xxxxxxxxxxxxxxxxxxxxxxxxxxx", )
client = Client(oauth)
shared_folder = client.folder(folder_id='0',).create_subfolder('sxxxx')
uploaded_file = shared_folder.upload('/root/xxxxxx.txt')

urllib2 Posting ZIP file error

I want to send my application/zip data to the server without pycurl or other libs. I am newbie with cURL. Firstly i succesfully sent text/xml data with this code
import urllib2
req = urllib2.Request("http://192.168.79.131/rest", headers = {"Content-type" : "text/xml" , "Accept" : "*/*"} , data = '<income><name>acme7</name></income>')
f = urllib2.urlopen(req)
But now i want to upload my ZIP file to the server. I tried this code:
import urllib2
zipPath = "c:/somedir/ways.zip"
zipData = open(zipPath, "rb")
req = urllib2.Request("http://192.168.79.131/rest", headers = {"Content-type" : "application/zip" , "Accept" : "*/*"} , data = zipData)
f = urllib2.urlopen(req)
I got these errors:
Traceback (most recent call last):
File "<pyshell#25>", line 1, in <module>
f = urllib2.urlopen(req)
File "C:\Python27\lib\urllib2.py", line 126, in urlopen
return _opener.open(url, data, timeout)
File "C:\Python27\lib\urllib2.py", line 386, in open
protocol = req.get_type()
File "C:\Python27\lib\urllib2.py", line 248, in get_type
**raise ValueError, "unknown url type: %s" % self.__original
ValueError: unknown url type: /rest/income**
Have you considered using something like Requests? It handles a lot of the urllib2 stuff so you don't have to:
import requests
url = 'http://httpbin.org/post'
files = {'file': open('c:/somedir/ways.zip', 'rb')}
r = requests.post(url, files=files)
print r
Prints:
>>> <Response [200]>

Web scraping using Python and HTTPS proxies

Is there currently something in Python that support HTTPS proxies for web scraping ? I am currently using Python 2.7 with Windows but I could use Python 3 if it supports HTTPS proxy protocol.
I tried using mechanize and requests but both failed on HTTPS proxy protocol.
This bit is using mechanize:
import mechanize
br = mechanize.Browser()
br.set_debug_http(True)
br.set_handle_robots(False)
br.set_proxies({
"http" : "ncproxy1.uk.net.intra:8080",
"https" : "ncproxy1.uk.net.intra:8080",})
br.add_proxy_password("uname", "pass")
br.open("http://www.google.co.jp/") # OK
br.open("https://www.google.co.jp/") # Proxy Authentication Required
or using requests:
import requests
from requests.auth import HTTPProxyAuth
proxyDict = {
'http' : 'ncproxy1.uk.net.intra:8080',
'https' : 'ncproxy1.uk.net.intra:8080'
}
auth = HTTPProxyAuth('uname', 'pass')
r = requests.get("https://www.google.com", proxies=proxyDict, auth=auth)
print r.text
I obtain the following message:
Traceback (most recent call last):
File "D:\SRC\NuffieldLogger\NuffieldLogger\nuffieldrequests.py", line 10, in <module>
r = requests.get("https://www.google.com", proxies=proxyDict, auth=auth)
File "C:\Python27\lib\site-packages\requests\api.py", line 55, in get
return request('get', url, **kwargs)
File "C:\Python27\lib\site-packages\requests\api.py", line 44, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 335, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python27\lib\site-packages\requests\sessions.py", line 438, in send
r = adapter.send(request, **kwargs)
File "C:\Python27\lib\site-packages\requests\adapters.py", line 331, in send
raise SSLError(e)
requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
For requests module you can use this
#!/usr/bin/env python3
import requests
proxy_dict = {
'http': 'http://user:passwd#proxy_ip:port',
'https': 'https://user:passwd#proxy_ip:port'
}
r = requests.get('https://google.com', proxies=proxy_dict)
print(r.text)
I have tested this.

Categories