Flask request as json [duplicate] - python

This question already has answers here:
How to get POSTed JSON in Flask?
(13 answers)
Closed 1 year ago.
I have 1 small program. I'm sending the request of json via CURL X POST and should get the answer.
The client code is:
curl -XPOST -d'{"animal":"cow", "sound":"moooo", "count": "3"}' 192.168.88.88:5000/test
The server code is:
import json
from flask import Flask, request, jsonify
app = Flask(__name)
#app.route("/test", methods=['POST'])
def json_example():
content = request.get_json(silent=True)
animal = content["animal"]
sound = content["sound"]
count = str(content["count"])
i=0
res=''
while i<int(count):
temp = animal + "says " + sound +"\n"
res = temp +res
i = i + 1
return res
app.run(host='0.0.0.0', port = 5000)
If I'm running the request at postman and indicating that this is json type - then all is OK, but if I'm running it via curl - has an error (None type object isn't subscriptable)
Please advice, how to correct the code at server and indicate, that all responses will be type of json.
Thanks

You have to specify -H "Content-Type: application/json" with the curl request. Alternatively you can use request.form.values if you don't specify header type for the request:
curl -H "Content-Type: application/json" -XPOST -d'{"animal":"cow", "sound":"moooo", "count": "3"}' 192.168.88.88:5000/test
For your curl request the mimetype given by request.mimetype is 'application/x-www-form-urlencoded'

Related

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)

Have issue during curl URL for REST API used Flask url: (35) schannel: next InitializeSecurityContext failed

I have design web app using Flask for REST API server
for get id and key from frontend, backend will get info and do some action
(only using POST method)
curl command
curl -X POST -H "Content-Type:application/json" --data "{/"account_id/":/"100002/", /"access_key/":/"AKIAWDL6TY5M2INS6J7E/"}" https://192.168.172.130:443/account
However, when I am using curl command as below:
X POST -H "Content-Type:application/json" --data "{/"account_id/":/"100002/", /"access_key/":/"AKIAWDL6TY5M2INS6J7E/"}" https://192.168.172.130:443/account
curl: (35) schannel: next InitializeSecurityContext failed: SEC_E_INVALID_TOKEN (0x80090308) - The token supplied to the function is invalid
code design in run.py
def scan_account(_account_id:str, _access_key:str):
# building connection to db
mySQLDB = mysqlDBConnector()
mySQLDB.dbConnection()
#init record log request
_now_time = datetime.datetime.now()
_request_info_log:str = 'Request of account id:'+str(_account_id)+' With Access Key: '+str(_access_key)+' at: '+str(_now_time)+' direction data: incoming with action type: post request'
mySQLDB.db_log_request_insert(_request_info_log)
# get secret key
_AccountID: int = _account_id
_AccessKey: str = _access_key
_SecretKey: str = mySQLDB.db_get_key(_AccountID,_AccessKey)
# init boto3 session
_aws_session = AWS_Session(_AccessKey, _SecretKey)
_aws_session.get_credentials()
#init running
_worker = Worker()
attrs = (getattr(_worker, name) for name in dir(_worker))
methods = filter(inspect.ismethod, attrs)
for method in methods:
_thread_method = threading.Thread(target=method, args=(_aws_session,))
_thread_method.start()
_thread_method.join()
#app.route("/account/",methods=["POST"])
def account_info():
_account_id = request.json['account_id']
_access_key = request.json['access_key']
#data = {'acount_id': _account_id, 'access_key': _access_key}
scan_account(_account_id,_access_key)
#return jsonify(data)
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0', port='443')
Ok lets get a couple of things out the way, I DO NOT suggest you use this for anything other than a local dev. Please use proper SSL.
Make sure you have pyOpenSSL properly installed.
from flask import Flask, jsonify, request, make_response
app = Flask(__name__)
#app.route("/account/",methods=["POST"])
def account_info():
_account_id = request.json['account_id']
_access_key = request.json['access_key']
data = {'acount_id': _account_id, 'access_key': _access_key}
return make_response(jsonify(data), 200)
if __name__ == '__main__':
app.run(debug=True,host='0.0.0.0', port='433', ssl_context='adhoc')
I also modified your curl to make it simpler, that and it was causing issues:
curl -X POST -H "Content-Type:application/json" --data '{"account_id":"100002", "access_key":"AKIAWDL6TY5M2INS6J7E"}' https://localhost:9443/account/ --insecure
I get the following output:
{
"access_key": "AKIAWDL6TY5M2INS6J7E",
"acount_id": "100002"
}
This is how i tested it all:
docker run --rm -it -p 9443:443 python:3.7 bash -c '
pip install flask pyOpenSSL;
curl -s https://gist.githubusercontent.com/kingbuzzman/a955b49a318eef9e76b4bf9026cd2595/raw/sample.py > sample.py;
python sample.py'
Here is the gist source: https://gist.github.com/kingbuzzman/a955b49a318eef9e76b4bf9026cd2595

POST service parameter - FLASK [duplicate]

