This is the shortest code of one of the pages not working when blocking cookies in browser (I know the code it’s involved, also it was written for Dash < 2.0, I have to update it in order to use some of the new features like duplicate callback outputs):
import config
import dash
import dash_bootstrap_components as dbc
from dash import Dash, dcc, html, Input, Output, State, callback, callback_context
dash.register_page(
__name__,
path = '/azione-neve',
title = config.SITE_TITLE+'Azione neve',
description = 'Calcolo delle azioni della neve su un edificio secondo NTC 2018.',
order = 1,
)
import random
from fastnumbers import fast_real
import calc.azione_neve_calc as calc
import calc.tools as tls
import calc.common_param as cpar
dropdown_provincia = dcc.Dropdown(
id="provincia",
options=list(calc.dict_provincia_zona.keys()),
clearable=False,
persistence=True,
persistence_type = 'memory',
style={'width':'15em','margin-top':'0.3em'},
)
input_provincia = html.Div(['Provincia',dropdown_provincia],className='outer-div')
dropdown_provincia.initial = None
radio_coeff_esposizione = dcc.RadioItems(
id='coeff_esposizione',
options=tls.dict_to_options({'battuta dai venti':'0.9', 'normalmente esposta ai venti':'1.0', 'riparata dai venti':'1.1'},use_value_as_label=False),
persistence=True,
persistence_type = 'memory',
inputStyle={"margin": "0 0.5em 0 0"},
labelStyle={'display':'block'},
style={"margin": "0 1em 0 1.5em"}
)
input_coeff_esposizione = html.Div([config.linkNTC2018('Esposizione dell\'area ai venti','tab3.4.I'),': ',radio_coeff_esposizione],className='outer-div')
radio_coeff_esposizione.qsv_dict = {'ventosa':'0.9', 'normale':'1.0', 'riparata':'1.1'}
radio_coeff_esposizione.initial = 'normale'
elem_coeff_termico = dcc.Input(
id='coeff_termico',
type="number",
min=0.8, max=1.2, step=0.01,
persistence=True,
persistence_type = 'memory',
style={'width': '5em','text-align':'center','margin-top':'0.3em'}
)
input_coeff_termico = html.Div([config.linkNTC2018('Coefficiente termico','3.4.5'),' stimato: ',elem_coeff_termico],className='outer-div',style={'width': '12em','text-align':'center'})
elem_coeff_termico.initial = '1.0'
def layout(prov=dropdown_provincia.initial, aslm=cpar.altitudine.initial, ce=radio_coeff_esposizione.initial, ct=elem_coeff_termico.initial, **other_unknown_query_strings):
cpar.altitudine.value = fast_real(aslm,None)
dropdown_provincia.value = prov if prov in dropdown_provincia.options else None
radio_coeff_esposizione.value = radio_coeff_esposizione.qsv_dict.get(ce,None) # if key does not exist return None
ct = fast_real(ct,1+elem_coeff_termico.max)
elem_coeff_termico.value = ct if (elem_coeff_termico.min<=ct<=elem_coeff_termico.max) else None
return dbc.Row(
[
html.H5(['Carico neve secondo ',config.linkNTC2018("NTC 2018","3.4"),' su una copertura piana ad una o due falde'], style={'text-align':'center'}),
html.Div([
input_provincia,
cpar.input_altitudine,
cpar.input_inclinazione_falda,
input_coeff_esposizione,
input_coeff_termico,
html.Div([
dbc.Button("Calcola", id="btn_calc_neve", color="primary", className="me-1",disabled=True),
dbc.Button("Scarica la relazione tecnica", id="btn_relaz_neve", color="primary", className="me-1",disabled=True)
],style={'margin':'0.5em'}),
html.Div(dcc.Markdown(id='md_neve',children='Premere il pulsante **\'Calcola\'** dopo aver impostato tutti i parametri di input.', mathjax=True,link_target='_blank'),className='outer-div'),
dcc.Download(id="download-relaz-neve"),
cpar.make_modal('modal-neve','Errore inatteso durante la creazione del documento della relazione.',info=True),
cpar.promemoria_corrispettivo('neve')
], style={'text-align':'center'})
]
)
@callback(
Output('md_neve', 'children'),
Output("btn_calc_neve", "disabled"),
Output("btn_relaz_neve", "disabled"),
Input("btn_calc_neve", "n_clicks"),
Input('provincia', 'value'),
Input('altitudine', 'value'),
Input('inclinazione_falda', 'value'),
Input('coeff_esposizione', 'value'),
Input('coeff_termico', 'value'),
# prevent_initial_call=True,
)
def new_input_and_calc(n_clicks,*args):
if None in args:
return 'Parametri di calcolo incompleti o non validi, si prega di verificare.',True,True
triggered_id = callback_context.triggered[0]['prop_id']
if triggered_id == 'btn_calc_neve.n_clicks':
config.log_event(f"pulsante calcolo neve: {args}")
provincia,altitudine,inclinazione_falda,coeff_esposizione,coeff_termico = args
return calc.q_neve(provincia,altitudine,inclinazione_falda,float(coeff_esposizione),coeff_termico)[-1],True,False
else:
return 'Premere il pulsante **\'Calcola\'** dopo aver impostato tutti i parametri di input.',False,True
@callback(
Output("download-relaz-neve", "data"),
Output("modal-neve", "is_open"),
Output("promemoria_neve", "is_open"),
Input("btn_relaz_neve", "n_clicks"),
State('md_neve', 'children'),
State('provincia', 'value'),
State('altitudine', 'value'),
State('inclinazione_falda', 'value'),
State('coeff_esposizione', 'value'),
State('coeff_termico', 'value'),
prevent_initial_call=True,
)
def press_download(n_clicks,txt_md,*filetitleargs):
filetitle = 'azione-neve_{}_{}_{}_{}_{}'.format(*filetitleargs).replace('.','-').replace(' ','-')
res = tls.convert_md2odt(txt_md)
if res is None: # error in converting markdown to odt
return dash.no_update,True,dash.no_update
else: # success in converting markdown to odt
return dcc.send_bytes(res,filetitle+'.odt'),dash.no_update,(True if random.random() < 0.1 else False)