CarlyneB commited on
Commit
6b18587
Β·
1 Parent(s): e391f61

[FIX] app: initialize session state at app level to prevent crashes on direct tab navigation

Browse files
Files changed (2) hide show
  1. app.py +30 -1
  2. 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 config.config import method_order, secondary_resources, hidden_resource_names
 
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(f"""
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