【问题标题】:How Can I Return a TXT file Using Flask Response?如何使用 Flask Response 返回 TXT​​ 文件?
【发布时间】:2021-04-15 07:51:33
【问题描述】:

我有一个脚本(“script2.py”),它接收一种特定类型的 HTML 文件,刮出一些内容,并将其汇总到一个 txt 输出文件中。我正在构建一个烧瓶应用程序,该应用程序将允许用户上传 HTML 文件,运行脚本,然后在他们单击“提交”后获取 txt 输出文件作为响应。这些文件非常小,我想避免在运行脚本时将它们保存在任何地方。 有没有办法通过烧瓶响应向用户提供一个 txt 文件?

使用下面的代码,我可以上传一个文件并返回一个 txt 文件作为响应,但该文件只包含这些行...

xml version="1.0" encoding="UTF-8"?
html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "XHTML1-s.dtd"

在堆栈跟踪中,会打印以下错误消息。

AssertionError: applications must write bytes

During handling of the above exception, another exception occurred:

...

TypeError: 'NoneType' object is not callable

我的网络应用程序的代码如下。我正在调用的“run_script_in_web_app”函数是将 HTML 文件转换为 txt 文件的脚本部分。

from flask import Flask, render_template, request, Response, make_response
import script2

app = Flask(__name__)

@app.route('/')
def display_home():
    return render_template("home.html")

@app.route('/upload', methods=["GET", "POST"])
def upload_and_run():
    uploaded_file = request.files['file']
    file_name = uploaded_file.filename
    file_contents = uploaded_file.stream.read().decode("utf-8")
    result = script2.run_script_in_web_app(file_name, file_contents)

    response = app.response_class(response=result, status=200, mimetype='application/txt')
    return response

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

我意识到这种方法目前是不安全的,因为它没有验证用户输入。在我将所有内容分层之前,我只是想让事情在本地主机上端到端运行。

我已经运行了一些测试,并且非常有信心响应的“上游”脚本部分正常工作(测试 HTML 文件不为空,上传正常,script2 能够打开文件等)

我正在调用的函数如下所示。注释指出每一行的内容。

这是我正在调用的 script2 中的函数。

def run_script_in_web_app(filename, file_contents):

    global soup

    name = filename

# Convert the HTML file contents into a Beautiful Soup object. 

    soup = BeautifulSoup(file_contents)
    return soup

# Creates a dictionary that contains an "author" value extracted from the HTML input file.

    extracted_authors = parse_authors(soup)

# Pulls contents from "header" divs with a certain ID in the input file.

    parse_headers(soup)

# Pulls contents from "body" divs with a certain ID in the input file. 

    parse_bodies(soup)

# Creates a list of dictionaries from header div contents. 

    extracted_heads = extract_headers(header_divs)

# Creates a list of dictionaries from body div contents. 

    extracted_bodies = extract_body(body_divs)

# Combines the header and body dictionaries together into a single list of dictionaries. 

    heads_and_bodies = merge_heads_with_bodies(extracted_heads, extracted_bodies)

# Writes the list of dictionaries and the "author" dictionary together in a .txt file for display to the end user. 

    output_file = dict_writer(extracted_authors, heads_and_bodies, name)
    return (output_file)

【问题讨论】:

  • 错误似乎在您的函数script2.run_script_in_web_app 中。您需要向我们展示该文件的内容以帮助我们进行调试
  • @NoCommandLine 刚刚使用我正在调用的函数更新了帖子。感谢您的帮助。

标签: python flask


【解决方案1】:
  1. 我看到你在做app.response_class,但你实际上没有自定义响应类,所以我想知道你为什么要这样做。为什么不app.make_response()
  2. 但我认为您的问题在于您的代码 - script2.run_script_in_web_app 返回的是一个 BeautifulSoup 对象,而不是您文件的实际内容。你必须做soup.body()

【讨论】:

  • 感谢您的提示。我看到我之前返回的文件包含我的 HTML 输入文件的头部。我添加了一行body = soup.find('body'),并将所有对“汤”的引用替换为我的其余函数中的这个“身体”。现在我得到一个空白文件作为回应。有什么我想念的吗?
  • 我只使用 app.response_class 因为我在几个代码示例中看到了它。感谢您的指点。
  • 不要做soup.find('body')。执行soup.body() 并打印内容并确认其中包含的内容。
【解决方案2】:

我知道这里发生了什么。有几个问题。

  1. 正如@NoCommandLine 所指出的,我的“run_script_in_web_app”函数有两个返回语句,所以它只是返回一个漂亮的汤对象,而不是我认为会返回的输出文件。

  2. 我在“run_script_in_web_app”中调用的“dict_writer”函数将输出文件写入磁盘。相反,我需要将输出写入结果,并将其返回给 Flask。

【讨论】:

    猜你喜欢
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-15
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    相关资源
    最近更新 更多