Spaces:
Sleeping
Sleeping
| # Use default Streamlit page configuration | |
| import streamlit as st | |
| # Configure the Streamlit app to use a wide layout for maximum content width | |
| st.set_page_config(layout="wide") | |
| def main(): | |
| from pathlib import Path | |
| from datetime import datetime, timedelta | |
| from pre import preprocess_uploaded_file | |
| from environment_loader import get_environments_paths | |
| from multiple import perform_analysis | |
| import getpass | |
| # Sidebar: Environment selection and loading options | |
| st.sidebar.header("Auto Environment Loader") | |
| base_path = st.sidebar.text_input("Base folder path", "Q:/Selenium_Reports") | |
| # Profile-based defaults for functional areas | |
| profiles = { | |
| "Daniel": [ | |
| "Services - Gamification*", | |
| "Services - Job Manager*", | |
| "Services - Measurements*", | |
| "Services - Multimedia*", | |
| "Services - Platform*", | |
| ], | |
| } | |
| # Determine a sensible default profile | |
| try: | |
| current_user = getpass.getuser().lower() | |
| default_profile = "Daniel" if "daniel" in current_user else "Custom" | |
| except Exception: | |
| default_profile = "Custom" | |
| if 'selected_profile' not in st.session_state: | |
| st.session_state.selected_profile = default_profile | |
| profile_options = ["Custom"] + sorted(list(profiles.keys())) | |
| selected_profile = st.sidebar.selectbox( | |
| "Profile", | |
| options=profile_options, | |
| index=profile_options.index(st.session_state.selected_profile) if st.session_state.selected_profile in profile_options else 0, | |
| key="profile_select" | |
| ) | |
| # Apply profile defaults when a known profile is selected | |
| if selected_profile != "Custom": | |
| st.session_state.default_functional_areas = profiles[selected_profile] | |
| st.session_state.selected_profile = selected_profile | |
| # Dynamically discover available environment folders | |
| env_root = Path(base_path) | |
| try: | |
| env_codes = [p.name for p in env_root.iterdir() if p.is_dir()] | |
| except Exception: | |
| env_codes = [] | |
| st.sidebar.error(f"Could not list environments under {base_path}") | |
| selected_envs = st.sidebar.multiselect("Select environments to load", env_codes) | |
| # Optional: Auto-load on environment selection change | |
| if 'auto_load_on_select' not in st.session_state: | |
| st.session_state.auto_load_on_select = False | |
| st.session_state.auto_load_on_select = st.sidebar.checkbox( | |
| "Auto-load when selection changes", value=st.session_state.auto_load_on_select | |
| ) | |
| # Functional areas to pre-select in analysis | |
| # Once set here, downstream analysis in multiple.perform_analysis will use it as defaults | |
| if 'default_functional_areas' not in st.session_state: | |
| st.session_state.default_functional_areas = ["All"] | |
| with st.sidebar.expander("Default Functional Areas", expanded=False): | |
| # If a named profile is selected, show the values as info; otherwise allow free text edit | |
| if st.session_state.selected_profile != "Custom": | |
| st.info( | |
| ", ".join(st.session_state.default_functional_areas) or "All" | |
| ) | |
| st.caption("Controlled by profile. Switch profile to 'Custom' to edit.") | |
| else: | |
| default_fa_input = st.text_input( | |
| "Comma-separated list (e.g. Services - Gamification, Services - Platform, All)", | |
| value=", ".join(st.session_state.default_functional_areas) | |
| ) | |
| parsed = [p.strip() for p in default_fa_input.split(',') if p.strip()] | |
| if parsed: | |
| st.session_state.default_functional_areas = parsed | |
| # For envs ending with 'FIN', let user pick one of the 3 most recent files | |
| version_selection = {} | |
| for env in selected_envs: | |
| # Only FIN environments get manual version selection | |
| if env.upper().endswith('FIN'): | |
| folder = Path(base_path) / env / 'XLSX' | |
| if not folder.exists(): | |
| st.sidebar.warning(f"No folder found for environment {env}: {folder}") | |
| continue | |
| # List the 3 most recent files | |
| recent_files = sorted(folder.glob('*.xlsx'), key=lambda f: f.stat().st_mtime, reverse=True)[:3] | |
| if not recent_files: | |
| st.sidebar.warning(f"No .xlsx files found for environment {env}") | |
| continue | |
| labels = [f.name for f in recent_files] | |
| choice = st.sidebar.selectbox(f"Select version for {env}", labels, index=0, key=f"select_{env}") | |
| version_selection[env] = folder / choice | |
| # Initialize session state for incremental loading | |
| if 'loaded_envs' not in st.session_state: | |
| st.session_state.loaded_envs = [] | |
| if 'uploaded_env_data' not in st.session_state: | |
| st.session_state.uploaded_env_data = {} | |
| def load_selected_envs(): | |
| if not selected_envs: | |
| st.sidebar.warning("Please select at least one environment to load.") | |
| return | |
| # Remove any environments that were loaded but are no longer selected | |
| deselected = [env for env in st.session_state.loaded_envs if env not in selected_envs] | |
| for env in deselected: | |
| st.session_state.uploaded_env_data.pop(env, None) | |
| st.session_state.loaded_envs.remove(env) | |
| # Determine which environments are new (always reload FIN envs for version changes) | |
| fin_selected = [env for env in selected_envs if env.upper().endswith('FIN')] | |
| non_fin_selected = [env for env in selected_envs if not env.upper().endswith('FIN')] | |
| new_non_fin = [env for env in non_fin_selected if env not in st.session_state.loaded_envs] | |
| new_envs = new_non_fin + fin_selected | |
| if not new_envs: | |
| st.sidebar.info("β All selected environments are already loaded.") | |
| return | |
| # Build paths: manual picks for FIN envs, auto for others | |
| paths = {} | |
| missing = [] | |
| fin_envs = [env for env in new_envs if env.upper().endswith('FIN')] | |
| non_fin = [env for env in new_envs if not env.upper().endswith('FIN')] | |
| # FIN envs must have manual selection | |
| for env in fin_envs: | |
| path = version_selection.get(env) | |
| if not path: | |
| missing.append(env) | |
| else: | |
| paths[env] = path | |
| if missing: | |
| st.sidebar.error(f"Please select a file version for: {', '.join(missing)}") | |
| return | |
| # Auto-load latest for non-FIN envs | |
| if non_fin: | |
| auto_paths = get_environments_paths(non_fin, base_path=base_path) | |
| paths.update(auto_paths) | |
| try: | |
| dfs = [] | |
| loaded = [] | |
| failed = [] | |
| # Preprocess each new file, tracking success/failure | |
| for env, path in paths.items(): | |
| try: | |
| df = preprocess_uploaded_file(path) | |
| dfs.append(df) | |
| loaded.append((env, path)) | |
| except Exception as e: | |
| failed.append((env, path, e)) | |
| # Show ticks for successful and failed loads | |
| if loaded: | |
| st.sidebar.markdown("**β Successfully loaded:**") | |
| for env, path in loaded: | |
| st.sidebar.markdown(f"- β {env}: `{path}`") | |
| if failed: | |
| st.sidebar.markdown("**β Failed to load:**") | |
| for env, path, e in failed: | |
| st.sidebar.markdown(f"- β {env}: `{path}` ({e})") | |
| # Update session state with new loaded data | |
| for (env, _), df in zip(loaded, dfs): | |
| st.session_state.uploaded_env_data[env] = df | |
| if env not in st.session_state.loaded_envs: | |
| st.session_state.loaded_envs.append(env) | |
| # Build combined list of DataFrames for analysis | |
| st.session_state.uploaded_data = list(st.session_state.uploaded_env_data.values()) | |
| except Exception as e: | |
| st.sidebar.error(str(e)) | |
| if st.sidebar.button("Load Latest Files", use_container_width=True): | |
| load_selected_envs() | |
| # Auto-load behavior when selection changes | |
| if st.session_state.auto_load_on_select: | |
| # Track last selection to detect change | |
| if 'last_selected_envs' not in st.session_state: | |
| st.session_state.last_selected_envs = [] | |
| if sorted(st.session_state.last_selected_envs) != sorted(selected_envs): | |
| st.session_state.last_selected_envs = list(selected_envs) | |
| load_selected_envs() | |
| # Main: run analysis if data is loaded | |
| st.title("Multiple File Analysis (Auto Env Loader)") | |
| if 'uploaded_data' in st.session_state and st.session_state.uploaded_data: | |
| perform_analysis(st.session_state.uploaded_data) | |
| else: | |
| st.info("Use the sidebar to select environments and load their latest files for analysis.") | |
| if __name__ == "__main__": | |
| main() |