直接从 Flask 服务上传到 Minio

Upload to Minio directly from Flask service

我想将文件从 Flask 服务存储到 Minio Bucket,而不是先将其存储在目录中。到目前为止我能做的是让用户使用 Flask 服务上传文件,将其存储在目录中,然后使用 Minio 的 put_object 函数上传它。 这样的事情可能吗?

下面你可以看到 upload_file flask 方法和 upload_object 方法,它利用了 Minio 的 put_object 函数:

UPLOAD_FOLDER = 'uploads'
ALLOWED_EXTENSIONS = {'txt', 'pdf', 'png', 'jpg', 'jpeg', 'gif', '7z', 'iso'}

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

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

@app.route('/', methods=['GET','POST'])
def upload_file():
    if request.method == 'POST':
        # check if the post request has the file part
        if 'file' not in request.files:
            flash('No file part') 
            return 'No file found'
        file = request.files['file']
        # if user does not select file, browser also
        # submit an empty part without filename
        if file.filename == '':
            flash('No selected file')
            return 'msg error'
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            file.save('uploads/'+filename)
            print(file.filename)
            # upload file to minio service
            upload_object(name=str(file.filename))
            return 'object stored in bucket'

    return '''
    <!doctype html>
    <title>Upload IPS File</title>
    <h1>Upload IPS File</h1>
    <form method=post enctype=multipart/form-data>
      <input type=file name=file>
      <input type=submit value=Upload>
    </form>
    '''

upload_object():

def upload_object(name):
    try:
        path = 'uploads/'+str(name)
        print(path)
        file_data = open(path, 'rb')
        print(file_data)
        file_stat = os.stat('uploads/'+str(name))
        print(minioClient.put_object('miniotestbucket', str(name), file_data, file_stat.st_size))
    except ResponseError as e: 
        print(e)
    except FileNotFoundError as e:
        print(e)

我已经检查过这个 Question 但我不太明白需要做什么。

应该是完全可以的,因为你只是保存后读取文件内容。 This post tells a bit more about FileStorage. Since FileStorage extends stream you have many of the same features while reading the file from the request as when reading it from a file on disk. Since you cannot stat the file I used another way to tell the size of the file found here.

您可以尝试这样的操作:

@app.route("/", methods=["GET", "POST"])
def upload_file():
    if request.method == "POST":
        uploaded_file = request.files["file"]
        if uploaded_file:
            bucket_name = "miniotestbucket"
            size = os.fstat(uploaded_file.fileno()).st_size

            minioClient.put_object(
                bucket_name, uploaded_file.filename, uploaded_file, size
            )

            return "object stored in bucket"

    return """
    <!doctype html>
    <title>Upload IPS File</title>
    <h1>Upload IPS File</h1>
    <form method=post enctype=multipart/form-data>
      <input type=file name=file>
      <input type=submit value=Upload>
    </form>
    """

我无法访问 Minio 存储桶,但我通过上传 YAML 文件并使用 yaml.load() 读取内容进行了一些测试,效果很好。