CoolFace
Apppublic

alexchilton/bern_whatson_aggregator

sourceHugging Faceupdated 6mo agoView on Hugging Face
0likes
App README

Bern What's On Aggregator

A full-stack event aggregator for the city of Bern — scrapes, normalises and surfaces local events through a searchable web interface.


Quick Start — Docker

The fastest way to run the full stack:

bash
docker compose up

Open http://localhost:8000 once the container is healthy.

To seed 20 realistic fake Bern events at startup (useful for local exploration):

bash
DEV_SEED_EVENTS=true docker compose up

Data (SQLite database + ChromaDB vectors) is persisted in a named Docker volume (app_data) across restarts.


Quick Start — Local Dev

Backend

bash
# 1. Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate

# 2. Install the package and dev dependencies
pip install -e ".[dev]"
pip install torch --index-url https://download.pytorch.org/whl/cpu

# 3. Copy and adjust environment variables
cp .env.example .env

# 4. Run database migrations
alembic upgrade head

# 5. Start the API server
uvicorn backend.main:create_app --factory --reload

The API is available at http://localhost:8000.

Frontend

bash
cd frontend
npm ci
npm run dev

The dev server starts at http://localhost:5173 and proxies /api requests to the backend.


Development

Run backend tests

bash
pytest tests/backend/ -q

Lint and type-check

bash
ruff check backend/
mypy backend/

Frontend dev server with hot reload

bash
cd frontend && npm run dev

Frontend tests

bash
cd frontend && npm test

Frontend production build

bash
cd frontend && npm run build

API Reference

MethodPathDescription
GET/api/healthHealth check — returns {"status": "ok"}
GET/api/eventsPaginated event list; supports q, category, date_from, date_to query params
GET/api/events/{event_id}Single event detail by UUID

Example — list upcoming music events

GET /api/events?category=music&date_from=2024-06-01&date_to=2024-06-30

Architecture

bern_whatson_aggregator/
├── backend/
│   ├── adapters/          # Format converters (JSON-LD, RSS/iCal)
│   ├── api/               # FastAPI route handlers
│   │   ├── events.py      # GET /api/events, GET /api/events/{id}
│   │   └── health.py      # GET /api/health
│   ├── models/            # SQLAlchemy ORM models
│   ├── schemas/           # Pydantic request/response schemas
│   ├── scrapers/          # Source-specific scraper modules + scheduler
│   ├── search/            # Hybrid search (SQL + ChromaDB vector)
│   ├── config.py          # Settings loaded from environment
│   ├── database.py        # SQLAlchemy engine & session factory
│   ├── dependencies.py    # FastAPI dependency injection helpers
│   └── main.py            # Application factory (create_app)
├── frontend/
│   ├── src/
│   │   ├── api/           # Typed API client
│   │   ├── components/    # Reusable UI components
│   │   ├── hooks/         # Custom React hooks
│   │   ├── i18n/          # Internationalisation strings
│   │   ├── pages/         # Route-level page components
│   │   └── types/         # Shared TypeScript types
│   ├── package.json
│   └── vite.config.ts
├── alembic/               # Database migrations
├── tests/
│   └── backend/           # pytest test suite
├── Dockerfile             # Multi-stage build (Node SPA + Python runtime)
├── docker-compose.yml     # Local dev / single-host deployment
├── .env.example           # Environment variable template
└── pyproject.toml         # Python project metadata and tool config

Environment Variables

VariableDefaultDescription
DATABASE_URLsqlite:///./data/dev.dbSQLAlchemy database URL
CHROMA_PATH./data/chromaDirectory for ChromaDB persistence
SEARCH_K200Number of candidates retrieved per vector search
DEV_SEED_EVENTSfalseSeed fake events at startup (dev only)
EVENTBRITE_API_KEY—Eventbrite scraper (optional)
MYSWITZERLAND_API_KEY—MySwitzerland scraper (optional)