0

我有一个烧瓶应用程序,它接收用户/投资组合 id 表单,然后创建一个显示用户数据、信息、图表等的页面。我正在尝试为每个用户投资组合/工具插入一个下载 CSV 数据链接/按钮.

我正在通过烧瓶会议来做到这一点。由于 CSV 数据超过了 cookie 限制,我需要使用特殊会话。直到现在我尝试使用 Redis 都没有成功(但它可能是一个选项),所以我正在使用文件系统 Flask 会话,它给出了错误OSError: [Errno 36] File name too long

这是我的代码的简化:

应用程序.py

from flask import Flask, render_template, redirect, request, session, send_file
from flask_wtf import FlaskForm
from flask_session import Session #this module has upper and lower case versions - I'm using lower

from wtforms import StringField, SelectField, SubmitField, validators
from wtforms.validators import DataRequired

from flask_bootstrap import Bootstrap

#import my modules

app = Flask(__name__)

SESSION_TYPE = 'filesystem' #redis #filesystem
app.config.from_object(__name__)

Session(app)
Bootstrap(app)


app.config.from_mapping(SECRET_KEY=.....)


...

#home route
@app.route('/', methods=['GET', 'POST'])
def home():
     form = DataForm(request.form)
     if request.method == 'POST' and form.validate_on_submit():
         data_id = request.form['data_id']
         target= request.form['target']
    
         return redirect(f"/data/{target}/{data_id}")

return render_template('home.html', form=form)


#route which receives user/portfolio id, gets data and creates display page
@app.route('/data/<target>/<data_id>')
def customeranalysis(target, data_id):
    data_id = procedures.handle_id(data_id)

    if target == 'user':
        user_infos, user_names, graphs, annual_tables, twelve_months_tables, monthly_tables, csvs = procedures.user_info(data_id)
    
        for i in range(len(user_names)):
            session[user_names[i]] = csvs[i]
    
        return render_template('data_display_page.html', 
                               user_id=data_id,
                               dfs=user_infos, 
                               names=user_names, 
                               graphs=graphs, 
                               annual_tables=annual_tables,
                               twelve_months_tables=twelve_months_tables,
                               monthly_tables=monthly_tables)
    if target == 'portfolio':
        #same as previous if, a little different


#route for the download page, to which the download link in previous route points
@app.route("/get_csv/<filename>", methods=['GET', 'POST'])
def get_csv(filename):
    df = session[filename]
    try:
        return send_file(df,  
                     as_attachment=True,
                     attachment_filename='dados.csv'
                     )
    except FileNotFoundError:
        abort(404)


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

因此,在我的 data_display_page.html 模板页面中,我有以下代码,它创建了下载链接:

data_display_page.html

    {% for i in range(names| length) %}
    ...
        <a href="{{url_for('get_csv', filename=names[i])}}" id="download" class="btn btn-outline-info">Download data</a>
    ...

当我运行 docker-compose 时,一切运行良好,但是当我单击下载加载链接并被重定向时,我在浏览器和控制台上收到内部服务器错误,我得到以下信息:

cmd:码头工人撰写错误

web_1  | 172.27.0.1 - - [15/Apr/2021 18:34:15] "GET /data/portfolio/portfolio_api_id HTTP/1.1" 200 -
web_1  | [2021-04-15 18:34:47,836] ERROR in app: Exception on /get_csv/portfolio_name[GET]
web_1  | Traceback (most recent call last):
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app
web_1  |     response = self.full_dispatch_request()
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request
web_1  |     rv = self.handle_user_exception(e)
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception
web_1  |     reraise(exc_type, exc_value, tb)
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise
web_1  |     raise value
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1950, in full_dispatch_request
web_1  |     rv = self.dispatch_request()
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/app.py", line 1936, in dispatch_request
web_1  |     return self.view_functions[rule.endpoint](**req.view_args)
web_1  |   File "/code/app.py", line 86, in get_csv
web_1  |     return send_file(df,
web_1  |   File "/usr/local/lib/python3.8/site-packages/flask/helpers.py", line 629, in send_file
web_1  |     file = open(filename, "rb")
web_1  | OSError: [Errno 36] File name too long: #Long string which is actually not the CSV's name, but the CSV string itself

不知何故,它认为文件名是整个 CSV 字符串,包含所有列和行等。

4

0 回答 0