This question already has answers here:
How to get POSTed JSON in Flask?
(13 answers)
Closed 6 years ago.
This is what i get
b'{"data": "https://files.slack.com/files-pri/T03HPFD2P-F2RU2S4R0/scher7-om-14.52.47.png"}'
when i print my request data from a flask POST web service.
print(request.data)
But when i do url = request.form.get('data', None)
I get value of url variable None
Why?
Your problem is that you sent the request as follows:
req = requests.post(url, data=json.dumps(payload), headers={'Content-Type': 'application/json'})
When sending json data, you should format the request in requests with the json parameter as follows:
req = requests.post(url, json=payload)
Further, in your flask app, you can access submitted json data via request.json
Because the content type is application/json -- it will not appear in request.form -- Data will appear in request.form when a request is received with an appropriate content type such as multipart/form-data
What's the Content-Type header in your POST request?
As described in its docs: request.form is a dict contains data parsed from POST or PUT form, while request.data contains the incoming request data as string in case it came with a mimetype Flask does not handle.
For the following code:
# -*- coding: utf-8 -*-
from flask import Flask, request
app = Flask("Test")
#app.route("/ping", methods=['POST'])
def ping():
print "Data: ", request.data
print "Form: ", request.form
return "pong"
if __name__ == '__main__':
app.run(host='0.0.0.0', port=7070, debug=False)
Curl with default Content-Type, there's no data in request.data:
curl -X POST -H "Content-Type: a/b" --data 'data=https://files.slack.com/files-pri/T03HPFD2P-F2RU2S4R0/schermafbeelding-2016-01-27-om-14.52.47.png' http://localhost:7070/ping
Output:
* Running on http://0.0.0.0:7070/ (Press CTRL+C to quit)
Data:
Form: ImmutableMultiDict([('data', u'https://files.slack.com/files-pri/T03HPFD2P-F2RU2S4R0/schermafbeelding-2016-01-27-om-14.52.47.png')])
127.0.0.1 - - [20/Oct/2016 21:40:41] "POST /ping HTTP/1.1" 200 -
But curl with a unknown Content-Type header, there's no data in request.form:
curl -X POST -H "Content-Type: a/b" --data 'data=https://files.slack.com/files-pri/T03HPFD2P-F2RU2S4R0/schermafbeelding-2016-01-27-om-14.52.47.png' http://localhost:7070/ping
Output:
Data: data=https://files.slack.com/files-pri/T03HPFD2P-F2RU2S4R0/schermafbeelding-2016-01-27-om-14.52.47.png
Form: ImmutableMultiDict([])
127.0.0.1 - - [20/Oct/2016 21:43:52] "POST /ping HTTP/1.1" 200 -
So if you want your form data in request.form, make sure the Content-Type is the one of those Flask can handle.

An example of POST request in Flask API gives "Method Not Allowed"

I'm using FLASK API and I want to use POST requests.
I want just to do an example with POST requests that will return something, I keep getting an error message "Method Not Allowed".
I want to give a parameter(e.g query_params = 'name1' ) to search for a user and to return a JSON, actually I don't know where to give this parameter and I don't understand why I'm getting that message.
Here I did a simple route:
#mod_api.route('/show-user', methods=['POST'])
def show_user():
query_params = 'name1'
query = {query_params: 'Myname' }
json_resp = mongo.db.coordinates.find(query)
return Response(response=json_util.dumps(json_resp), status=200, mimetype='application/json')
Any help please?
The likely reason is that you are probably not doing a POST request against the route, which only accepts POST requests. Here is a simplified example with the mongodb details removed to illustrate this.
from flask import Flask
app = Flask(__name__)
#app.route('/show-user', methods=('POST',))
def show_user():
return "name info"
if __name__ == "__main__":
app.run(debug=True)
Now if we do a POST request it works, but if we do A GET request it raises the error you saw:
curl -H "Content-Type: application/json" -X POST -d '{}' http://127.0.0.1:5000/show-user
name info
curl -H "Content-Type: application/json" -X GET http://127.0.0.1:5000/show-user
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>405 Method Not Allowed</title>
<h1>Method Not Allowed</h1>
<p>The method is not allowed for the requested URL.</p>

RESTFUL POST with Python request to Glassfish Server

I'm having a difficulty trying to make a Python REST POST to a webservice running on Glassfish. I have verified that POST works ok using CURL but having no luck with Python.
Here is the CURL request that works ok.
curl -X POST -H "Content-Type: application/json" -d '{"id":1,"lastname":"smith"}'
http://192.168.0.20:8080/field1/resources/com.field1entity.field1
Here is the Python code to make the POST request
import urllib
import httplib2
def call():
http = httplib2.Http()
url = 'http://192.168.0.20:8080/field1/resources/com.field1entity.field1'
params = urllib.urlencode({"id":11111,"lastname":"oojamalip"})
response, content = http.request(url, 'POST', params, headers={'Content-type':'application/json'})
print "lets stop here to have a looksy at the variables"
print content
if __name__ == '__main__':
namesPage = call()
print namesPage
Output from console,
Unexpected character ('l' (code 108)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')
at [Source: org.apache.catalina.connector.CoyoteInputStream#18f494d; line: 1, column: 2]
Hope someone can shed some light on the problem.
thanks
Nick
You are url encoding the prams and then telling the server it is json encoded
import json
params = json.dumps({"id":11111,"lastname":"oojamalip"})
# then
response, content = http.request(url, 'POST', body=params, headers={'Content-type':'application/json'})

Categories