Using PUT to receive an xml file in webpy - python

I am trying to receive an xml file through PUT in web.py, it is not working.Can any one explain what is the issue in the below code
import web
urls = (
'/', 'index'
)
class index:
def PUT(self):
postdata = web.data().read()
fout = open('/home/test/Desktop/e.xml','w')
fout.write(postdata)
fout.close()
return "Hello, world!"
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
I am getting this is terminal
"HTTP/1.1 PUT /doc.xml" - 404 Not Found
I use curl to upload the xml
curl -o log.out -H "Content-type: text/xml; charset=utf-8" -T doc.xml "http://0.0.0.0:8760"

import web
urls = ( '/upload', 'index')
class index:
def PUT(self):
datta = web.data()
with open("another.xml", "w") as f:
f.write(datta)
return "hello"
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
with this curl
curl -T somexml.xml http://0.0.0.0:8080/upload
worked for me. I needed to change url because curl behaved strange. Or maybe it seemed to me. but somehow this code won't work with "/" as a url.

You are using the wrong curl option.
If you want your file content in the request body, you should use -d instead of -T
curl -o log.out -H "Content-type: text/xml; charset=utf-8" -d doc.xml "http://0.0.0.0:8760"
EDIT:
Anyway, this will transform your curl into a POST request. To keep it as PUT, use -X PUT
curl -X PUT -o log.out -H "Content-type: text/xml; charset=utf-8" -d doc.xml "http://0.0.0.0:8760"

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)

uploading flie to FastAPI endpoint using curl - 307 Temporary Redirect

I have a fastAPI endpoint that recieves a file and saves it to disk as follows:
from fastapi import FastAPI, File, UploadFile
import shutil
app = FastAPI()
#app.post('/upload')
async def upload_file(file: UploadFile=File(...)):
with open(file.filename, "wb") as buffer:
shutil.copyfileobj(file.file, buffer)
return {
"filename": file.filename,
}
This works as expected when I upload a file through the docs interface at http://localhost:8000/docs
I am able to select a file and it successfully uploads.
However, attempting the same with curl fail:
curl -X POST localhost:8000/upload -F file=#photo.png
the curl command returns nothing and on the server side a 307 Temporary Redirect is logged.
I am not sure what I am missing here
In some scenario/setup where FastAPI redirect the request, use the curl with full dns/ip address.
something like this :
curl -X 'POST' '127.0.0.1:8000/upload' -F 'file=#photo.png
or can add headers(-H) too based on the application that is built.
curl -X 'POST' \
'http://127.0.0.1:8000/upload' \
-H 'accept: application/json' \
-H 'Content-Type: multipart/form-data' \
-F 'file=#photo.png;type=application/json'

Flask send image with curl as json payload

I have a simple flask API with file upload to send an image:
from flask import request
from flask import Flask
app = Flask(__name__)
#app.route('/', methods=['POST'])
def upload_file():
f = request.files['image']
print(f.content_type)
print(f.filename)
# do something with the file
# f.read()
return("Done")
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
When I send an image using curl's -F option, I can access the file:
curl -XPOST localhost:5000 -F "image=#img.jpg"
But how can I send an image as a payload in a json file with the -d option? If I encode the image using base64, put the string into a json file and send it with the -d option, it cannot find my image: KeyError: 'image'
I tried with different content types:
curl -XPOST localhost:5000 -d #img.json --header "Content-Type: application/json"
curl -XPOST localhost:5000 -d #img.json --header "Content-Type: image/jpeg"
My image.json looks something like this:
{"image":"/9j/4AAQSkZJRgABAQEAS..."}
(with the complete string instead of ...)
If you are sending data as JSON payload, you will have to use request.json to access them. Flask docs for files attribute state, that this attribute is non-empty when enctype="multipart/form-data". curl will set multipart/form-data header implicitly when you use -F option.
But for json data you have to set --header "Content-Type: application/json" as you have in you example. However, you have to check request.mimetype on the server side. Based on that check, you will either use files or json attribute. Here is the example how to handle those 2 cases:
from flask import request
from flask import Flask
app = Flask(__name__)
#app.route('/', methods=['POST'])
def upload_file():
if request.mimetype == 'multipart/form-data':
f = request.files['image']
print(f.content_type)
print(f.filename)
# do something with the file
# f.read()
else if request.mimetype == 'application/json':
f = request.json['image']
print(f)
# decode f from Base64
else:
# handle other mimetypes or return that selected mimetype is not supported
print('Unsupported content-type')
return("Done")
if __name__ == "__main__":
app.run(debug=True, host='0.0.0.0', port=5000)
The curl command you used should be handled correctly:
curl -XPOST localhost:5000 -d #img.json --header "Content-Type: application/json"

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

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>

Categories