I'm trying to convert the following curl post to a Python request:
curl -k -i -H "Content-Type: multipart/mixed" -X POST --form
'session.id=e7a29776-5783-49d7-afa0-b0e688096b5e' --form 'ajax=upload'
--form 'file=#myproject.zip;type=application/zip' --form 'project=MyProject;type/plain' https://localhost:8443/manager
I used curl.trillworks.com to make an auto conversion but it didn't work. I also tried the following:
sessionID = e7a29776-5783-49d7-afa0-b0e688096b5e
project = 'file.zip'
metadata = json.dumps({"documentType":"multipart/mixed"})
files = {
'meta' : ('', metadata , 'application/zip'),
'data':(project, 'multipart/mixed', 'application/octet-stream')}
data = {'ajax':'upload','project':'test','session.id':sessionId}
cookie = {'azkaban.browser.session.id':sessionId}
response=requests.post('https://'+azkabanURL+'/manager',
data=data,verify=False,files=files)
print response.text
I got the following error:
<p>Problem accessing /manager. Reason:
<pre> INTERNAL_SERVER_ERROR</pre></p><h3>Caused by:</h3><pre>java.lang.NullPointerException
at azkaban.webapp.servlet.ProjectManagerServlet.ajaxHandleUpload(ProjectManagerServlet.java:1664)
at azkaban.webapp.servlet.ProjectManagerServlet.handleMultiformPost(ProjectManagerServlet.java:183)
at azkaban.webapp.servlet.LoginAbstractAzkabanServlet.doPost(LoginAbstractAzkabanServlet.java:276)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:401)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:766)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:945)
at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:756)
at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at org.mortbay.jetty.bio.SocketConnector$Connection.run(SocketConnector.java:228)
at org.mortbay.jetty.security.SslSocketConnector$SslConnection.run(SslSocketConnector.java:713)
at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Can't figure out what I'm missing here??
I found the answer after trying out some of the examples from requests site and finally it worked.
data = {'ajax':'upload','project':'test','session.id':sessionId}
files = {'file':('projects.zip',open('projects.zip','rb'),'application/zip')}
response=requests.post('https://'+azkabanURL+'/manager',data=data,verify=False,files=files)
print response.text
print response.status_code
For the future reference I recommend you to check this online tool:
http://curl.trillworks.com/
it converts curl to python requests, node and php.
It has helped my multiple times.
Related
I am trying to convert the following cURL request to a python requests request.
I know the format for a GET request but not sure how to format the --output flag.
curl -u usr:pass -X GET "http://url-to-file.com/filefolder/filepath.txt" --output new_file_name.txt
This is what I have so far but it was returning a 405 Method not allowed error.
r = session.get('http://url-to-file.com/filefolder/filepath.txt')
I am trying to convert a python POST requests to a curl statement for the following request:
# this is the requests.post I want to convert to CURL - it works for python but
# I need to run this in a shell script, so I need to convert the following to
# curl statement:
response = requests.post(url,
files=files,
headers=headers)
# the "files" in the above request.post contain a json data AND
# a yaml data as shown below:
files = {
'json': (None, json.dumps(jsondata), 'application/json'),
'file': ('heat_template', heat_yaml,'application/yaml')}
# However, in python, the 'file' class that contains the yaml data is assigned with cgi.FieldStorage class.
# the header contains X-Auth-Token
headers = {}
headers['X-Auth-Token'] = token_value
Originally I tried to use the following curl statement but it doesn't work:
curl -i X POST -d $JSONDATA -H "Content-Type:application/json" -data-urlencode "file#datafile.yaml" -H "Content-Type:application/yaml" $url -H "X-Auth-Token:$TOKEN"
UPDATE: I motified the curl statement to the following and it worked 'partially':
curl -i -X POST -F json="$JSONDATA" -F file="$ENCODED_YAML" $URL -H "X-Auth-Token:$TOKEN"
The destination url $URL is able to translate the json data -F json="$JSONDATA" and the header data H "X-Auth-Token:$TOKEN") correctly from the curl statement, but the -F file="$ENCODED_YAML" is treated as a string python class instead of the expected cgi.FieldStorage python class. How do we pass a file data as a cgi.FieldStorage class in a curl statement?
Appreciate the help!
I have the following curl that successfully logs me into a website. It returns a 302 and a cookie:
curl \
--verbose \
--request POST \
--data '__EVENTTARGET=&body%3Ax%3AtxtLogin=kingkong%40mailinator.com&body%3Ax%3AbtnLogin=&crypted_pass=736015615f9e251692a6a4aa8a7baa14' \
"https://emma.maryland.gov/page.aspx/en/usr/login"
Unfortunately, I have to insert the real username & encrypted password of the account. otherwise this curl it won't work. However, this is a completely dummy account with NO private data in it. So please don't get mad at me.
I want to convert it to a Python3 code using requests.post(). So I made this code:
>>> requests.post(
... url='https://emma.maryland.gov/page.aspx/en/usr/login',
... data={
... '__EVENTTARGET': '',
... 'body:x:txtLogin': 'kingkong#mailinator.com',
... 'body:x:btnLogin': '',
... 'crypted_pass': '736015615f9e251692a6a4aa8a7baa14'
... }
... )
<Response [200]>
But the response I get from the Python3 code (200) doesn't match the response I get from the Curl (302). This means that the target server senses a difference between the two requests.
How can I convert the curl to Python3 that sends the exact same underlying HTTP request?
Your requests code is actually smarter than the cURL command.
HTTP 302 - is a redirect, cURL didn't follow it and gave you the first response it got. You can make cURL follow the redirect with -L: Is there a way to follow redirects with command line cURL?
The requests code followed the redirect and gave you the final response, which happened to be a HTTP 200.
Try your curl command with -L and see if you get HTTP 200 or not.
Alternatively, you can ask requests to not follow redirects with the allow_redirects=False option: Is there an easy way to request a URL in python and NOT follow redirects?
I'm trying to code the upload of a file to a web service through a REST API in Python. The service's documentation shows a example using curl as client:
curl -X POST -H \
-H "Content-Type: multipart/form-data" \
-F "file=filename.ext" \
-F "property1=value1" \
-F "property2=value2" \
-F "property3=value3" \
https://domain/api/endpoint
The difficulty for me is that this syntax doesn't match multipart form-data examples I found, including the requests documentation. I tried this, which doesn't work (rejected by the API):
import requests
file_data = [
("file", "filename.ext"),
("property1", "value1"),
("property2", "value2"),
("property3", "value3"),
]
response = requests.post("https://domain/api/endpoint",
headers={"Content-Type": "multipart/form-data"}, files=file_data)
With the error: "org.apache.commons.fileupload.FileUploadException: the request was rejected because no multipart boundary was found"
Can anybody help in transposing that curl example to proper Python code?
Thanks!
R.
OK, looks like the web services documentation is wrong, and metadata simply needs to be sent as parameters. Moreover, I found in another request that you shouldn't set the header. So I was starting from a wrong example.
I am making a python build script for a phonegap project.
I need to open the ios key before i build
I am trying to do this with a http put request through the requests module for python.
If i do it with cURL from command line, it works fine
curl -vvv -d 'data={"password":"myPassWord"}' -X PUT https://build.phonegap.com/api/v1/keys/ios/193686?auth_token=passwordlesstokenphg
But from python like this.
password_for_key = {'password': 'myPassword'}
authentication_token = {'auth_token': 'passwordlesstokenphg'}
requests.put('https://build.phonegap.com/api/v1/keys/ios/193686', data=password_for_key, params=authentication_token)
It just returns the json you would recieve if you did a cURL without the data.
For me it seems like the data is not being sent to phonegap correctly.
API reference from build.phonegap.com
docs.build.phonegap.com/en_US/2.9.0/developer_api_write.md.html
Please help :)
So when you do
curl -d "..." -X PUT https://example.com
curl sends exactly what's in that string. requests does not translate so directly to curl. To do something similar in requests you need to do the following:
import json
password_for_key = {'password': 'myPassword'}
authentication_token = {'auth_token': 'passwordlesstokenphg'}
requests.put('https://build.phonegap.com/api/v1/keys/ios/193686',
data={'data': json.dumps(password_for_key)},
params=authentication_token)
What requests will do is build data={"password":"myPassword"} for you if you use the above. First you have to JSON encode the data in password_for_key then pass it in the dictionary to data.