diff --git a/app/__pycache__/__init__.cpython-313.pyc b/app/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 00000000..496745f9 Binary files /dev/null and b/app/__pycache__/__init__.cpython-313.pyc differ diff --git a/app/__pycache__/__init__.cpython-314.pyc b/app/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 00000000..6b482af8 Binary files /dev/null and b/app/__pycache__/__init__.cpython-314.pyc differ diff --git a/app/__pycache__/data_loader.cpython-313.pyc b/app/__pycache__/data_loader.cpython-313.pyc new file mode 100644 index 00000000..3b8af88a Binary files /dev/null and b/app/__pycache__/data_loader.cpython-313.pyc differ diff --git a/app/__pycache__/data_loader.cpython-314.pyc b/app/__pycache__/data_loader.cpython-314.pyc new file mode 100644 index 00000000..5d2c163e Binary files /dev/null and b/app/__pycache__/data_loader.cpython-314.pyc differ diff --git a/app/__pycache__/data_processor.cpython-313.pyc b/app/__pycache__/data_processor.cpython-313.pyc new file mode 100644 index 00000000..cd8c337e Binary files /dev/null and b/app/__pycache__/data_processor.cpython-313.pyc differ diff --git a/app/__pycache__/data_processor.cpython-314.pyc b/app/__pycache__/data_processor.cpython-314.pyc new file mode 100644 index 00000000..d717e4dd Binary files /dev/null and b/app/__pycache__/data_processor.cpython-314.pyc differ diff --git a/app/__pycache__/visualizer.cpython-313.pyc b/app/__pycache__/visualizer.cpython-313.pyc new file mode 100644 index 00000000..10a380eb Binary files /dev/null and b/app/__pycache__/visualizer.cpython-313.pyc differ diff --git a/app/__pycache__/visualizer.cpython-314.pyc b/app/__pycache__/visualizer.cpython-314.pyc new file mode 100644 index 00000000..588729e0 Binary files /dev/null and b/app/__pycache__/visualizer.cpython-314.pyc differ diff --git a/app/data_loader.py b/app/data_loader.py index 1052e9d1..d92f11dc 100644 --- a/app/data_loader.py +++ b/app/data_loader.py @@ -4,9 +4,10 @@ from dotenv import load_dotenv import os -load_dotenv() +load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), "..", ".env")) -BASE_URL = os.getenv("BASE_API_URL") +BASE_API_URL = os.getenv("BASE_API_URL") +print(BASE_API_URL) def fetch_data(endpoint, params=None): @@ -29,11 +30,18 @@ def fetch_data(endpoint, params=None): if params is None: params = {} - url = f"{BASE_URL}{endpoint}" + url = f"{BASE_API_URL}{endpoint}" full_url = requests.Request('GET', url, params=params).prepare().url - response = requests.get(full_url) - response.raise_for_status() - return pd.DataFrame(response.json()) + try: + response = requests.get(full_url) + + if response.status_code == 404: + return pd.DataFrame() + response.raise_for_status() + return pd.DataFrame(response.json()) + except requests.exceptions.RequestException as e: + print("API Error:", e) + return pd.DataFrame() # Cached API calls using Streamlit's cache_data decorator diff --git a/main.py b/main.py index adaccab4..f886c74d 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ import streamlit as st +import datetime from app.data_loader import ( fetch_data, fetch_sessions, @@ -28,15 +29,19 @@ with col1: # Step 1: Select Year and Country dynamically - available_years = [2023, 2024, 2025] + available_years = [2023, 2024, 2025, 2026] selected_year = st.selectbox("Select Year", available_years, index=len(available_years) - 1) # Fetch all meetings for selected year all_meetings = fetch_data("meetings", {"year": selected_year}) + current_year = datetime.datetime.now().year if all_meetings.empty: - st.error("No meetings found for this year.") - st.stop() + if selected_year >= current_year: + st.warning("No race data yet. Showing upcoming schedule if available.") + else: + st.error("No meetings found for this year.") + st.stop() available_countries = sorted(all_meetings["country_name"].dropna().unique()) selected_country = st.selectbox("Select Country", available_countries) @@ -46,12 +51,21 @@ filtered_meetings["label"] = filtered_meetings["meeting_name"] + " - " + filtered_meetings["location"] filtered_meetings = filtered_meetings.sort_values(by="meeting_key", ascending=False) + if filtered_meetings.empty: + st.warning("🚧 No Grand Prix available yet for this selection.") + st.stop() + with col2: selected_meeting = st.selectbox("Select Grand Prix", filtered_meetings["label"], disabled=True) selected_meeting_key = filtered_meetings.loc[ filtered_meetings["label"] == selected_meeting, "meeting_key" ].values[0] sessions = fetch_sessions(selected_meeting_key) + + if sessions.empty: + st.info("📅 Session schedule not available yet.") + st.stop() + selected_session = st.selectbox("Select Session", sessions["label"]) sessions["session_type"] = sessions["label"].str.extract(r"^(.*?)\s\(") selected_session_type = sessions.loc[sessions["label"] == selected_session, "session_type"].values[0] @@ -72,8 +86,16 @@ with st.expander(f"📈 Lap Time Chart for {selected_session_type} at {selected_country} {selected_year}", expanded=True): lap_df = fetch_laps(selected_session_key) + + if lap_df.empty: + st.info("🚧 This session hasn't happened yet. Showing schedule only.") + st.stop() + processed_df = process_lap_data(lap_df) + if processed_df.empty: + st.info("🚧 This session hasn’t happened yet. Data will appear after completion.") + # Merge name_acronym into the lap data processed_df["driver_number"] = processed_df["driver_number"].astype(str) processed_df = processed_df.merge(driver_info, on="driver_number", how="left")