pandas NoneType对象对于使用Pyinstaller的Flask应用程序没有“write”属性

0pizxfdo  于 2023-04-28  发布在  其他
关注(0)|答案(1)|浏览(208)

我写了一个多模板Flask应用程序,并试图将其转换为PyInstaller的可执行文件。该应用程序有一个表单页面,允许您提交到csv,然后它消耗该csv并将其转换为Pandas dataframe,它显示。我在每个渲染的dataframe旁边有一个按钮,用于“下载”视图,通过使用内置的pandas函数将特定的dataframe删除到csv。一切似乎都很好,除了当应用程序加载时,我得到以下错误:

Traceback (most recent call last):
  File "app.py", line 426, in <module>
  File "flask\app.py", line 915, in run
  File "flask\cli.py", line 680, in show_server_banner
  File "click\utils.py", line 298, in echo
AttributeError: 'NoneType' object has no attribute 'write'

当我按下任何一个“下载”按钮时,应用程序都会崩溃。
下面是相关代码:
app.py

from flask import Flask, abort, render_template, request, url_for, jsonify
from markupsafe import escape
import os
import datetime
from datetime import timedelta
import calendar
import csv
from csv import DictWriter
import pathlib
import pandas as pd
import json
import sys
import webbrowser
from threading import Timer

#This is how I can store my controller in the same directory as my master log file
sys.path.insert(1, "C:/Users/sam/webdev/crosstraining")
import PYcontroller

pd.set_option('display.max_columns', 20)

if getattr(sys, 'frozen', False):
    template_folder = os.path.join(sys._MEIPASS, "templates")
    static_folder = os.path.join(sys._MEIPASS, "static")
    app = Flask(__name__, template_folder=template_folder, static_folder=static_folder)
else:
    app = Flask(__name__)

app.config['TEMPLATES_AUTO_RELOAD'] = True

computers = ['home', 'laptop', 'work', 'production']
location = computers[0]

@app.route('/timekeeper/', methods=["GET","POST"])
def timekeeper():
    timekeeperdata = {
        'utc_dt':date_time_str,
        'day':today,
        'month':month,
        'file':table,
        'engineer':engineer,
        'jobs':jobs,
        'dates':dates
        }
    monthCategory = aggDF(master_crossTrainingLog, getMonth())
    yearCategory = aggDF(master_crossTrainingLog, getYear())
    crosstraining = crossTrainingDF(master_crossTrainingLog, engineer)
    admincrosstraining = admincrossTrainingDF(master_crossTrainingLog)
    #These lists are to make the download work
    all_dfs = [admincrosstraining, crosstraining, monthCategory, yearCategory, full_hours]
    all_df_names = ["Admin_view_crosstraining", "_crossTraining", "ThisMonthCrossTraining", "ThisYearCrossTraining", "MasterCrossTrainingFile"]
    #the df's in all_df's are ordered as they are used in timekeeper.
    if request.method == "POST":
        view = request.form.get("view")
        download_view(view, all_dfs, all_df_names)

    return render_template("timekeeper.html", timekeeperdata=timekeeperdata,
    #these are all of the pandas tables that have been made elsewhere 
    tables=[admincrosstraining.to_html(classes='data'),
            crosstraining.to_html(classes='data'),
            monthCategory.to_html(classes='data'),
            yearCategory.to_html(classes='data'),
            full_hours.to_html(classes='data')],

     titles=[admincrosstraining.columns.values,
        crosstraining.columns.values,
        monthCategory.columns.values,
        yearCategory.columns.values,
        full_hours.columns.values])

def download_view(viewNum, data, dataNames):
    df = data[int(viewNum)]
    if viewNum == 1:
        filename = str(engineer[1][3]) + str(dataNames[int(viewNum)])
    else:
        filename = str(dataNames[int(viewNum)])
    filepath = str(pathlib.Path.home() / "Downloads") +"\\"+ filename + "_"+date_time_str[:10] + ".csv"
    df.to_csv(filepath)
    print("file downloaded to: "+ filepath)

def open_browser():
    webbrowser.open_new('http://127.0.0.1:5000/')


if __name__=='__main__':
    Timer(1, open_browser).start()
    app.run() #<--- This is line 426

计时器模板

{% if timekeeperdata['engineer'][1][1] == 'admin' %}
    <h3> Team Hours to Date</h3>
    <div id="pandas" name="View0"> {{tables[0]|safe }} </div> <!--This is the Team hours-->

    <form action="{{ url_for('timekeeper')}}" method="post">
        <input type="text" name="view" value=0 style="display:none;">
        <button type="submit" class="btn" name='download' value="View0" >Download</button>       <p id="submitMessage"> Download Complete!</p>
    </form>

当你点击下载按钮时,它会思考一分钟,然后返回一个500 Internal server错误消息。开发工具中的控制台说:

Status
500
INTERNAL SERVER ERROR
VersionHTTP/1.0
Transferred464 B (290 B size)
Referrer Policystrict-origin-when-cross-origin
Request PriorityHighest

我不知道在这种情况下我需要发送什么头来消除CORS问题,如果这是真正导致错误的原因。
我只是假设启动时的错误和当你尝试“下载”一个 Dataframe 时它抛出错误的方式是相关的,但我不确定如何。如果它们不相关,我想知道如何探索的任何建议。我不是特别精通Pyinstaller或Flask。
还有更多的代码,但我很确定这是所有相关的。如果你认为从故障排除的Angular 来看,缺少一些东西,请随时让我知道。

***编辑:当我从pyinstaller中省略-w标志时,应用程序似乎可以工作。

cbjzeqam

cbjzeqam1#

我不确定,但我认为这与Python3.10有关,因为当我使用Python3.9时,它可以工作

相关问题