Spaces:
Running
Running
[FIX] app: initialize session state at app level to prevent crashes on direct tab navigation
Browse files- app.py +30 -1
- tabs/tab0_welcome.py +2 -2
app.py
CHANGED
|
@@ -9,7 +9,8 @@ from tabs import (tab0_welcome, tab1_inputs, tab2_constraints,
|
|
| 9 |
tab3_coefficients, tab4_optimization, tab5_sensitivity,
|
| 10 |
tab6_scenarios)
|
| 11 |
from utils.data_utils import load_slider_data, strip_unit_suffix
|
| 12 |
-
from
|
|
|
|
| 13 |
|
| 14 |
# ββ Auto-update: regenerate JSON files if inputs_aggregated.csv has changed βββ
|
| 15 |
# Uses a hash file to detect changes β works both locally and on Hugging Face.
|
|
@@ -104,6 +105,23 @@ with st.sidebar:
|
|
| 104 |
|
| 105 |
cost_sliders = load_slider_data()
|
| 106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
if "constraints" not in st.session_state:
|
| 108 |
st.session_state.constraints = {}
|
| 109 |
if "auto_disabled_methods" not in st.session_state:
|
|
@@ -130,6 +148,17 @@ if "costs" not in st.session_state or st.session_state.costs == {} or _expected_
|
|
| 130 |
for m in cost_sliders
|
| 131 |
}
|
| 132 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 133 |
# When the user navigates TO "Method constraints" from any other tab, force a
|
| 134 |
# full widget re-sync so toggle_M / slider_M keys always reflect the constraint
|
| 135 |
# state. Normal-mode setdefault can't recover keys that were externally set to
|
|
|
|
| 9 |
tab3_coefficients, tab4_optimization, tab5_sensitivity,
|
| 10 |
tab6_scenarios)
|
| 11 |
from utils.data_utils import load_slider_data, strip_unit_suffix
|
| 12 |
+
from utils.state_utils import init_custom_resources
|
| 13 |
+
from config.config import method_order, resource_order, secondary_resources
|
| 14 |
|
| 15 |
# ββ Auto-update: regenerate JSON files if inputs_aggregated.csv has changed βββ
|
| 16 |
# Uses a hash file to detect changes β works both locally and on Hugging Face.
|
|
|
|
| 105 |
|
| 106 |
cost_sliders = load_slider_data()
|
| 107 |
|
| 108 |
+
# Initialise resource_caps / custom_resources / enabled_methods / auto_disabled_methods
|
| 109 |
+
# here (not just in tab1) β the app's default landing tab is "Welcome", so a
|
| 110 |
+
# user can reach any other tab (e.g. "Portfolio generation") without ever
|
| 111 |
+
# rendering tab1 first. Several tabs access these via direct attribute
|
| 112 |
+
# access (st.session_state.resource_caps, not .get()), which crashes with
|
| 113 |
+
# an uninitialised-key AttributeError if tab1 hasn't run yet.
|
| 114 |
+
if "resource_caps" not in st.session_state:
|
| 115 |
+
st.session_state.resource_caps = {}
|
| 116 |
+
for r in resource_order:
|
| 117 |
+
if r not in st.session_state.resource_caps:
|
| 118 |
+
st.session_state.resource_caps[r] = 0.0
|
| 119 |
+
init_custom_resources()
|
| 120 |
+
# Same reasoning for "scenarios" β tab4's "Save scenario" button writes to it
|
| 121 |
+
# directly, but it was previously only ever initialised inside tab6's render.
|
| 122 |
+
if "scenarios" not in st.session_state:
|
| 123 |
+
st.session_state.scenarios = {}
|
| 124 |
+
|
| 125 |
if "constraints" not in st.session_state:
|
| 126 |
st.session_state.constraints = {}
|
| 127 |
if "auto_disabled_methods" not in st.session_state:
|
|
|
|
| 148 |
for m in cost_sliders
|
| 149 |
}
|
| 150 |
|
| 151 |
+
# Auto-activate/deactivate methods based on real resource availability on
|
| 152 |
+
# EVERY render, not only when Tab 2 is the active tab β otherwise a user who
|
| 153 |
+
# goes straight from Tab 1 to Tab 3/4/5 without visiting Tab 2 first would
|
| 154 |
+
# find every method stuck "inactive" and the optimisation would fail with
|
| 155 |
+
# "No active methods" despite correctly configured resources.
|
| 156 |
+
_cost_sliders_norm = {
|
| 157 |
+
m: {strip_unit_suffix(name): conf for name, conf in resources.items()}
|
| 158 |
+
for m, resources in cost_sliders.items()
|
| 159 |
+
}
|
| 160 |
+
tab2_constraints.refresh_active_methods(_cost_sliders_norm)
|
| 161 |
+
|
| 162 |
# When the user navigates TO "Method constraints" from any other tab, force a
|
| 163 |
# full widget re-sync so toggle_M / slider_M keys always reflect the constraint
|
| 164 |
# state. Normal-mode setdefault can't recover keys that were externally set to
|
tabs/tab0_welcome.py
CHANGED
|
@@ -11,10 +11,10 @@ def render_tab():
|
|
| 11 |
st.markdown('<h1 class="crra-heading">Welcome!</h1>', unsafe_allow_html=True)
|
| 12 |
show_bar()
|
| 13 |
|
| 14 |
-
st.markdown(
|
| 15 |
<div class='custom-corps'>
|
| 16 |
This tool helps you exploring how to optimize your carbon dioxide removal portfolios by adjusting resource usage and constraints.
|
| 17 |
-
</div>
|
| 18 |
<br>
|
| 19 |
""", unsafe_allow_html=True)
|
| 20 |
|
|
|
|
| 11 |
st.markdown('<h1 class="crra-heading">Welcome!</h1>', unsafe_allow_html=True)
|
| 12 |
show_bar()
|
| 13 |
|
| 14 |
+
st.markdown("""
|
| 15 |
<div class='custom-corps'>
|
| 16 |
This tool helps you exploring how to optimize your carbon dioxide removal portfolios by adjusting resource usage and constraints.
|
| 17 |
+
</div>
|
| 18 |
<br>
|
| 19 |
""", unsafe_allow_html=True)
|
| 20 |
|