import streamlit as st import pandas as pd import matplotlib.pyplot as plt from io import BytesIO import base64 import random import io import re from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas from streamlit_tags import st_tags from streamlit_vertical_slider import vertical_slider import pdf_generator import datetime # Set page config st.set_page_config( page_title="Pilot Drafting", page_icon="🛫", layout="wide", initial_sidebar_state="collapsed" ) # Password protection def check_password(): def password_entered(): if st.session_state["password"] == st.secrets["app_password"]: st.session_state["password_correct"] = True del st.session_state["password"] else: st.session_state["password_correct"] = False if "password_correct" not in st.session_state: st.markdown("\n\n") st.text_input("Enter the password", type="password", on_change=password_entered, key="password") st.divider() st.info("Developed by Milan Mrdenovic © IBM Norway 2025") return False elif not st.session_state["password_correct"]: st.markdown("\n\n") st.text_input("Enter the password", type="password", on_change=password_entered, key="password") st.divider() st.info("Developed by Milan Mrdenovic © IBM Norway 2025") st.error("😕 Password incorrect") return False else: return True if not check_password(): st.stop() # Initialize session state if 'current_page' not in st.session_state: st.session_state.current_page = 0 if 'answers' not in st.session_state: st.session_state.answers = { 'workload_scope': { 'feature_prioritization': ['', '', '', '', ''], 'preferred_start_period': '', 'team_composition': { 'partner': '', 'ibm': '' } }, 'useful_assets': { 'solution_elements': [], 'ibm_software': [], 'open_source_supports': [] }, 'pilot_evaluation': { 'metrics': [] } } # Define the content for each page pages = [ { 'title': "Scope a Manageable Workload", 'content': """ Define the scope of your project to ensure a manageable workload. Consider the time commitments, deadlines, and feature prioritization. """, 'input_key': 'workload_scope', 'input_type': 'custom' }, { 'title': "Solution Elements", 'content': """ Discuss the useful assets and libraries that can be utilized for the project. Consider Langchain, Langflow, ChromaDB, Jupyter Notebooks, etc. """, 'input_key': 'useful_assets', 'input_type': 'custom' }, { 'title': "Pilot Evaluation", 'content': """ Plan for the metrics that need to be tracked for the project. Consider queries, token usage, F1 scores, precision, etc. """, 'input_key': 'pilot_evaluation', 'input_type': 'custom' }, { 'title': "Generate Evaluation Report", 'content': "You have completed the Pilot Drafting. \nClick the button below to generate and download your PDF report.", 'input_key': None } ] st.session_state.pages = pages # Main Streamlit app st.title("Pilot Drafting") # Navigation buttons col1, col2, col3 = st.columns([1, 2, 1]) with col1: if st.session_state.current_page > 0: if st.button("Back"): st.session_state.current_page -= 1 st.rerun() with col3: if st.session_state.current_page < len(pages) - 1: if st.button("Next", use_container_width=True): st.session_state.current_page += 1 st.rerun() # Display current page current_page = pages[st.session_state.current_page] st.header(current_page['title']) with st.expander("Description", expanded=False): st.markdown(current_page['content']) # Input fields if 'input_key' in current_page and current_page['input_key'] is not None: if current_page['input_key'] == 'workload_scope': st.subheader("Workload Scope") col1, col2, col3 = st.columns(3) with col1: st.session_state.answers['workload_scope']['feature_prioritization'] = [st.text_area(f"Feature Prioritization {i+1}", value=st.session_state.answers['workload_scope']['feature_prioritization'][i], height=100) for i in range(5)] with col2: st.session_state.answers['workload_scope']['preferred_start_period'] = st.date_input("Preferred Start Period", value=(datetime.date.today(), datetime.date.today() + datetime.timedelta(days=30))) with col3: st.session_state.answers['workload_scope']['team_composition']['partner'] = st.text_area("Partner", value=st.session_state.answers['workload_scope']['team_composition']['partner'], height=150) st.session_state.answers['workload_scope']['team_composition']['ibm'] = st.text_area("IBM", value=st.session_state.answers['workload_scope']['team_composition']['ibm'], height=150) elif current_page['input_key'] == 'useful_assets': st.info(st.session_state.answers['workload_scope']['feature_prioritization']) st.subheader("Solution Elements") col1, col2 = st.columns(2) with col1: st.session_state.answers['useful_assets']['ibm_software'] = st_tags(label='Enter IBM Software:', text='Press enter to add more', value=st.session_state.answers['useful_assets']['ibm_software'], suggestions=[], maxtags=5, key='ibm_software') with col2: st.session_state.answers['useful_assets']['open_source_supports'] = st_tags(label='Enter Open Source Supports:', text='Press enter to add more', value=st.session_state.answers['useful_assets']['open_source_supports'], suggestions=[], maxtags=5, key='open_source_supports') elif current_page['input_key'] == 'pilot_evaluation': st.subheader("Evaluation Criteria") col1, col2 = st.columns(2) with col1: qualitative_criteria = st_tags(label='Enter Qualitative Criteria:', text='Press enter to add more', value=st.session_state.answers['useful_assets'].get('qualitative', []), suggestions=[], maxtags=5, key='qualitative_criteria') st.session_state.answers['useful_assets']['qualitative'] = qualitative_criteria # Add description fields for each qualitative criterion for i, criterion in enumerate(qualitative_criteria): description_key = f'qual_desc_{i}' description = st.text_area(f"Description for {criterion}:", value=st.session_state.answers['useful_assets'].get(description_key, ""), key=description_key, height=100) st.session_state.answers['useful_assets'][description_key] = description with col2: quantitative_criteria = st_tags(label='Enter Quantitative Criteria:', text='Use format: CriteriaName[min - max] (can use %, floats, or integers)', value=st.session_state.answers['useful_assets'].get('quantitative', []), suggestions=[], maxtags=5, key='quantitative_criteria') st.session_state.answers['useful_assets']['quantitative'] = quantitative_criteria if quantitative_criteria: slider_cols = st.columns(len(quantitative_criteria)) for i, (criterion, slider_col) in enumerate(zip(quantitative_criteria, slider_cols)): parsed = pdf_generator.parse_quantitative_criteria(criterion) if parsed: name, min_val, max_val, is_percentage, is_integer = parsed current_value = st.session_state.answers['useful_assets'].get(f'quant_value_{i}', min_val) with slider_col: value = vertical_slider(label=name, key=f"quant_slider_{i}", min_value=min_val, max_value=max_val, step=(max_val - min_val) / 100, default_value=current_value, height=200, thumb_shape="circle", thumb_color="#9999FF", slider_color=('green', 'orange'), value_always_visible=True) st.session_state.answers['useful_assets'][f'quant_value_{i}'] = value if is_percentage: st.markdown(f"**{name}: {value:.1f}%**") # st.markdown(f"**{name}: {value*100:.1f}%**") elif is_integer: st.markdown(f"**{name}: {int(value)}**") else: st.markdown(f"**{name}: {value:.2f}**") else: st.warning(f"Invalid format for quantitative criterion: {criterion}") # Generate PDF button (only on the last page) if st.session_state.current_page == len(pages) - 1: if st.button("Generate and Download PDF", use_container_width=True): pdf = pdf_generator.generate_pdf(st.session_state) st.download_button(label="Download PDF", data=pdf, file_name="Pilot_Drafting.pdf", mime="application/pdf", use_container_width=True) # Display progress st.progress((st.session_state.current_page + 1) / len(pages)) st.divider()