How to structure python / Flask project

Viewed 213

As a python beginner and newby to Flask, I made some structural mistakes in my project.
I have a html page with some dropdown menus and buttons where I set parameters and then my python code (let’s call it apple.py) does some analysis work and sends it back to the html page to display.
Now, I would like to add some modified copies of my apple.py code and have a start page from where I can choose which py code / page I’d like to load. I’ve read about the Blueprints in Flask but I don’t get it implemented.
This is the structure of my project now:

apple.py
    /static
    /css
    /template
        Index.html

apple.py is organised like this:

csv / Dataframe crunching
Tons of variables 

Class xxx()

@app.route('/')

@app.route('/main/', methods=['GET', 'POST'])

Some Functions / main code()…

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

I can’t change anything in the main code, also moving the routes above the class causes many errors. Any suggestions how to structure this to get a html start page from where I could navigate to apple.py, banana.py, etc..?

UPDATE:
Upon request I post here the truncated main code (apple.py).
I deleted all repetitive lines from the functions as well as the variables because they don't matter here

from flask import Flask, render_template, request, make_response
import pandas as pd
import numpy as np
import sys
import pygal

#****** csv import and dataframe setup ****************************************************

df = pd.read_csv('ES_M5_7h00.csv', sep=';', engine='python')
df['Date'] = pd.to_datetime(df['Date'] + ' ' + df['Time'], dayfirst=True)
df.set_index('Date', inplace=True)
to_delete = ['2019-12-25', '2019-12-26', '2020-01-01', '2020-07-03']
df = df[~(df.index.strftime('%Y-%m-%d').isin(to_delete))]
df.Time = df.Time.str.replace(':', '').astype(float).astype(int)
df.reset_index(inplace=True)
df = df[df['Time'].between(70000, 221000)]
SessionStart = 70000
df = df.join(df.resample('B', on='Date')['yVAH_init'].last().rename('yVAH'), on=pd.to_datetime((df['Date'] - pd.tseries.offsets.BusinessDay()).dt.date))
df = df.join(df.resample('B', on='Date')['yVAL_init'].last().rename('yVAL'), on=pd.to_datetime((df['Date'] - pd.tseries.offsets.BusinessDay()).dt.date))
df = df.join(df.resample('B', on='Date')['yPOC_init'].last().rename('yPOC'), on=pd.to_datetime((df['Date'] - pd.tseries.offsets.BusinessDay()).dt.date))
df['Opening'] = df.Date.dt.date.map(df.resample('B', on='Date').Open.first())
df.drop(['yVAH_init', 'yVAL_init','yPOC_init'], axis=1, inplace=True)
sample_length = df['Date'].dt.date.nunique()

#****** variables start ****************************************************

#****** variables end ****************************************************

#****** main code ****************************************************

class Opening(object):

    def __init__(self, zone=None, zonegroup=None, yClosing=None, zonelist=None, zonetextlist=None, chart_legend=None, zone_names=None, chart_titles=None, yCondition=None):

        self.zone = zone
        self.zonegroup = zonegroup
        self.yClosing = yClosing
        self.zonelist = zonelist
        self.zonetextlist = zonetextlist
        self.chart_legend = chart_legend
        self.zone_names = zone_names
        self.chart_titles = chart_titles
        self.yCondition = yCondition

@app.route('/')
@app.route('/main/', methods=['GET', 'POST'])

def select_zone():

    selected_zone = request.form.get("select_zone")
   
    if selected_zone is None:
        return open_empty()

    if selected_zone == "-":
        return open_empty()    
        
    if selected_zone == "Z1":
        
        Opening.zone = Z1
        Opening.zonelist = zonelist[0]
        Opening.zonetextlist = zonetextlist[0]
        Opening.chart_legend = chart_legend[0]
        Opening.zone_names = zone_names[0]
        Opening.chart_titles = chart_titles[0]

        return module_opening(Z1group, Z1)
etc etc...


def select_yClosing():

    yClosing  = request.form.get("select_yClosing")

    if yClosing == "irrelevant":
        Opening.yClosing = df1 = Opening.zone 
        df1 = df[Opening.zone].groupby(df['Date'].dt.date).first()
        return df1
    
    if yClosing == "above_value":
        
        Opening.yClosing = df1 = df[yCLOSEOUTOFVALUEabove].eq(df[Opening.zone]) 
        df1 = df[df1].groupby(df['Date'].dt.date).first()
        return df1

   etc etc....

