Spaces:
Running
Running
Download app.py from CGdev/CRRA_optimisation_tool: direct link, hf CLI and curl.
- Browser
- Download file 4.41 kB
-
https://huggingface.co/spaces/CGdev/CRRA_optimisation_tool/resolve/426e34612f74fc5cffe06ac825fd39eeb9bdfb2f/app.py
- Command line
-
hf download hf://spaces/CGdev/CRRA_optimisation_tool@426e34612f74fc5cffe06ac825fd39eeb9bdfb2f/app.py
-
curl -L -o app.py https://huggingface.co/spaces/CGdev/CRRA_optimisation_tool/resolve/426e34612f74fc5cffe06ac825fd39eeb9bdfb2f/app.py
4.41 kB
| import hashlib | |
| import os | |
| import sys | |
| import subprocess | |
| import pathlib | |
| import streamlit as st | |
| from streamlit_option_menu import option_menu | |
| # ── Auto-update: regenerate JSON files if inputs_aggregated.csv has changed ─── | |
| # Uses a hash file to detect changes — works both locally and on Hugging Face. | |
| # Must run before importing config/tabs, which read the generated JSON files. | |
| csv = "data/inputs_aggregated.csv" | |
| hash_file = "data/.csv_hash" | |
| generated = [ | |
| "data/cost_sliders.json", | |
| "data/method_groups.json", | |
| "data/secondary_resources.json", | |
| ] | |
| def md5(path): | |
| hasher = hashlib.md5() | |
| with open(path, "rb") as f: | |
| hasher.update(f.read()) | |
| return hasher.hexdigest() | |
| if os.path.exists(csv): | |
| current_hash = md5(csv) | |
| stored_hash = open(hash_file).read().strip() if os.path.exists(hash_file) else "" | |
| missing = any(not os.path.exists(f) for f in generated) | |
| if current_hash != stored_hash or missing: | |
| print("inputs_aggregated.csv has changed — running data/update.py ...") | |
| subprocess.run([sys.executable, "data/update.py"], check=True) | |
| with open(hash_file, "w") as file: | |
| file.write(current_hash) | |
| print("Data files updated successfully.") | |
| from tabs import (tab0_welcome, tab1_inputs, tab2_constraints, | |
| tab3_coefficients, tab4_optimization, tab5_sensitivity, | |
| tab6_scenarios) | |
| from utils.data_utils import load_slider_data, strip_unit_suffix | |
| from config.config import method_order, secondary_resources | |
| st.set_page_config("Carbon Portfolio Optimizer", layout="wide") | |
| def load_css(file_path): | |
| with open(file_path) as f: | |
| st.markdown(f"<style>{f.read()}</style>", unsafe_allow_html=True) | |
| css_path = pathlib.Path("assets/styles.css") | |
| load_css(css_path) | |
| st.markdown('<h1 class="custom-title">CRRA <span class="crra-hl">Toolkit</span>: CDR Portfolio Optimization</h1>', unsafe_allow_html=True) | |
| with st.sidebar: | |
| selected = option_menu( | |
| "Navigation", | |
| options=[ | |
| "Welcome", | |
| "Resource inputs", | |
| "Method constraints", | |
| "Resource coefficients", | |
| "Portfolio generation", | |
| "Sensitivity analysis", | |
| "Scenario comparison", | |
| ], | |
| icons=["house", "upload", "gear", "sliders", "graph-up-arrow", "card-checklist", "search"], | |
| default_index=0, | |
| orientation="vertical", | |
| key="crra-menu", | |
| styles={ | |
| "container":{ | |
| "border-radius":"0px", | |
| }, | |
| "menu-title":{ | |
| "font-family": "Segoe UI, sans-serif", | |
| "font-weight":"bold", | |
| "color": "#ff5f4d", | |
| "text-transform": "uppercase", | |
| "font-style": "italic", | |
| }, | |
| "nav-link": { | |
| "font-family": "Segoe UI, sans-serif", | |
| "margin": "4px 0", | |
| "--hover-color": "#F5F5F5", | |
| "text-transform": "uppercase", | |
| "font-weight":"600", | |
| "font-style": "italic", | |
| }, | |
| "nav-link-selected": { | |
| "background-color": "#eae9d8", | |
| "color": "#298231", | |
| "font-weight": "900", | |
| }, | |
| } | |
| ) | |
| if "constraints" not in st.session_state: | |
| st.session_state.constraints = {} | |
| for m in method_order: | |
| if m not in st.session_state.constraints: | |
| st.session_state.constraints[m] = {"active": True, "cap_type": "percent", "cap_value": 100} | |
| cost_sliders = load_slider_data() | |
| if "costs" not in st.session_state or st.session_state.costs == {}: | |
| st.session_state.costs = { | |
| m: { | |
| strip_unit_suffix(r): (0.0 if (m, strip_unit_suffix(r)) in secondary_resources else cost_sliders[m][r]["median"]) | |
| for r in cost_sliders[m] | |
| } | |
| for m in cost_sliders | |
| } | |
| if selected == "Welcome": | |
| tab0_welcome.render_tab() | |
| elif selected == "Resource inputs": | |
| tab1_inputs.render_tab(cost_sliders) | |
| elif selected == "Method constraints": | |
| tab2_constraints.render_tab() | |
| elif selected == "Resource coefficients": | |
| tab3_coefficients.render_tab(cost_sliders) | |
| elif selected == "Portfolio generation": | |
| tab4_optimization.render_tab() | |
| elif selected == "Sensitivity analysis": | |
| tab5_sensitivity.render_tab() | |
| elif selected == "Scenario comparison": | |
| tab6_scenarios.render_tab() |