Entz commited on
Commit
8223e7e
·
verified ·
1 Parent(s): bb67e1f

Upload 5 files

Browse files
Files changed (5) hide show
  1. .gitignore +5 -0
  2. Dockerfile +12 -13
  3. app_structure.txt +6 -0
  4. index.py +179 -0
  5. requirements.txt +7 -3
.gitignore ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ .env
2
+ *.db
3
+ node_modules/
4
+ __pycache__/
5
+ *.pyc
Dockerfile CHANGED
@@ -1,21 +1,20 @@
1
- FROM python:3.9-slim
2
 
 
3
  WORKDIR /app
4
 
5
- RUN apt-get update && apt-get install -y \
6
- build-essential \
7
- curl \
8
- software-properties-common \
9
- git \
10
- && rm -rf /var/lib/apt/lists/*
11
 
12
- COPY requirements.txt ./
13
- COPY src/ ./src/
14
-
15
- RUN pip3 install -r requirements.txt
16
 
 
17
  EXPOSE 8501
18
 
19
- HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health
 
20
 
21
- ENTRYPOINT ["streamlit", "run", "src/streamlit_app.py", "--server.port=8501", "--server.address=0.0.0.0"]
 
 
1
+ FROM python:3.10-slim
2
 
3
+ # Set working directory in the container
4
  WORKDIR /app
5
 
6
+ # Copy requirements and install dependencies
7
+ COPY requirements.txt .
8
+ RUN pip install --no-cache-dir -r requirements.txt
 
 
 
9
 
10
+ # Copy application files
11
+ COPY index.py .
 
 
12
 
13
+ # Expose Streamlit port
14
  EXPOSE 8501
15
 
16
+ # Health check for Streamlit
17
+ HEALTHCHECK CMD curl --fail http://localhost:8501/_stcore/health || exit 1
18
 
19
+ # Run Streamlit
20
+ CMD ["streamlit", "run", "index.py", "--server.port=8501", "--server.address=0.0.0.0"]
app_structure.txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ /frontend_streamlit
2
+ ├── index.py
3
+ ├── requirements.txt
4
+ ├── README.md
5
+ ├── Dockerfile
6
+ └── .gitignore
index.py ADDED
@@ -0,0 +1,179 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import requests
3
+ import json
4
+ import time
5
+ import random
6
+ from dotenv import load_dotenv
7
+ import os
8
+
9
+
10
+
11
+ load_dotenv()
12
+ API_URL = os.getenv("API_URL", "http://localhost:8000")
13
+
14
+ TRANSITION_MESSAGES = [
15
+ "Now we are moving onto question {number}!",
16
+ "Time to switch to question {number}!",
17
+ "Let's proceed with question {number}!",
18
+ "Moving forward to question {number}!",
19
+ "Onward to question {number}!"
20
+ ]
21
+
22
+ def start_registration():
23
+ print("Starting registration...")
24
+ try:
25
+ response = requests.post(f"{API_URL}/start_registration")
26
+ response.raise_for_status()
27
+ data = response.json()
28
+ print("API Response:", data)
29
+ st.session_state.session_id = data["session_id"]
30
+ st.session_state.current_question = data["message"]
31
+ st.session_state.feedback = ""
32
+ st.session_state.summary = None
33
+ st.session_state.answer = ""
34
+ st.session_state.skip_address = False
35
+ st.session_state.skip_phone = False
36
+ st.session_state.prev_question = ""
37
+ st.session_state.question_number = 1
38
+ except requests.RequestException as e:
39
+ print(f"Error starting registration: {e}")
40
+ st.error(f"Error starting registration: {e}")
41
+
42
+ def submit_response():
43
+ if not st.session_state.session_id:
44
+ st.error("No active session. Please start registration.")
45
+ return
46
+ skip_steps = []
47
+ if st.session_state.get("skip_address", False):
48
+ skip_steps.append("ask_address")
49
+ if st.session_state.get("skip_phone", False):
50
+ skip_steps.append("ask_phone")
51
+ payload = {
52
+ "session_id": st.session_state.session_id,
53
+ "answer": st.session_state.answer,
54
+ "skip_steps": skip_steps
55
+ }
56
+ print("Submitting response with payload:", payload)
57
+ try:
58
+ response = requests.post(f"{API_URL}/submit_response", json=payload)
59
+ response.raise_for_status()
60
+ data = response.json()
61
+ print("API Response:", data)
62
+ if data.get("message") == "Registration complete!":
63
+ st.session_state.summary = data["summary"]
64
+ st.session_state.current_question = ""
65
+ st.session_state.feedback = "Registration complete!"
66
+ st.session_state.question_number = 1
67
+ else:
68
+ st.session_state.prev_question = st.session_state.current_question
69
+ st.session_state.current_question = data.get("next_question", "")
70
+ st.session_state.feedback = data.get("validation_feedback", "")
71
+ if st.session_state.prev_question != st.session_state.current_question:
72
+ st.session_state.question_number += 1
73
+ st.session_state.answer = ""
74
+ st.session_state.skip_address = False
75
+ st.session_state.skip_phone = False
76
+ st.rerun()
77
+ except requests.RequestException as e:
78
+ print(f"Error submitting response: {e}")
79
+ st.error(f"Error submitting response: {e}")
80
+
81
+ def edit_field(field, value):
82
+ if not st.session_state.session_id:
83
+ st.error("No active session.")
84
+ return
85
+ payload = {
86
+ "session_id": st.session_state.session_id,
87
+ "field_to_edit": field,
88
+ "new_value": value
89
+ }
90
+ print("Editing field with payload:", payload)
91
+ try:
92
+ response = requests.post(f"{API_URL}/edit_field", json=payload)
93
+ response.raise_for_status()
94
+ data = response.json()
95
+ print("API Response:", data)
96
+ st.session_state.feedback = data.get("validation_feedback", "")
97
+ st.session_state.summary = data.get("summary", st.session_state.summary)
98
+ if data.get("message") == "Needs clarification":
99
+ st.error(f"Clarification needed for {field}: {data['validation_feedback']}")
100
+ elif data.get("message") == "Field updated successfully!":
101
+ st.success("Database updated.")
102
+ st.rerun()
103
+ except requests.RequestException as e:
104
+ print(f"Error editing field: {e}")
105
+ st.error(f"Error editing field: {e}")
106
+
107
+ if "session_state" not in st.session_state:
108
+ st.session_state.session_state = {}
109
+ st.session_state.session_id = None
110
+ st.session_state.current_question = ""
111
+ st.session_state.answer = ""
112
+ st.session_state.feedback = ""
113
+ st.session_state.summary = None
114
+ st.session_state.skip_address = False
115
+ st.session_state.skip_phone = False
116
+ st.session_state.prev_question = ""
117
+ st.session_state.question_number = 1
118
+
119
+ if st.session_state.session_id is None:
120
+ start_registration()
121
+
122
+ st.title("AI-Powered Registration System")
123
+
124
+ if st.session_state.summary:
125
+ st.success("Registration Complete!")
126
+ st.subheader("Summary")
127
+ for key, value in st.session_state.summary.items():
128
+ st.write(f"**{key}**: {value}")
129
+ new_value = st.text_input(f"Edit {key}", key=f"edit_{key}")
130
+ if st.button(f"Update {key}", key=f"update_{key}"):
131
+ edit_field(key, new_value)
132
+ col1, col2 = st.columns(2)
133
+ with col1:
134
+ if st.button("Next Registration", key="next_reg", on_click=start_registration):
135
+ pass
136
+ with col2:
137
+ if st.button("End Session", key="end_sess", on_click=start_registration):
138
+ pass
139
+ else:
140
+ if st.session_state.current_question:
141
+ if st.session_state.feedback:
142
+ st.error(st.session_state.feedback)
143
+ if st.session_state.prev_question and st.session_state.prev_question != st.session_state.current_question:
144
+ transition_msg = random.choice(TRANSITION_MESSAGES).format(number=st.session_state.question_number)
145
+ st.info(transition_msg)
146
+ time.sleep(1)
147
+ print(f"Displaying question: {st.session_state.current_question}")
148
+ st.subheader(f"Question {st.session_state.question_number}: {st.session_state.current_question}")
149
+
150
+ is_address_question = st.session_state.current_question == "What is your address?"
151
+ is_phone_question = st.session_state.current_question == "What is your phone number?"
152
+
153
+ if is_address_question or is_phone_question:
154
+ st.info(
155
+ f"This question is optional. Check the box to skip, or enter your information below.\n"
156
+ 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"
157
+ 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."
158
+ )
159
+ if is_address_question:
160
+ st.session_state.skip_address = st.checkbox("Skip this question", value=st.session_state.skip_address)
161
+ elif is_phone_question:
162
+ st.session_state.skip_phone = st.checkbox("Skip this question", value=st.session_state.skip_phone)
163
+
164
+ st.components.v1.html("""
165
+ document.addEventListener('keypress', function(e) {
166
+ if (e.key === 'Enter' && document.activeElement.tagName === 'INPUT') {
167
+ e.preventDefault();
168
+ const submitButton = document.querySelector('button[key="submit_button"]');
169
+ if (submitButton && !submitButton.disabled) submitButton.click();
170
+ }
171
+ });
172
+ """, height=0)
173
+
174
+ st.session_state.answer = st.text_input("Your Answer", value="", key=f"answer_input_{st.session_state.question_number}")
175
+
176
+ if st.button("Submit", key="submit_button"):
177
+ submit_response()
178
+ else:
179
+ print("Waiting for session to initialize...")
requirements.txt CHANGED
@@ -1,3 +1,7 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
1
+ # Frontend
2
+ python-dotenv==1.1.0
3
+
4
+ requests==2.32.4
5
+
6
+
7
+ streamlit==1.46.0