From 8453f78e31179bd1085deb6a04076fab9cf86fc2 Mon Sep 17 00:00:00 2001 From: lmiranda Date: Sun, 11 Jan 2026 14:09:28 -0500 Subject: [PATCH] feat: add app foundation (config.py, app.py, home page) - config.py: Pydantic BaseSettings for env loading - app.py: Dash factory with Pages routing - pages/home.py: Placeholder landing page Closes #7 Co-Authored-By: Claude Opus 4.5 --- portfolio_app/app.py | 37 +++++++++++++++++++++++++++++++++++++ portfolio_app/config.py | 34 ++++++++++++++++++++++++++++++++++ portfolio_app/pages/home.py | 14 ++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 portfolio_app/app.py create mode 100644 portfolio_app/config.py create mode 100644 portfolio_app/pages/home.py diff --git a/portfolio_app/app.py b/portfolio_app/app.py new file mode 100644 index 0000000..47bd0db --- /dev/null +++ b/portfolio_app/app.py @@ -0,0 +1,37 @@ +"""Dash application factory with Pages routing.""" + +import dash +from dash import html + +from .config import get_settings + + +def create_app() -> dash.Dash: + """Create and configure the Dash application.""" + settings = get_settings() + + app = dash.Dash( + __name__, + use_pages=True, + suppress_callback_exceptions=True, + title="Analytics Portfolio", + ) + + app.layout = html.Div( + [ + dash.page_container, + ] + ) + + return app + + +def main() -> None: + """Run the development server.""" + settings = get_settings() + app = create_app() + app.run(debug=settings.dash_debug, host="0.0.0.0", port=8050) + + +if __name__ == "__main__": + main() diff --git a/portfolio_app/config.py b/portfolio_app/config.py new file mode 100644 index 0000000..026361b --- /dev/null +++ b/portfolio_app/config.py @@ -0,0 +1,34 @@ +"""Application configuration using Pydantic BaseSettings.""" + +from functools import lru_cache + +from pydantic_settings import BaseSettings, SettingsConfigDict + + +class Settings(BaseSettings): + """Application settings loaded from environment variables.""" + + model_config = SettingsConfigDict( + env_file=".env", + env_file_encoding="utf-8", + extra="ignore", + ) + + # Database + database_url: str = "postgresql://portfolio:portfolio_dev@localhost:5432/portfolio" + postgres_user: str = "portfolio" + postgres_password: str = "portfolio_dev" + postgres_db: str = "portfolio" + + # Application + dash_debug: bool = True + secret_key: str = "change-me-in-production" + + # Logging + log_level: str = "INFO" + + +@lru_cache +def get_settings() -> Settings: + """Get cached settings instance.""" + return Settings() diff --git a/portfolio_app/pages/home.py b/portfolio_app/pages/home.py new file mode 100644 index 0000000..d49cbc2 --- /dev/null +++ b/portfolio_app/pages/home.py @@ -0,0 +1,14 @@ +"""Bio landing page.""" + +import dash +from dash import html + +dash.register_page(__name__, path="/", name="Home") + +layout = html.Div( + [ + html.H1("Analytics Portfolio"), + html.P("Welcome to Leo's analytics portfolio."), + html.P("Dashboard coming soon."), + ] +)