使用Flask上传和下载文件 [英] Uploading and Downloading Files with Flask

查看:1007
本文介绍了使用Flask上传和下载文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用PythonAnywhere和Flask编写一个简单的web应用程序,让用户上传文本文件,生成一个csv文件,然后让用户下载csv文件。它不一定是花式的,它只需要工作。我已经编写了用于从驱动器上的txt文件生成csv的程序。



现在,我的功能会打开驱动器上的文件:

 打开(INPUTFILE,r)作为fname:

并写入csv:

 以open(OUTPUTFILE,'w')作为fname:

用INPUTFILE和OUTPUTFILE作为文件名字符串。



对于由flask / html返回的对象,将文件作为对象处理会更好吗? >我不知道该怎么做。我应该如何构建这个程序?我需要多少个HTML模板?我宁愿在没有任何地方保存文件的情况下工作,但是如果我必须将它们保存到PythonAnywhere目录中,我可以。我怎样才能做到这一点?

解决方案

PythonAnywhere dev这里。这是一个关于Flask和Web开发的一个很好的问题,而不是特定于我们的系统,所以我会尝试给出一个通用的答案,没有任何特定的给我们: - )



<为了给你的问题一个明确的答案,我需要知道一些事情,所以我将首先列出我正在做的假设 - 如果我有任何错误,请留下我的评论他们和我会适当更新答案。


  • 我假设你上传的文件不是很大,可以适合到一个合理的内存量 - 比方说,小于一兆字节。
  • 我假设你已经编写的用于从文本文件生成CSV的程序是在Python,并且它可能(或者更可能的是,可能很容易被改变)具有一个函数,它接受一个包含文本文件内容的字符串,并返回需要写入CSV的内容。 >


如果两者都是如果是这种情况,那么构建Flask应用程序的最好方法就是处理Flask中的所有东西。一个代码示例胜过千言万语,所以这里是一个简单的代码,允许用户上传一个文本文件,通过一个名为 transform 的函数来运行它你的转换程序中的函数会插入 - 我的文件只是在整个文件中用替换 = ),将结果发送回浏览器。 PythonAnywhere上有这个应用程序的实时版本

  from flask import烧瓶,make_response,请求

app = Flask(__ name__)

def transform(text_file_contents):
return text_file_contents.replace (=,,)


@ app.route('/')
def form():
return
< html>
< body>
< h1>转换文件演示< / h1>

< form action =/ transformmethod =post enctype =multipart / form-data>
< input type =filename =data_file/>
< input type =submit/>
< / form>
< / body>
< / html>


@ app.route = [POST])
def transform_view():
file = request.files ['data_file']
如果不是t文件:
返回无文件

file_contents = file.stream.read()。decode(utf-8)

result = transform file_contents)

response = make_response(result)
response.headers [Content-Disposition] =attachment; filename = result.csv
return response

关于其他问题:




  • 模板:我没有在这个例子中使用模板,因为我想把它全部整合到一段代码中,如果我这样做的话那么我会把由窗体视图生成的东西放到一个模板中,但就是这样。

  • 你能做到吗通过写入文件 - 是的,你可以,上传的文件可以通过使用保存( filename )来保存方法在文件对象,我使用属性。你的文件是相当小的(根据我上面的假设),那么像上面的代码一样在内存中处理它们可能更有意义。


我希望一切都有帮助,如果您有任何问题,请留下评论。


I'm trying to write a really simply webapp with PythonAnywhere and Flask that has lets the user upload a text file, generates a csv file, then lets the user download the csv file. It doesn't have to be fancy, it only has to work. I have already written the program for generating the csv from a txt file on the drive.

Right now, my function opens the file on the drive with:

with open(INPUTFILE, "r") as fname:

and writes the csv with:

with open(OUTPUTFILE, 'w') as fname:

with INPUTFILE and OUTPUTFILE being filename strings.

Would it be better for me to handle the files as objects, returned by the flask/html somehow?

I don't know how to do this. How should I structure this program? How many HTML Templates do I need? I would prefer to work on the files wihthout saving them anywhere but if I have to save them to the PythonAnywhere directory, I could. How can I do that?

解决方案

PythonAnywhere dev here. This is a good question about Flask and web development in general rather than specific to our system, so I'll try to give a generic answer without anything specific to us :-)

There are a few things that I'd need to know to give a definitive answer to your question, so I'll start by listing the assumptions I'm making -- leave me a comment if I'm wrong with any of them and I'll update the answer appropriately.

  • I'm assuming that the files you're uploading aren't huge and can fit into a reasonable amount of memory -- let's say, smaller than a megabyte.
  • I'm assuming that the program that you've already written to generate the CSV from the text file is in Python, and that it has (or, perhaps more likely, could be easily changed to have) a function that takes a string containing the contents of the text file, and returns the contents that need to be written into the CSV.

If both of those are the case, then the best way to structure your Flask app would be to handle everything inside Flask. A code sample is worth a thousand words, so here's a simple one I put together that allows the user to upload a text file, runs it through a function called transform (which is where the function from your conversion program would slot in -- mine just replaces = with , throughout the file), and sends the results back to the browser. There's a live version of this app on PythonAnywhere here.

from flask import Flask, make_response, request

app = Flask(__name__)

def transform(text_file_contents):
    return text_file_contents.replace("=", ",")


@app.route('/')
def form():
    return """
        <html>
            <body>
                <h1>Transform a file demo</h1>

                <form action="/transform" method="post" enctype="multipart/form-data">
                    <input type="file" name="data_file" />
                    <input type="submit" />
                </form>
            </body>
        </html>
    """

@app.route('/transform', methods=["POST"])
def transform_view():
    file = request.files['data_file']
    if not file:
        return "No file"

    file_contents = file.stream.read().decode("utf-8")

    result = transform(file_contents)

    response = make_response(result)
    response.headers["Content-Disposition"] = "attachment; filename=result.csv"
    return response

Regarding your other questions:

  • Templates: I didn't use a template for this example, because I wanted it all to fit into a single piece of code. If I were doing it properly then I'd put the stuff that's generated by the form view into a template, but that's all.
  • Can you do it by writing to files -- yes you can, and the uploaded file can be saved by using the save(filename) method on the file object that I'm using the stream property of. But if your files are pretty small (as per my assumption above) then it probably makes more sense to process them in-memory like the code above does.

I hope that all helps, and if you have any questions then just leave a comment.

这篇关于使用Flask上传和下载文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