Converting python requests.post to CURL statement - python

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!

Related

collect others parameters in my flask api [duplicate]

This question already has answers here:
Using cURL to upload POST data with files
(11 answers)
Closed 2 months ago.
I send a json file by curl with this command and its work :
curl -X POST -H "Content-Type: application/json" -d #/Users/test/testjson.json 'http://127.0.0.1:5000
I collect this data like and its work :
#app.route('/json_test', methods=['POST'])
def process_data():
# Collect the JSON file from the request
data = json.loads(request.data)
#
I want to add both parameters source and id.
How can I send these parameters in Curl plus my json file . I tried
curl -i -X POST -H "Content-Type: multipart/form-data"
-F "data /Users/test/testjson.json” -F "source=Value1" -F "ident=Value2" http://127.0.0.1:5000
But it's not working
if you can help me to have the command and how i can read this data with python.
Please provide more information of the content on both values you want to add.
I changed a quotation mark inside your curl, try with:
curl -i -X POST -H 'Content-Type: multipart/form-data'
-F 'data /Users/test/testjson.json' -F "source=Value1" -F 'ident=Value2' http://127.0.0.1:5000
To use variables from the curl, you need to update your method. The below curl is another example you can try for now:
#app.route('/json_test', methods=['POST'])
def process_data(source: str, ident: str):
# Collect the JSON file from the request
data = json.loads(request.data)
#
Curl Command:
curl -i -X POST \
'http://127.0.0.1:5000/json_test/?source=value1/?ident=value2' \
-H 'Content-Type: multipart/form-data' \
-F 'data /Users/test/testjson.json'
Try this:
curl -i -X POST -H "Content-Type: multipart/form-data"
-F "user_input=</Users/test/testjson.json” -F "source=Value1" -F "ident=Value2" http://127.0.0.1:5000/json_test
Note that this will create a form with three fields: user_input, source, and ident. You'll need to modify your controller endpoint as well:
#app.route('/json_test', methods=['POST'])
def process_data():
form_content_as_json = json.loads(request.form)

change curl cmd to python

I am a beginner. I am trying to change a curl cmd to an actually Post request in my python code.
Each time, I am getting either a 404 or 400 errors. I am a bit lost. Thanks.
Curl request : (echo -n '{"data": "'; base64 test-1.pdf; echo '", "extension": ".pdf"}') | curl -X POST -H "Content-Type: application/json" -d #- http://localhost:5000
My python code:
import json
import requests
url ='http://localhost:5000/POST'
newHeaders = {'Content-Type': 'application/json'}
response = requests.post(url, json={"data": "'; base64 test-1.pdf; echo '", "extension": ".pdf"},headers=newHeaders)
print("Status code: ", response.status_code)
response_Json = response.json()
print("Printing Post JSON data")
print(response_Json['data'])
print("Content-Type is ", response_Json['headers']['Content-Type'])
Your URL is wrong and should not have the /POST at the end, but in addition to that, you need to actually base64-encode the test-1.pdf (this is what the shell command that runs curl is doing).
You could use this (combined with the code in the question) to put the correct value into the parameters dictionary.
import base64
#...
b64 = base64.b64encode(open("test-1.pdf", "rb").read()).decode()
response = requests.post(url,
json={"data": b64,
"extension": ".pdf"},
headers=newHeaders)

Use python requests to write a curl command with parameters like -u and -T

I am trying to replicate a curl command of the following format:
curl -X PUT -w "<some string>" \
-u <user_name>:<password> \
-T <some_string> \
<some_url>
I've tried to add the parameters in headers in the following format, but it didn't work:
url = ''
headers = {'u': '<user>', 'T': '<string>'}
response = requests.post(url, headers=headers)
Those -u and -T flags aren't headers, they trigger specific behaviour in curl. You need to understand that behaviour and look up how to do the equivalent thing in the requests manual.
-X sets the request method, here PUT, which corresponds to requests.put,
-u corresponds to the auth=(user, pass) argument,
-T uploads a file, which corresponds to the files={...} parameter.
Putting it all together, you want something like:
requests.put(url,
auth=('username', 'password'),
files={'file': open('filename', 'rb')})
you use curl with put,but you use requests with post.
please read requests'doc .
3.response = requests.put('http://aaaa', auth=('', ''),data={},files = {'file': open('report.xls', 'rb')})

Django DRF JWT authentication get token - JSON parse error - Expecting value

I have simple Django DRF application setup which I have implemented JWT authentication.
I used the Django REST framework JWT documentation
I am using curl to test the implementation.
I can successfully get a token using the following notation used in the documentation:
$ curl -X POST -d "username=admin&password=password123" http://localhost:8000/api-token-auth/
The token is returned in following format:
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InNpdHJ1Y3AiLCJleHAiOjE1MTE2NTEyMTQsInVzZXJfaWQiOjEsImVtYWlsIjoiY3VydGlzLnBva3JhbnRAZ21haWwuY29tIn0.F1TSkxe5tQVpddetUdOJDdAPP1XB9Bimb5U3c75oWd0"}
However, when I try using this other variation, I get an error:
$ curl -X POST -H "Content-Type: application/json" -d '{"username":"admin","password":"password123"}' http://localhost:8000/api-token-auth/
The error I get is:
{"detail":"JSON parse error - Expecting value: line 1 column 1 (char 0)"}
I also had the same error when trying to refresh or verify the token:
Refresh:
$ curl -X POST -H "Content-Type: application/json" -d '{"token":"<EXISTING_TOKEN>"}' http://localhost:8000/api-token-refresh/
Verify:
$ curl -X POST -H "Content-Type: application/json" -d '{"token":"<EXISTING_TOKEN>"}' http://localhost:8000/api-token-verify/
I was adding the token as follows:
curl -X POST -H "Content-Type: application/json" -d '{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VybmFtZSI6InNpdHJ1Y3AiLCJleHAiOjE1MTE2NDg5MjIsInVzZXJfaWQiOjEsImVtYWlsIjoiY3VydGlzLnBva3JhbnRAZ21haWwuY29tIn0.T5h_PSvzvKOZCPTS60x5IUm3DgAsRCRmbMJeGWZk3Tw"}' http://localhost:8800/api-token-refresh/
Am I perhaps adding the token incorrectly? Does it need some other formatting with quotes?
Those requests are sending data in two different ways. The first request sends it as form data (x-www-form-urlencoded) which is what your endpoint is expecting and the second request sends it as application/json.
I'm not sure that the library you're using will handle a json request out of the box so one option would be to create a custom endpoint and use something like the following:
import json
def ParseFormData(self, request):
payload = json.loads(request.body.decode('utf-8'))
// use django auth to authorize request and return token
You can read more about it in this answer here: https://stackoverflow.com/a/29514222/5443056
There's instructions for manually creating auth tokens in your library's documentation. Here's the code:
from rest_framework_jwt.settings import api_settings
jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
payload = jwt_payload_handler(user)
token = jwt_encode_handler(payload)
i suggest use json.dumps({key:value})

convert curl to requests using multipart/mixed in python

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.

Categories