提问者:小点点

Flask-使用OOP进行多用户访问


我用烧瓶创建了一个应用程序,但我有一个全局变量的多用户访问bcs的问题。每当我运行脚本(可能需要几分钟),而其他人试图访问页面并运行脚本时,也会出现冲突,两个用户的数据会混合。

我真的明白在这种情况下我应该使用OOP,但我无法复制此应用程序的OOP用法(是的,我是OOP初学者)。有人可以给我一个提示或一点代码关于OOP的这种情况吗?

非常感谢。

蟒蛇:

from flask import Flask, render_template, url_for, request, redirect, Response
from datetime import datetime
import time
import pandas as pd
import re
import os


app = Flask(__name__)


@app.route('/', methods=['POST', 'GET'])
def index():

    if request.method == 'POST':
        start_date = request.form["Start_date"]
        end_date = request.form["End_date"]
        dates = pd.period_range(start=start_date, end=end_date, freq='D')
        global s_date
        global f_date
        s_date = dates[0]
        f_date = dates[-1]
        print(s_date, f_date)
        query = request.form["query"].strip()
        splitted = query.split("\r\n")

        global fiii
        fiii = pd.DataFrame()

        for x in splitted:
            print(x)
            for date in dates:
                print(date)

                directory = '/home/USER/Parquets/{}/{:02d}/{:02d}/'.format(date.year, date.month, date.day)
                for filename in os.listdir(directory):
                    if filename.endswith(".parquet"):
                        df = pd.read_parquet(directory)
                        df.set_index("query", inplace=True)


                        if request.form.get('lowercase') == "on":
                            df.index = df.index.str.casefold()
                        if request.form.get('sensitive') == "on":

                            fiii = fiii.append(df.filter(regex=re.compile(x), axis=0))
                        else:

                            fiii = fiii.append(df.filter(regex=re.compile(x, re.IGNORECASE), axis=0))

        fiii = fiii.groupby(['query'])["total"].sum().sort_values(ascending=False)

        if request.form.get('csv') == "on":
            return redirect("/getCSV")
        else:
            pass
        # return render_template("index.html")
        return fiii.to_frame().to_html(table_id="table")
    else:
        return render_template("index.html")



@app.route("/getCSV")
def getPlotCSV():


    return Response(
        fiii.to_csv(encoding="UTF-8", sep="\t", header=True),
        mimetype="text/csv",
        headers={"Content-disposition":
                 f"attachment; filename={s_date}-{f_date}.csv"})


if __name__ == "__main__":
    app.run(debug=True,port=4444)

HTML:

<html lang="en"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/mate                                                                                                                                       rialize/1.0.0/css/materialize.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js                                                                                                                                       /materialize.min.js"></script>
    <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel                                                                                                                                       ="stylesheet">

    </head>
    <body>
        <div class="container">
            <div class="row">
                <form class="col s6 offset-s3" action="/" method="POST">
                    <div class="valign-wrapper col s12">
                        <h3 class="col s6">Query master</h3>
                        <div class="right-align input-field col s6">
                            <button class="btn btn-large btn-floating waves-                                                                                                                                       effect waves-light" type="submit" name="action">
                                <i class="material-icons right">send</i>
                            </button>
                        </div>
                    </div>

                    <div class="input-field col s12">
                        <input type="text" id="date-start" class="datepicker                                                                                                                                       " name="Start_date">
                        <label for="date-start">Start Date</label>
                    </div>

                    <div class="input-field col s12">
                        <input type="text" id="date-end" class="datepicker"                                                                                                                                        name="End_date">
                        <label for="date-end">End Date</label>
                    </div>

                    <label class="input-field col s12">
                        <input type="checkbox" name="lowercase" />
                        <span>Lowercase queries</span>
                    </label>

                    <label class="input-field col s12">
                        <input type="checkbox" name="sensitive" />
                        <span>Case sensitive</span>
                    </label>

                    <label class="input-field col s12">
                        <input type="checkbox" name="csv" />
                        <span>CSV export (Funkční pouze csv export)</span>
                    </label>

                    <div class="input-field col s12">
                        <textarea id="textarea1" name="query" class="materia                                                                                                                                       lize-textarea"></textarea>
                        <label for="textarea1">Queries (RegEx supported)</la                                                                                                                                       bel>
                    </div>

                </form>

            </div>

            <script>
                document.addEventListener('DOMContentLoaded', function() {
                    var elems = document.querySelectorAll('.datepicker');
                    var instances = M.Datepicker.init(elems, {
                        format: 'm/d/yyyy',
                    });
                });
            </script>
        </div>
    </body>
</html>


共1个答案

匿名用户

您的问题与OO完全无关—它只是使用gobal变量的结果。

flask服务器进程将依次为所有传入请求提供服务。因此,在多用户场景中发生的情况是:

1/用户A发布到索引。这将为全局s\u日期f\u日期填充赋值。

2/用户A被重定向到getCSV

3/同时,用户B发布到索引。这会将全局s_日期f_日期填充重新绑定到新值

4/用户A的浏览器已跟随重定向,并呈现用户B的填充

解决方案非常简单:不要将全局状态用于每个用户的数据持久性—您希望短期会话数据使用用户会话和/或长期用户数据使用RDBMS。