Update doc

This commit is contained in:
2026-09-10 13:12:35 +02:00
parent d5e5b78334
commit e15f00e98c
4 changed files with 135 additions and 60 deletions
+16
View File
@@ -0,0 +1,16 @@
# Copy to .env and fill in. .env is gitignored.
# The Makefile does `include .env`, so this file must exist before `make run`.
# --- Local dev (make run) ---
# btcdata instance the server proxies WebSockets to. The code falls back to
# http://localhost:4100 when unset, but the Makefile needs the file to exist.
BTCDATA_URL=http://localhost:4100
# Used by `make run-local` to point at a btcdata on this machine while
# BTCDATA_URL above points elsewhere (e.g. a deployed instance).
BTCDATA_LOCAL_URL=http://localhost:4100
# --- Docker (docker compose up -d) ---
# Port btcdata listens on inside btc-network. Must match DOCKER_BTCDATA_PORT
# in ../btcdata/.env.
DOCKER_BTCDATA_PORT=4102
+35 -20
View File
@@ -1,39 +1,54 @@
# CLAUDE.md # CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. Bitcoin price tracker UI — Python FastAPI web application. Serves the HTML/Tailwind UI and
proxies live price data from btcdata over WebSocket.
## Overview
Bitcoin price tracker UI — Python FastAPI web application. Serves an HTML/Tailwind page with live price updates streamed from btcdata (separate service) via WebSocket using HTMX.
## Build & Development Commands ## Build & Development Commands
- `make run` — Start dev server on port 4000 (connects to btcdata at BTCDATA_URL from `.env`) - `make run` — Start dev server on port 4000; creates `.venv` and installs `requirements.txt`
- `make run-local` — Start dev server using BTCDATA_LOCAL_URL from `.env` on first run (the `venv` target, keyed off `requirements.txt`)
- `make tailwind` — Watch Tailwind CSS for changes (run in separate terminal) - `cp .env.example .env` — optional; `.env` is `-include`d, so a missing one is not fatal
- `make test` — Run tests with pytest (`tests/` directory) - `make run-local` — Same, but with `BTCDATA_URL=$BTCDATA_LOCAL_URL`
- `npm run css:build` — One-off Tailwind CSS build - `make tailwind` — Watch Tailwind CSS for changes
- `make test` — Runs `pytest tests/`, but there is no `tests/` directory yet and pytest is not
in `requirements.txt`
- `make venv` — Bootstrap the virtualenv without starting the server
## Docker ## Docker
Docker runs alongside local dev on different ports: Docker runs alongside local dev on different ports:
| Service | Local dev | Docker | | Service | Local dev | Docker |
|----------|----------------|----------------| |----------|----------------|--------------------------------------|
| btcprice | localhost:4000 | localhost:4041 | | btcprice | localhost:4000 | localhost:4041 (container port 4040) |
| btcdata | localhost:4100 | localhost:4101 | | btcdata | localhost:4100 | localhost:4102 |
Uses external `btc-network` Docker network. btcdata must be running separately (or via its own docker-compose). `docker compose up -d` here starts **btcprice only**. Both projects attach to the external
`btc-network` (`docker network create btc-network` once), and btcdata must be started from
`../btcdata`. Inside the network btcprice reaches it at `http://btcdata:${DOCKER_BTCDATA_PORT:-4102}`.
Note: `Dockerfile` bakes in a stale `ENV BTCDATA_URL=http://btcdata:4101`; compose always
overrides it, so it only matters if the image is run outside compose. `ENV PORT` is likewise
unused — the port in `CMD` is hardcoded.
## Architecture ## Architecture
- **Framework:** FastAPI + Uvicorn - **Framework:** FastAPI
- **Templates:** Inline HTML strings in Python + HTMX (WebSocket extension) - **Server:** Uvicorn
- **Styling:** Tailwind CSS v4 — scans `app/**/*.py` for class names (configured in `resources/css/input.css` via `@source`) - **Templates:** Inline HTML strings + HTMX (WebSocket extension)
- **Data backend:** btcdata (separate service at BTCDATA_URL, default http://localhost:4100) - **Styling:** Tailwind CSS v4
- **Data backend:** btcdata (separate service at `BTCDATA_URL`, default `http://localhost:4100`)
- **No database** — all data comes from btcdata - **No database** — all data comes from btcdata
### Data Flow ### btcdata connection
The browser connects only to btcprice: `ws-connect="/ws/price"` and `ws-connect="/ws/strike"`.
Each endpoint runs `_ws_proxy`, which opens an upstream WebSocket to btcdata's `/api/price/ws`
and `/api/strike/ws`, converts each JSON message to an HTML fragment (`price_json_to_html`,
`strike_json_to_html`) and forwards it. `BTCDATA_URL` is the single point of contact;
`_btcdata_ws_url` rewrites its scheme to `ws`/`wss`.
## Source Layout
btcprice acts as a WebSocket proxy between the browser and btcdata: btcprice acts as a WebSocket proxy between the browser and btcdata:
1. Browser connects via HTMX WebSocket to `/ws/price` or `/ws/strike` 1. Browser connects via HTMX WebSocket to `/ws/price` or `/ws/strike`
+18 -8
View File
@@ -1,19 +1,29 @@
include .env -include .env
export export
.PHONY: clean run run-docker tailwind test VENV := .venv
UVICORN := $(VENV)/bin/uvicorn
.PHONY: clean run run-local tailwind test venv
venv: $(UVICORN)
$(UVICORN): requirements.txt
python3 -m venv $(VENV)
$(VENV)/bin/pip install --upgrade pip
$(VENV)/bin/pip install -r requirements.txt
clean: clean:
rm -rf __pycache__ app/__pycache__ rm -rf __pycache__ app/__pycache__
run: run: venv
.venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 4000 --reload $(UVICORN) app.main:app --host 0.0.0.0 --port 4000 --reload
run-local: run-local: venv
BTCDATA_URL=$(BTCDATA_LOCAL_URL) .venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 4000 --reload BTCDATA_URL=$(BTCDATA_LOCAL_URL) $(UVICORN) app.main:app --host 0.0.0.0 --port 4000 --reload
tailwind: tailwind:
npm run css:watch npm run css:watch
test: test: venv
.venv/bin/python -m pytest tests/ $(VENV)/bin/python -m pytest tests/
+66 -32
View File
@@ -1,32 +1,66 @@
# btcprice # btcprice
Bitcoin price tracker UI. Serves an HTML page with live price updates streamed from [btcdata](../btcdata) via WebSocket using HTMX. Bitcoin price tracker UI. Serves an HTML page with live price updates streamed from
[btcdata](../btcdata), which this server proxies over WebSocket and renders as HTML fragments
## Quick Start for HTMX.
```bash ## Quick Start
# Start btcdata first (provides price data)
cd ../btcdata && make run ```bash
# Start btcdata first (provides price data)
# Local dev cd ../btcdata && make run
make run # starts on port 4000
make tailwind # watch Tailwind CSS (separate terminal) # Local dev — creates .venv and installs requirements on first run
make run # starts on port 4000
# Docker (starts both btcprice + btcdata) make tailwind # watch Tailwind CSS (separate terminal)
docker compose up -d # btcprice on 4041, btcdata on 4101 ```
```
Optionally `cp .env.example .env` to override `BTCDATA_URL`; without it the code default
## Environment Variables (`http://localhost:4100`) applies. `make run-local` requires a `.env` defining
`BTCDATA_LOCAL_URL`.
| Variable | Default | Description |
|---|---|---| ## Docker
| `PORT` | `4000` | HTTP server port |
| `BTCDATA_URL` | `http://192.168.50.42:4100` | btcdata service URL (browser connects via WebSocket) | `docker compose up -d` starts **btcprice only** — it does not bring up btcdata. Both compose
files attach to the external `btc-network`, so create it once and start btcdata separately:
## How It Works
```bash
The server renders an HTML page with HTMX and the WebSocket extension (`hx-ext="ws"`). HTMX connects directly to btcdata's WebSocket endpoint (`BTCDATA_URL/api/price/ws`), which sends HTML fragments. HTMX swaps the received `<div id="price-display">` into the DOM automatically. Price changes are color-coded (green up, red down). Reconnection is handled by HTMX with exponential backoff. docker network create btc-network # once
cd ../btcdata && docker compose up -d
## Tech Stack cd ../btcprice && docker compose up -d
```
Clojure · Kit · Undertow · Reitit · Hiccup · HTMX · Tailwind CSS v4
| Service | Local dev | Docker |
|----------|----------------|---------------------------------------|
| btcprice | localhost:4000 | localhost:4041 (container port 4040) |
| btcdata | localhost:4100 | localhost:4102 |
Inside `btc-network`, btcprice reaches btcdata as `http://btcdata:4102`.
## Environment Variables
| Variable | Default | Description |
|---|---|---|
| `BTCDATA_URL` | `http://localhost:4100` | btcdata service URL the server proxies to |
| `BTCDATA_LOCAL_URL` | — | Used by `make run-local` instead of `BTCDATA_URL` |
| `DOCKER_BTCDATA_PORT` | `4102` | btcdata's port inside `btc-network` (compose only) |
The HTTP port is not configurable via environment: `make run` hardcodes 4000 and the Docker
image's `CMD` hardcodes 4040.
## How It Works
The browser loads a page with HTMX and the WebSocket extension, which connects back to
**btcprice** at `/ws/price` and `/ws/strike` — the browser never contacts btcdata directly.
Each of those endpoints opens an upstream WebSocket to btcdata (`/api/price/ws` and
`/api/strike/ws`), converts each JSON message to an HTML fragment (`price_json_to_html`,
`strike_json_to_html`), and forwards it to the browser. HTMX swaps the received
`<div id="price-display">` / `<div id="strike-display">` into the DOM. Price changes are
color-coded (green up, red down). Reconnection is handled by HTMX.
## Tech Stack
Python · FastAPI · Uvicorn · websockets · HTMX · Tailwind CSS v4
The Clojure implementation this replaced is on the `clojure` branch.