Flask-RESTful - 上传图片

28

我在想如何通过创建API服务上传文件?

class UploadImage(Resource):
    def post(self, fname):
        file = request.files['file']
        if file:
            # save image
        else:
            # return error
            return {'False'}

线路

api.add_resource(UploadImage, '/api/uploadimage/<string:fname>')

然后就是HTML

   <input type="file" name="file">

我已在服务器端启用CORS

我正在使用angular.js作为前端,如果有影响的话,我也可以使用ng-upload,但也可以使用CURL语句!


尝试使用Blue Imp jQuery文件上传 https://github.com/blueimp/jQuery-File-Upload - iJade
你好 @iJade,我正在使用 Angular 作为前端!但还是谢谢你的推荐!我只需要知道你是如何在服务器端实现这个的! :) - Sigils
6个回答

28
以下内容足以保存已上传的文件:
from flask import Flask
from flask_restful import Resource, Api, reqparse
import werkzeug

class UploadImage(Resource):
   def post(self):
     parse = reqparse.RequestParser()
     parse.add_argument('file', type=werkzeug.datastructures.FileStorage, location='files')
     args = parse.parse_args()
     image_file = args['file']
     image_file.save("your_file_name.jpg")

werkzeug.datastructures.FileStoragewerkzeug.FileStorage 有什么区别? - DarkSuniuM
3
需要提及该API的使用方法:以下是一个 curl 的例子: curl -v -X POST -H "Content-Type: multipart/form-data" -F "file=@test.zip" http://localhost:8080/api/maintenance/update使用 application/octet-stream 作为内容类型对我来说行不通... - domih
跳过“-H”Content-Type: multipart/form-data”对我有用。 - daparic

23
class UploadWavAPI(Resource):
    def post(self):
        parse = reqparse.RequestParser()
        parse.add_argument('audio', type=werkzeug.FileStorage, location='files')

        args = parse.parse_args()

        stream = args['audio'].stream
        wav_file = wave.open(stream, 'rb')
        signal = wav_file.readframes(-1)
        signal = np.fromstring(signal, 'Int16')
        fs = wav_file.getframerate()
        wav_file.close()

如果输入流是wav格式,那么上面的代码可以处理。如果是图像,则应存储在数据库中或上传到AWS S3或Google Storage。


6

您可以使用Flask的请求(request)对象

class UploadImage(Resource):
    def post(self, fname):
        file = request.files['file']
        if file and allowed_file(file.filename):
            # From flask uploading tutorial
            filename = secure_filename(file.filename)
            file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
            return redirect(url_for('uploaded_file', filename=filename))
        else:
            # return error
            return {'False'}

http://flask.pocoo.org/docs/0.12/patterns/fileuploads/


4
以下代码可以帮助解决类似问题。
 @app.route('/upload', methods=['GET', 'POST'])
 def upload():
    if request.method == 'POST':
        file = request.files['file']
        extension = os.path.splitext(file.filename)[1]
        f_name = str(uuid.uuid4()) + extension
        file.save(os.path.join(app.config['UPLOAD_FOLDER'], f_name))
        return json.dumps({'filename':f_name})

20
似乎没有使用Flask-RESTful。 - Daryl Spitzer
1
对我来说也不符合RESTful的要求。 - Nabin
它不是符合RESTful标准的。 - Maleehak

4
以下是使用curl上传图像并将其保存在本地的简单程序。
from flask import Flask
from flask_restful import Resource, Api, reqparse
import werkzeug
import cv2
import numpy as np

app = Flask(__name__)
api = Api(app)

parser = reqparse.RequestParser()
parser.add_argument('file',
                    type=werkzeug.datastructures.FileStorage,
                    location='files',
                    required=True,
                    help='provide a file')

class SaveImage(Resource):
    def post(self):
        args = parser.parse_args()
        # read like a stream
        stream = args['file'].read()
        # convert to numpy array
        npimg = np.fromstring(stream, np.uint8)
        # convert numpy array to image
        img = cv2.imdecode(npimg, cv2.IMREAD_UNCHANGED)
        cv2.imwrite("saved_file.jpg", img)

api.add_resource(SaveImage, '/image')

if __name__ == '__main__':
    app.run(debug=True)

您可以像这样使用curl:

curl localhost:port/image -F file=@image_filename.jpg

参考:链接

0
#Image(s) and file Upload
from flask import Flask, json, request, jsonify
import os
import urllib.request
from werkzeug.utils import secure_filename

app = Flask(__name__)

app.secret_key = "caircocoders-ednalan"

UPLOAD_FOLDER = 'static/uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_LENGTH'] = 16 * 1024 * 1024

ALLOWED_EXTENSIONS = set(['txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif'])

def allowed_file(filename):
    return '.' in filename and filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/api/upload', methods=['POST'])
def upload_image():
    if 'image' not in request.files:
        resp = jsonify({
            'status' : False,
            'message' : 'Image is not defined'})
        resp.status_code = 400
        return resp

    files = request.files.getlist('image')

    errors = {}
    success = False

for photo in files:

    if photo and allowed_file(photo.filename):
        filename = secure_filename(photo.filename)
        photo.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
        success = True
    else:
        errors[photo.filename] = 'Image type is not allowed'

if success and errors:
    errors['message'] = jsonify({
        'data' : photo.filename,
        'status' : True,
        'message' : 'Image(s) successfully uploaded'})
    resp = jsonify(errors)
    resp.status_code = 500
    return resp

if success:
    resp = jsonify({
        'data' : photo.filename,
        'status' : True,
        'message' : 'Images successfully uploaded'})
    resp.status_code = 201
    return resp
else:
    resp = jsonify(errors)
    resp.status_code = 500
    return resp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接