import streamlit as st import requests import json import time import random import os API_URL = os.getenv("API_URL") TRANSITION_MESSAGES = [ "Now we are moving onto question {number}!", "Time to switch to question {number}!", "Let's proceed with question {number}!", "Moving forward to question {number}!", "Onward to question {number}!" ] TAB1_FILE = "tab1.txt" TAB1_FALLBACK = """ # Registration System Demo Data quality issues have long plagued council databases, burdening W2 workflow teams (e.g. the Assisted Travel Team's dashboard I am working on), data analysts, and engineers with manual cleaning and validation. This pilot explores how AI-driven workflows can address these pain points by streamlining user registration, ensuring accurate data collection, and reducing validation overhead. *If you see this message, `tab1.txt` was not found. Please upload it to the app directory for the full intro page.* """ def read_content_from_file(file_path): try: with open(file_path, 'r') as file: return file.read() except FileNotFoundError: return TAB1_FALLBACK def reset_registration_state(): for key in [ "session_id", "current_question", "answer", "feedback", "summary", "skip_address", "skip_phone", "prev_question", "question_number", "edit_field_values" ]: if key in st.session_state: del st.session_state[key] def start_registration(): reset_registration_state() try: headers = {"Origin": "https://entz-council-3.hf.space"} response = requests.post(f"{API_URL}/start_registration", headers=headers, timeout=2) response.raise_for_status() data = response.json() st.session_state.session_id = data["session_id"] st.session_state.current_question = data["message"] st.session_state.feedback = "" st.session_state.summary = None st.session_state.answer = "" st.session_state.skip_address = False st.session_state.skip_phone = False st.session_state.prev_question = "" st.session_state.question_number = 1 st.session_state.edit_field_values = {} except requests.RequestException as e: st.error(f"Error starting registration: {e}") def submit_response(): if not st.session_state.session_id: st.error("No active session. Please start registration.") return skip_steps = [] if st.session_state.get("skip_address", False): skip_steps.append("ask_address") if st.session_state.get("skip_phone", False): skip_steps.append("ask_phone") payload = { "session_id": st.session_state.session_id, "answer": st.session_state.answer, "skip_steps": skip_steps } try: response = requests.post(f"{API_URL}/submit_response", json=payload) response.raise_for_status() data = response.json() if data.get("message") == "Registration complete!": st.session_state.summary = data["summary"] st.session_state.current_question = "" st.session_state.feedback = "Registration complete!" st.session_state.question_number = 1 else: st.session_state.prev_question = st.session_state.current_question st.session_state.current_question = data.get("next_question", "") st.session_state.feedback = data.get("validation_feedback", "") if st.session_state.prev_question != st.session_state.current_question: st.session_state.question_number += 1 st.session_state.answer = "" st.session_state.skip_address = False st.session_state.skip_phone = False st.rerun() except requests.RequestException as e: st.error(f"Error submitting response: {e}") def edit_field(field, value): if not st.session_state.session_id: st.error("No active session.") return payload = { "session_id": st.session_state.session_id, "field_to_edit": field, "new_value": value } try: response = requests.post(f"{API_URL}/edit_field", json=payload) response.raise_for_status() data = response.json() st.session_state.feedback = data.get("validation_feedback", "") st.session_state.summary = data.get("summary", st.session_state.summary) if data.get("message") == "Needs clarification": st.error(f"Clarification needed for {field}: {data['validation_feedback']}") elif data.get("message") == "Field updated successfully!": st.success("Database updated.") st.rerun() except requests.RequestException as e: st.error(f"Error editing field: {e}") def ensure_registration_state(): if "session_id" not in st.session_state: start_registration() if "edit_field_values" not in st.session_state: st.session_state.edit_field_values = {} def run_registration_app(): ensure_registration_state() st.title("AI-Powered Registration System") st.markdown("*** If 403 or other connection errors, please refresh the page every 1 minute, because the backend server is being spun up. Developed by entzyeung@gmail.com**") if st.session_state.summary: st.success("Registration Complete!") st.subheader("Summary") for key, value in st.session_state.summary.items(): edit_key = f"edit_{key}" if edit_key not in st.session_state.edit_field_values: st.session_state.edit_field_values[edit_key] = "" st.write(f"**{key}**: {value}") st.session_state.edit_field_values[edit_key] = st.text_input( f"Edit {key}", value=st.session_state.edit_field_values[edit_key], key=edit_key ) if st.button(f"Update {key}", key=f"update_{key}"): edit_field(key, st.session_state.edit_field_values[edit_key]) col1, col2 = st.columns(2) with col1: if st.button("Next Registration", key="next_reg"): start_registration() st.rerun() with col2: if st.button("End Session", key="end_sess"): reset_registration_state() st.success("Session ended. Please select 'Registration' tab to start again.") elif st.session_state.current_question: if st.session_state.feedback and st.session_state.feedback != "Registration complete!": st.error(st.session_state.feedback) if st.session_state.prev_question and st.session_state.prev_question != st.session_state.current_question: transition_msg = random.choice(TRANSITION_MESSAGES).format(number=st.session_state.question_number) st.info(transition_msg) time.sleep(1) st.subheader(f"Question {st.session_state.question_number}: {st.session_state.current_question}") is_address_question = st.session_state.current_question.strip().lower() == "what is your address?" is_phone_question = st.session_state.current_question.strip().lower() == "what is your phone number?" if is_address_question or is_phone_question: st.info( f"This question is optional. Check the box to skip, or enter your information below.\n" f"- For address: Include house number (e.g., 123), street name (e.g., High Street), town/city (e.g., London), and postcode (e.g., SW1A 1AA). Example: 123 High Street, London, SW1A 1AA.\n" f"- For phone: Use 10 digits for landlines (e.g., 020 123 4567) or 11 digits for mobiles starting with 07 (e.g., 07700 900 123). Do not use +44 or other region numbers." ) if is_address_question: st.session_state.skip_address = st.checkbox("Skip this question", value=st.session_state.skip_address, key="skip_address_checkbox") elif is_phone_question: st.session_state.skip_phone = st.checkbox("Skip this question", value=st.session_state.skip_phone, key="skip_phone_checkbox") answer_key = f"answer_input_q{st.session_state.question_number}" st.session_state.answer = st.text_input( "Your Answer", value=st.session_state.answer, key=answer_key ) if st.button("Submit", key=f"submit_button_q{st.session_state.question_number}"): submit_response() else: st.info("Initializing registration session...") tab1, tab2 = st.tabs(["Intro", "Registration"]) with tab1: st.markdown(read_content_from_file(TAB1_FILE)) with tab2: run_registration_app()