-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathvisualize.py
More file actions
151 lines (125 loc) · 5.14 KB
/
visualize.py
File metadata and controls
151 lines (125 loc) · 5.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
"""Autobiographer dashboard entrypoint.
Configures the page, renders the shared sidebar, and runs the multi-page
navigation. All chart logic lives in the ``pages/`` modules; shared data
loading lives in ``components/sidebar``.
Run with::
streamlit run visualize.py
"""
from __future__ import annotations
from functools import partial
import streamlit as st
from dotenv import load_dotenv
import components.theme # registers autobio_dark Plotly template as default # noqa: F401
from components.sidebar import render_sidebar
from pages.beer import render_beer
from pages.culture import render_culture
from pages.data_sources import render_data_sources, render_plugin_page
from pages.fitness import render_fitness
from pages.insights import render_insights, render_insights_and_narrative # noqa: F401
from pages.music import render_music, render_top_charts # noqa: F401
from pages.overview import render_overview # noqa: F401
from pages.places import ( # noqa: F401
render_checkin_insights,
render_places,
render_spatial_analysis,
)
from plugins.sources import REGISTRY, load_builtin_plugins
load_dotenv()
_GLOBAL_CSS = """
<style>
/* ── Chrome — hide unwanted UI without touching the sidebar toggle ─────────
Do NOT hide stHeader or stToolbar: they contain the collapsed-sidebar
expand button, and hiding them traps users with no way to reopen it. */
#MainMenu {visibility: hidden;}
footer {visibility: hidden;}
[data-testid="stDecoration"] {display: none;}
[data-testid="stStatusWidget"] {visibility: hidden;}
/* ── Layout ───────────────────────────────────────────────────────────────*/
.block-container {
padding-top: 1.5rem;
padding-bottom: 1rem;
}
/* ── Card containers ──────────────────────────────────────────────────────
Targets bordered st.container() blocks and the overview hero card. */
[data-testid="stVerticalBlockBorderWrapper"] {
background-color: #141c2f !important;
border-radius: 12px !important;
border: 1px solid #2d3a52 !important;
box-shadow: 0 4px 24px rgba(0,0,0,0.4);
}
.autobio-hero-card {
background: linear-gradient(135deg, #1e1b4b, #0c1120);
border: 1px solid #6366f1;
border-radius: 12px;
padding: 2rem 2.5rem;
margin-bottom: 1.5rem;
}
/* ── Section headers (sidebar nav group labels) ───────────────────────────*/
.autobio-section-header {
font-size: 0.75rem;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
opacity: 0.55;
margin: 0.5rem 0 0.15rem 0;
padding-left: 0.5rem;
line-height: 1.5;
}
</style>
"""
@st.cache_resource
def _load_plugins_once() -> None:
"""Load built-in plugins into REGISTRY exactly once per server process."""
load_builtin_plugins()
@st.cache_resource
def _build_plugin_nav_pages() -> list[st.Page]:
"""Build the Sources nav pages once; reused on every subsequent rerun."""
pages: list[st.Page] = [
st.Page(render_data_sources, title="Data Sources", icon=":material/database:"),
]
for plugin_id, plugin_cls in REGISTRY.items():
plugin = plugin_cls()
pages.append(
st.Page(
partial(render_plugin_page, plugin_id),
title=plugin.DISPLAY_NAME,
icon=plugin.ICON,
url_path=plugin_id,
)
)
return pages
def main() -> None:
"""Configure and launch the Autobiographer multi-page dashboard."""
st.set_page_config(page_title="Autobiographer", layout="wide")
st.markdown(_GLOBAL_CSS, unsafe_allow_html=True)
# Populate REGISTRY before building nav so plugin pages can be listed.
_load_plugins_once()
sources_pages = _build_plugin_nav_pages()
pg = st.navigation(
{
"Overview": [
st.Page(render_overview, title="Overview", icon=":material/dashboard:"),
],
"Music": [
st.Page(render_music, title="Listening", icon=":material/headphones:"),
st.Page(render_insights, title="Insights", icon=":material/auto_stories:"),
],
"Places": [
st.Page(render_places, title="Check-ins", icon=":material/location_on:"),
st.Page(render_checkin_insights, title="Insights", icon=":material/insights:"),
],
"Health": [
st.Page(render_fitness, title="Fitness", icon=":material/fitness_center:"),
],
"Culture": [
st.Page(render_culture, title="Films & Books", icon=":material/local_library:"),
st.Page(render_beer, title="Beer", icon=":material/sports_bar:"),
],
"Sources": sources_pages,
}
)
# render_sidebar after st.navigation so it appears below the nav list.
render_sidebar()
pg.run()
if __name__ == "__main__":
main()