"""Streamlit entry point for the sync_pilot dashboard. Launch with:: python -m sync_pilot dashboard [--port 8501] Navigation uses Streamlit's modern ``st.navigation`` / ``st.Page`` API so the sidebar shows a single tabbed page list at the top, then our branding and data-source caption below it. The pages themselves live in ``sync_pilot/dashboard/views/`` (deliberately *not* ``pages/`` — Streamlit's file-based auto-discovery only triggers on the literal name ``pages`` and we don't want a second nav showing up). """ from __future__ import annotations import streamlit as st from sync_pilot.dashboard.styles import apply_global_styles from sync_pilot.dashboard.views import gt_review, overview, taxonomy, tracks def main() -> None: st.set_page_config( page_title="sync_pilot — Median Müzik", page_icon="♪", layout="wide", initial_sidebar_state="expanded", ) apply_global_styles() # Each ``st.Page`` needs an explicit ``url_path`` because the three view # modules all expose a callable named ``render``. Without explicit paths, # Streamlit infers the URL pathname from the callable name and three # pages collide on "/render". nav = st.navigation( [ st.Page( overview.render, title="Overview", icon=":material/dashboard:", url_path="overview", default=True, ), st.Page( taxonomy.render, title="Taxonomy", icon=":material/category:", url_path="taxonomy", ), st.Page( tracks.render, title="Track explorer", icon=":material/library_music:", url_path="tracks", ), st.Page( gt_review.render, title="GT review", icon=":material/fact_check:", url_path="gt-review", ), ], position="sidebar", ) nav.run() # Streamlit executes this file top-to-bottom as a script every rerun, so we # call ``main()`` at import/execute time rather than guarding under # ``__name__ == '__main__'`` (which would never fire for a streamlit-run # script). main()