如何在Sanic中执行文件上载

Jib*_*hew 7 python-3.x sanic

我正在尝试在Sanic上执行文件上传,但它无法正常工作,烧瓶的正常语法似乎不适用于sanic.

我甚至无法访问文件名或save方法来将上传的文件保存到给定目录.

Jib*_*hew 9

经过长时间的斗争,我发现以下代码正在运行

@app.route("/upload", methods=['POST'])
async def omo(request):
    from sanic import response
    import os
    if not os.path.exists(appConfig["upload"]):
        os.makedirs(appConfig["upload"])

    f = open(appConfig["upload"]+"/"+request.files["file"][0].name,"wb")
    f.write(request.files["file"][0].body)
    f.close()

    return response.json(True)
Run Code Online (Sandbox Code Playgroud)

  • 感谢您跟进并分享答案 (2认同)

小智 8

上面的答案很棒。一些小的改进:

(1) 由于我们使用的是Sanic,所以我们尝试异步执行文件io:

async def write_file(path, body):
    async with aiofiles.open(path, 'wb') as f:
        await f.write(body)
    f.close()
Run Code Online (Sandbox Code Playgroud)

(2) 确保文件不会太大而导致服务器崩溃:

def valid_file_size(file_body):
    if len(file_body) < 10485760:
        return True
    return False
Run Code Online (Sandbox Code Playgroud)

(3) 检查文件名和文件类型以获得正确的文件类型:

  def valid_file_type(file_name, file_type):
     file_name_type = file_name.split('.')[-1]
     if file_name_type == "pdf" and file_type == "application/pdf":
         return True
     return False
Run Code Online (Sandbox Code Playgroud)

(4) 确保文件名没有危险/不安全的字符。您可以在 werkzeug.utils 中使用 secure_filename 函数:http : //flask.pocoo.org/docs/0.12/patterns/fileuploads/

(5) 这段代码将所有内容结合在一起:

async def process_upload(request):
        # Create upload folder if doesn't exist
        if not os.path.exists(app.config.UPLOAD_DIR):
            os.makedirs(app.config.UPLOAD_DIR)

        # Ensure a file was sent
        upload_file = request.files.get('file_names')
        if not upload_file:
            return redirect("/?error=no_file")

        # Clean up the filename in case it creates security risks
        filename = secure_filename(upload_file.name)

        # Ensure the file is a valid type and size, and if so
        # write the file to disk and redirect back to main
        if not valid_file_type(upload_file.name, upload_file.type):
            return redirect('/?error=invalid_file_type')
        elif not valid_file_size(upload_file.body):
            return redirect('/?error=invalid_file_size')
        else:
            file_path = f"{app.config.UPLOAD_DIR}/{str(datetime.now())}.pdf"
            await write_file(file_path, upload_file.body)
            return redirect('/?error=none')
Run Code Online (Sandbox Code Playgroud)

我创建了一篇关于如何在 Sanic 中处理文件上传的博客文章。我添加了一些文件验证和异步文件写入。我希望其他人觉得这有帮助:

https://blog.fcast.co/2019/06/16/file-upload-handling-using-asynchronous-file-writing/