def select_yCondition():

    yCondition  = request.form.get("select_yCondition")

    if yCondition == "irrelevant":

        Opening.yCondition = df1 = Opening.zone 
        df1 = df[Opening.zone].groupby(df['Date'].dt.date).first()
        return df1

    if yCondition == "close_above_open":
        
        Opening.yCondition = df1 = df[Opening.yClosing].eq(df[yClose_above_yOpen]) 
        df1 = df[df1].groupby(df['Date'].dt.date).first()
        return df1

etc etc...


def open_empty():
    return render_template('emptyRTH.html')


def module_opening(zonegroup, zone):
    
    time_receive1 = 0
    time_receive2 = 0
    
          
    time1 = request.form
    time2 = request.form
    if request.method == "POST":
        time_receive1 = time1["select_time1"] 
        time_receive2 = time2["select_time2"]

    TimeSpanStart = int(time_receive1)
    TimeSpanEnd = int(time_receive2)
    

    output = []
    output2 = []
    chart_values = []

   
    df1 = zonegroup
    df1 = select_yClosing()
    df1 = select_yCondition()
    df1 = df1[df1['Time'].between(SessionStart, SessionStart)]
    
    SESSIONS = len(df1)
    output.append(
        str(len(df1)) 
        + " " +str(Opening.zone_names) + "sessions out of " 
        + str(sample_length) 
        +" days sample size. " 
        + "\n" + "\n" )
          #+ str(df1.Date))
         #)

    z = [None] * 5

    for j in range(5): 
            
            df1 = Opening.yClosing
            df1 = Opening.yCondition
            z[j] = df[Opening.zonelist[j]].eq(df[df1])
            z[j] = df[z[j]].groupby(df['Date'].dt.date).first().reset_index(drop=True).set_index('Date')
            z[j] = z[j][z[j]['Time'].between(TimeSpanStart, TimeSpanEnd)]
            

            output2.append(
                str(len(z[j])) 
                + " hits in " 
                + str(SESSIONS) 
                + " " +str(Opening.zone_names) + " sessions sample size. " 
                +"<br><b>"
                + "{:.2%}".format(len(z[j]) / SESSIONS) 
                +"</b>"
                + str(Opening.zonetextlist[j])
                +str(TimeSpanStart) 
                + ' and ' 
                + str(TimeSpanEnd) 
                + "\n" + "\n" 
                +'<div class="toggleDIV">'
                +'"""<xmp>'
                + str(z[j].index.strftime("%Y-%m-%d %H:%M:%S"))
                +' </xmp>"""'
                +'</div>'
                   )

            chart_values.append(round((len(z[j]) / SESSIONS)*100))

    from pygal.style import Style
    custom_style = Style(
    background='transparent',
    plot_background='transparent',
    foreground='#403C44',
    foreground_strong='#003366',
    foreground_subtle='#630C0D',
    opacity='.6',
    opacity_hover='.9',
    legend_font_size=9,
    title_font_size=12,
    #transition='400ms ease-in',
    colors=('#CD6155', '#3498DB', '#16A085', '#95A5A6', '#5D6D7E'))
    line_chart = pygal.HorizontalBar(print_values=True, style=custom_style, width=650, height=450, explicit_size=True)
    line_chart.title = Opening.chart_titles
    line_chart.x_labels = [chart_values[0]]#, chart_values[1], chart_values[2], chart_values[3], chart_values[4], chart_values[5]]
    #line_chart.add('Depth %', [chart_values[0], chart_values[1], chart_values[2], chart_values[3], chart_values[4], chart_values[5]])
    line_chart.add(Opening.chart_legend[0], [chart_values[0]])
    line_chart.add(Opening.chart_legend[1], [chart_values[1]])
    line_chart.add(Opening.chart_legend[2], [chart_values[2]])
    line_chart.add(Opening.chart_legend[3], [chart_values[3]])
    line_chart.add(Opening.chart_legend[4], [chart_values[4]])
    bar_data = line_chart.render_data_uri()

    return render_template('indexRTH.html', output = output, output2 = output2, bar_data = bar_data)




if __name__ == "__main__":
    app.run(debug=True)
1 Answers

If i got your question, you should try this; in apple.py;

from flask import Flask, render_template
app = Flask(__name__, template_folder="template") #template is the name of your templates folder
@app.route("/")
def index():
   return render_template("index.html")
Related