minimal example working with translator api
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
API client functions for interacting with the Airport Announcement System backend.
|
||||
"""
|
||||
import requests
|
||||
from typing import List, Optional
|
||||
from typing import List, Optional, Dict, Any
|
||||
|
||||
# This can be overridden through environment variables
|
||||
API_BASE_URL = "http://localhost:7999"
|
||||
@@ -40,19 +40,29 @@ def delete_group(group_id: int) -> None:
|
||||
|
||||
def start_announcement(text: str, group_id: int) -> None:
|
||||
"""Start a new announcement."""
|
||||
response = requests.post(f"{API_BASE_URL}/announcements", params={"text": text, "group_id": group_id})
|
||||
# Changed from /announcements to /announcement to match translator_api.py
|
||||
response = requests.post(f"{API_BASE_URL}/announcement", params={"text": text, "group_id": group_id})
|
||||
response.raise_for_status()
|
||||
|
||||
def get_announcement_status() -> dict:
|
||||
"""Get the status of the current announcement."""
|
||||
response = requests.get(f"{API_BASE_URL}/announcements/status")
|
||||
response.raise_for_status()
|
||||
return response.json()
|
||||
def get_group_state(group_id: int) -> Dict[str, Any]:
|
||||
"""Get the status of the current announcement for a specific group.
|
||||
|
||||
Args:
|
||||
group_id: The ID of the group to check the announcement status for
|
||||
|
||||
Returns:
|
||||
Dictionary with 'name' and 'value' keys representing the current state
|
||||
"""
|
||||
response = requests.get(f"{API_BASE_URL}/groups/{group_id}/state")
|
||||
|
||||
state = response.json()
|
||||
return state
|
||||
|
||||
def get_available_endpoints() -> List[str]:
|
||||
"""Get all available endpoints."""
|
||||
response = requests.get(f"{API_BASE_URL}/endpoints")
|
||||
response.raise_for_status()
|
||||
# Transform the endpoint objects to match the expected format in app.py
|
||||
return response.json()
|
||||
|
||||
def get_available_languages() -> List[str]:
|
||||
|
||||
@@ -9,7 +9,7 @@ st.set_page_config(page_title="Airport Announcement System", page_icon="✈️")
|
||||
import time
|
||||
import requests
|
||||
from api_client.client import (
|
||||
get_groups, get_available_languages, get_announcement_status,
|
||||
get_groups, get_available_languages, get_group_state,
|
||||
start_announcement, update_group, get_available_endpoints
|
||||
)
|
||||
|
||||
@@ -31,19 +31,31 @@ if "available_languages" not in st.session_state:
|
||||
|
||||
# Initialize session state for announcement text and status tracking
|
||||
if "announcement_text" not in st.session_state:
|
||||
st.session_state.announcement_text = "Hallo Welt."
|
||||
st.session_state.announcement_text = "Achtung bitte! Der Flug LH-2456 nach München ist jetzt zum Einsteigen bereit am Gate B12."
|
||||
if "show_success_message" not in st.session_state:
|
||||
st.session_state.show_success_message = False
|
||||
if "announcement_id" not in st.session_state:
|
||||
st.session_state.announcement_id = 0
|
||||
if "status_container_key" not in st.session_state:
|
||||
st.session_state.status_container_key = 0
|
||||
if "selected_group_id" not in st.session_state:
|
||||
st.session_state.selected_group_id = None
|
||||
|
||||
|
||||
def show_announcement_status():
|
||||
def show_announcement_status(group_id: int):
|
||||
"""Show the status of an announcement for a specific group."""
|
||||
try:
|
||||
status_data = get_announcement_status()
|
||||
if status_data["state"] != "idle":
|
||||
# Get the group for additional information
|
||||
group = next((g for g in st.session_state.endpoint_groups if g["id"] == group_id), None)
|
||||
if not group:
|
||||
st.error(f"Group with ID {group_id} not found")
|
||||
return
|
||||
|
||||
# Get the state from the API
|
||||
state = get_group_state(group_id)
|
||||
|
||||
# Only show status if state is not IDLE
|
||||
if state["value"] != 0:
|
||||
# Create a container with a unique key for each announcement
|
||||
# This ensures we get a fresh container for each new announcement
|
||||
with st.container(key=f"status_container_{st.session_state.status_container_key}"):
|
||||
@@ -51,44 +63,72 @@ def show_announcement_status():
|
||||
status = st.status("**Airport PA System Status**", expanded=True)
|
||||
|
||||
with status:
|
||||
# Calculate progress from state value (normalize to 0.0-1.0 range)
|
||||
# Assuming states are ordered from IDLE(0) to COMPLETED(4)
|
||||
max_state_value = 4 # COMPLETED is the maximum state value
|
||||
progress = min(state["value"] / max_state_value, 1.0)
|
||||
|
||||
# Progress elements
|
||||
progress_bar = st.progress(status_data["progress"])
|
||||
progress_bar = st.progress(progress)
|
||||
time_col, stage_col = st.columns([1, 3])
|
||||
|
||||
# Track last displayed state
|
||||
last_state = None
|
||||
|
||||
# Update loop
|
||||
while status_data["state"] not in ["complete", "error"]:
|
||||
# Update time elapsed continuously
|
||||
|
||||
# Only update stage display if state changed
|
||||
if status_data["state"] != last_state:
|
||||
stage_col.write(f"**Stage:** {status_data['state']}")
|
||||
last_state = status_data["state"]
|
||||
time_col.write(f"⏱️ Time elapsed: {time.time() - status_data['details']['start_time']:.1f}s")
|
||||
|
||||
# Update progress bar
|
||||
progress_bar.progress(status_data["progress"])
|
||||
time.sleep(0.3)
|
||||
|
||||
# Refresh status data
|
||||
status_data = get_announcement_status()
|
||||
# Add timeout mechanism
|
||||
max_wait_time = 60 # Maximum wait time in seconds
|
||||
start_tracking_time = time.time()
|
||||
|
||||
# Make sure to update the progress bar one final time with the final state's progress value
|
||||
progress_bar.progress(status_data["progress"])
|
||||
# Update loop
|
||||
while state["name"] not in ["COMPLETED", "IDLE"]:
|
||||
# Check for timeout
|
||||
elapsed_time = time.time() - start_tracking_time
|
||||
if elapsed_time > max_wait_time:
|
||||
st.warning(f"Status tracking timed out after {max_wait_time} seconds")
|
||||
break
|
||||
|
||||
# Only update stage display if state changed
|
||||
if state != last_state:
|
||||
stage_col.write(f"**Stage:** {state['name']}")
|
||||
last_state = state
|
||||
|
||||
# Show start time if available
|
||||
start_time = group.get("anouncement_start_time", time.time())
|
||||
time_col.write(f"⏱️ Time elapsed: {time.time() - start_time:.1f}s")
|
||||
|
||||
# Update progress bar directly from state value
|
||||
progress = min(state["value"] / max_state_value, 1.0)
|
||||
progress_bar.progress(progress)
|
||||
|
||||
# Add a small delay between requests to avoid hammering the API
|
||||
time.sleep(0.5)
|
||||
|
||||
# Refresh state
|
||||
state = get_group_state(group_id)
|
||||
|
||||
# Final update to progress bar
|
||||
progress = min(state["value"] / max_state_value, 1.0)
|
||||
progress_bar.progress(progress)
|
||||
|
||||
# Final state
|
||||
if status_data["state"] == "error":
|
||||
st.error(f"❌ Error: {status_data['error']}")
|
||||
else:
|
||||
if state["name"] == "COMPLETED":
|
||||
st.success("✅ Announcement completed successfully")
|
||||
st.write(f"📢 Announcement made to group {status_data['details']['group']['name']}:")
|
||||
st.write(f"📡 Endpoints: {', '.join(status_data['details']['group']['endpoints'])}")
|
||||
st.write(f"🗣️ '{status_data['details']['text']}'")
|
||||
|
||||
# Display language codes directly
|
||||
st.write(f"🌐 Languages: {', '.join(status_data['details']['languages'])}")
|
||||
# Display group information
|
||||
st.write(f"📢 Announcement made to group {group.get('name', '')}")
|
||||
|
||||
# Display endpoints if available
|
||||
endpoints = group.get("endpoints", [])
|
||||
if endpoints:
|
||||
endpoint_names = [ep.get("name", ep) for ep in endpoints if isinstance(ep, dict)]
|
||||
if not endpoint_names: # Handle case where endpoints is a list of strings
|
||||
endpoint_names = endpoints
|
||||
st.write(f"📡 Endpoints: {', '.join(endpoint_names)}")
|
||||
|
||||
# Display languages if available
|
||||
languages = group.get("languages", [])
|
||||
if languages:
|
||||
st.write(f"🌐 Languages: {', '.join(languages)}")
|
||||
|
||||
# Clear the success message when announcement completes
|
||||
st.session_state.show_success_message = False
|
||||
@@ -108,14 +148,14 @@ with st.container():
|
||||
st.write("**Predefined Announcements** (click to autofill)")
|
||||
col1, col2, col3 = st.columns(3)
|
||||
with col1:
|
||||
if st.button("Final Boarding Call"):
|
||||
st.session_state.announcement_text = "This is the final boarding call for flight LX-380 to New York"
|
||||
if st.button("Letzter Aufruf"):
|
||||
st.session_state.announcement_text = "Dies ist der letzte Aufruf für Flug LH-380 nach Berlin. Bitte begeben Sie sich sofort zum Gate B15."
|
||||
with col2:
|
||||
if st.button("Security Reminder"):
|
||||
st.session_state.announcement_text = "Please keep your luggage with you at all times"
|
||||
if st.button("Sicherheitshinweis"):
|
||||
st.session_state.announcement_text = "Aus Sicherheitsgründen bitten wir Sie, Ihr Gepäck niemals unbeaufsichtigt zu lassen."
|
||||
with col3:
|
||||
if st.button("Delay Notice"):
|
||||
st.session_state.announcement_text = "We regret to inform you of a 30-minute delay"
|
||||
if st.button("Verspätung"):
|
||||
st.session_state.announcement_text = "Wir bedauern mitteilen zu müssen, dass sich der Flug LH-472 um 30 Minuten verspätet."
|
||||
|
||||
# Custom announcement
|
||||
with st.form("custom_announcement"):
|
||||
@@ -123,26 +163,32 @@ with st.container():
|
||||
group_options = [(g["name"], g["id"]) for g in st.session_state.endpoint_groups]
|
||||
selected_group_name = st.selectbox(
|
||||
"Select announcement area",
|
||||
options=[g[0] for g in group_options]
|
||||
options=[g[0] for g in group_options] if group_options else ["No groups available"]
|
||||
)
|
||||
message = st.text_area("Enter announcement text", st.session_state.announcement_text)
|
||||
|
||||
if st.form_submit_button("Make Announcement"):
|
||||
try:
|
||||
selected_group_id = next(g[1] for g in group_options if g[0] == selected_group_name)
|
||||
start_announcement(message, selected_group_id)
|
||||
|
||||
# Set flag to show success message
|
||||
st.session_state.show_success_message = True
|
||||
|
||||
# Increment announcement ID to ensure a fresh status container
|
||||
st.session_state.announcement_id += 1
|
||||
st.session_state.status_container_key = st.session_state.announcement_id
|
||||
|
||||
# Clear the announcement text after successful submission
|
||||
st.session_state.announcement_text = ""
|
||||
except requests.exceptions.RequestException as e:
|
||||
st.error(f"Failed to start announcement: {str(e)}")
|
||||
if not group_options:
|
||||
st.error("No endpoint groups available. Please create a group first.")
|
||||
else:
|
||||
try:
|
||||
selected_group_id = next(g[1] for g in group_options if g[0] == selected_group_name)
|
||||
# Save the selected group ID for status tracking
|
||||
st.session_state.selected_group_id = selected_group_id
|
||||
|
||||
start_announcement(message, selected_group_id)
|
||||
|
||||
# Set flag to show success message
|
||||
st.session_state.show_success_message = True
|
||||
|
||||
# Increment announcement ID to ensure a fresh status container
|
||||
st.session_state.announcement_id += 1
|
||||
st.session_state.status_container_key = st.session_state.announcement_id
|
||||
|
||||
# Clear the announcement text after successful submission
|
||||
st.session_state.announcement_text = ""
|
||||
except requests.exceptions.RequestException as e:
|
||||
st.error(f"Failed to start announcement: {str(e)}")
|
||||
|
||||
# Configuration section in sidebar
|
||||
with st.sidebar:
|
||||
@@ -181,33 +227,53 @@ with st.sidebar:
|
||||
st.error(f"Failed to update group name: {str(e)}")
|
||||
|
||||
try:
|
||||
available_endpoints = get_available_endpoints()
|
||||
endpoints_dict = get_available_endpoints()
|
||||
# Extract endpoint names from the endpoints dictionary
|
||||
available_endpoint_names = []
|
||||
for endpoint_id, endpoint_data in endpoints_dict.items():
|
||||
if isinstance(endpoint_data, dict) and "name" in endpoint_data:
|
||||
available_endpoint_names.append(endpoint_data["name"])
|
||||
|
||||
# Use a unique key for the endpoints multiselect
|
||||
endpoints_key = f"endpoints_select_{i}"
|
||||
|
||||
# Initialize the previous value in session state if not present
|
||||
if f"prev_{endpoints_key}" not in st.session_state:
|
||||
st.session_state[f"prev_{endpoints_key}"] = group["endpoints"]
|
||||
st.session_state[f"prev_{endpoints_key}"] = group.get("endpoints", [])
|
||||
|
||||
# Extract endpoint names from group.endpoints if they are dictionaries
|
||||
current_endpoints = []
|
||||
for ep in group.get("endpoints", []):
|
||||
if isinstance(ep, dict) and "name" in ep:
|
||||
current_endpoints.append(ep["name"])
|
||||
elif isinstance(ep, str):
|
||||
current_endpoints.append(ep)
|
||||
|
||||
selected_endpoints = st.multiselect(
|
||||
f"Endpoints",
|
||||
options=available_endpoints,
|
||||
default=group["endpoints"],
|
||||
options=available_endpoint_names,
|
||||
default=current_endpoints,
|
||||
key=endpoints_key
|
||||
)
|
||||
|
||||
# Only update if endpoints have changed and they're different from previous value
|
||||
if selected_endpoints != group["endpoints"] and selected_endpoints != st.session_state[f"prev_{endpoints_key}"]:
|
||||
endpoints_changed = selected_endpoints != current_endpoints
|
||||
endpoints_diff_from_prev = selected_endpoints != st.session_state[f"prev_{endpoints_key}"]
|
||||
|
||||
if endpoints_changed and endpoints_diff_from_prev:
|
||||
updated_group = group.copy()
|
||||
updated_group["endpoints"] = selected_endpoints
|
||||
update_group(group["id"], updated_group)
|
||||
# Update the session state with the latest groups
|
||||
st.session_state.endpoint_groups = get_groups()
|
||||
# Update the previous value before rerunning
|
||||
st.session_state[f"prev_{endpoints_key}"] = selected_endpoints
|
||||
st.session_state.endpoint_groups = get_groups()
|
||||
st.rerun()
|
||||
|
||||
# Add language selection
|
||||
available_languages = st.session_state.available_languages
|
||||
except requests.exceptions.RequestException as e:
|
||||
st.error(f"Failed to load endpoints: {str(e)}")
|
||||
|
||||
# Language selection for the group
|
||||
try:
|
||||
# Use a unique key for the languages multiselect
|
||||
languages_key = f"languages_select_{i}"
|
||||
|
||||
@@ -215,74 +281,40 @@ with st.sidebar:
|
||||
if f"prev_{languages_key}" not in st.session_state:
|
||||
st.session_state[f"prev_{languages_key}"] = group.get("languages", [])
|
||||
|
||||
# Extract language codes from group.languages if they are dictionaries
|
||||
current_languages = []
|
||||
for lang in group.get("languages", []):
|
||||
if isinstance(lang, dict) and "code" in lang:
|
||||
current_languages.append(lang["code"])
|
||||
elif isinstance(lang, str):
|
||||
current_languages.append(lang)
|
||||
|
||||
selected_languages = st.multiselect(
|
||||
f"Languages",
|
||||
options=available_languages,
|
||||
default=group.get("languages", []),
|
||||
options=st.session_state.available_languages,
|
||||
default=current_languages,
|
||||
key=languages_key
|
||||
)
|
||||
|
||||
# Only update if languages have changed and they're different from previous value
|
||||
if selected_languages != group.get("languages", []) and selected_languages != st.session_state[f"prev_{languages_key}"]:
|
||||
languages_changed = selected_languages != current_languages
|
||||
languages_diff_from_prev = selected_languages != st.session_state[f"prev_{languages_key}"]
|
||||
|
||||
if languages_changed and languages_diff_from_prev:
|
||||
updated_group = group.copy()
|
||||
updated_group["languages"] = selected_languages
|
||||
update_group(group["id"], updated_group)
|
||||
# Update the session state with the latest groups
|
||||
st.session_state.endpoint_groups = get_groups()
|
||||
# Update the previous value before rerunning
|
||||
st.session_state[f"prev_{languages_key}"] = selected_languages
|
||||
st.session_state.endpoint_groups = get_groups()
|
||||
st.rerun()
|
||||
except requests.exceptions.RequestException as e:
|
||||
st.error(f"Failed to get available endpoints: {str(e)}")
|
||||
|
||||
with cols[1]:
|
||||
if st.button("Delete", key=f"delete_group_{i}"):
|
||||
try:
|
||||
# This is assumed to exist in the API client module
|
||||
from api_client.client import delete_group
|
||||
delete_group(group["id"])
|
||||
# Update the session state with the latest groups
|
||||
st.session_state.endpoint_groups = get_groups()
|
||||
st.rerun()
|
||||
except requests.exceptions.RequestException as e:
|
||||
st.error(f"Failed to delete group: {str(e)}")
|
||||
|
||||
# Add new group
|
||||
st.subheader("Add New Group")
|
||||
with st.form("add_group_form"):
|
||||
new_group_name = st.text_input("New Group Name")
|
||||
|
||||
try:
|
||||
available_endpoints = get_available_endpoints()
|
||||
new_group_endpoints = st.multiselect("Endpoints", options=available_endpoints)
|
||||
except Exception as e:
|
||||
st.error(f"Failed to load languages: {str(e)}")
|
||||
|
||||
# Add language selection for new group
|
||||
available_languages = st.session_state.available_languages
|
||||
new_group_languages = st.multiselect(
|
||||
"Languages",
|
||||
options=available_languages
|
||||
)
|
||||
except requests.exceptions.RequestException as e:
|
||||
st.error(f"Failed to get available endpoints: {str(e)}")
|
||||
new_group_endpoints = []
|
||||
new_group_languages = []
|
||||
|
||||
if st.form_submit_button("Add Group"):
|
||||
if new_group_name:
|
||||
try:
|
||||
from api_client.client import create_group
|
||||
new_group = {
|
||||
"name": new_group_name,
|
||||
"endpoints": new_group_endpoints,
|
||||
"languages": new_group_languages
|
||||
}
|
||||
create_group(new_group)
|
||||
# Update the session state with the latest groups
|
||||
st.session_state.endpoint_groups = get_groups()
|
||||
st.rerun()
|
||||
except requests.exceptions.RequestException as e:
|
||||
st.error(f"Failed to create group: {str(e)}")
|
||||
else:
|
||||
st.error("Group name cannot be empty")
|
||||
|
||||
# Show the announcement status
|
||||
show_announcement_status()
|
||||
# Separator for visual clarity
|
||||
st.markdown("---")
|
||||
|
||||
# Show status of any ongoing announcements
|
||||
if st.session_state.show_success_message and st.session_state.selected_group_id is not None:
|
||||
show_announcement_status(st.session_state.selected_group_id)
|
||||
|
||||
Reference in New Issue
Block a user