@@ -28,106 +28,88 @@ Starting with v0.5, Ceopardy is split in two parts:
2828
2929- A Python/Flask back-end that exposes a small REST API (` /api/v1/... ` ) and
3030 broadcasts state changes over a single Socket.IO namespace (` /game ` ).
31- - A Vite + Vue 3 front-end (in ` frontend/ ` ) that powers the crowd-facing
32- viewer, the host UI, and the start screen.
31+ - A Vite + Vue 3 + TypeScript front-end (in ` frontend/ ` ) that powers the
32+ crowd-facing viewer, the host UI, and the start screen.
3333
34+ Ceopardy is designed for single-operator local-network use: the server binds
35+ to ` 127.0.0.1 ` and there is no authentication on the host UI. If you need to
36+ expose it on a LAN, put your own reverse proxy (and auth) in front.
3437
35- ## First time deployment
3638
37- You need Python, pip, virtualenv and Node.js (LTS). The tl;dr:
39+ ## Running Ceopardy (operators)
3840
39- make venv
40- source .venv/bin/activate # bash/zsh
41- source .venv/bin/activate.fish # fish
42- make init # seed data/ and game-media/ from templates
43- npm install --prefix frontend
44- npm run build --prefix frontend
45- python run.py
41+ For people who just want to host a game.
4642
47- ` make venv ` creates ` .venv/ ` and installs both runtime and dev requirements.
48- ` make init ` is a one-time step that copies starter ` data/1st.round ` and
49- ` data/Questions.cp ` into the repo and creates ` game-media/ ` . Edit those files
50- to set up your game.
43+ Install [ pipx] ( https://pipx.pypa.io/ ) , then install the latest release wheel
44+ (requires ` curl ` and ` jq ` ):
5145
52- ### Optional: direnv
53-
54- If you use [ direnv] ( https://direnv.net/ ) , the repo ships an ` .envrc ` that puts
55- ` .venv/bin ` on your ` PATH ` automatically when you ` cd ` into the directory —
56- works in bash, zsh, and fish. Install direnv (see
57- [ upstream docs] ( https://direnv.net/docs/installation.html ) for shell hook setup),
58- then from the repo root:
59-
60- make venv # create the venv first; direnv won't do this for you
61- direnv allow # trust the .envrc
46+ pipx install "$(curl -fsSL https://api.github.com/repos/obilodeau/ceopardy/releases/latest | jq -r '.assets[] | select(.name | endswith(".whl")) | .browser_download_url')"
6247
63- After that, entering the directory activates the venv and leaving deactivates
64- it — no manual ` source ` needed.
48+ Or pin a specific version from the
49+ [ releases page ] ( https://github.com/obilodeau/ceopardy/releases ) :
6550
66- Then open [ the host view] ( http://127.0.0.1:5000/host ) to set up the game.
67- [ The players' view] ( http://127.0.0.1:5000/ ) (also known as the viewer) can be
68- opened at any time.
51+ pipx install https://github.com/obilodeau/ceopardy/releases/download/v0.6.0/ceopardy-0.6.0-py3-none-any.whl
6952
70- ` python run.py ` runs the built-in dev server (debug + reloader). For
71- production, run it under gunicorn with the eventlet worker. Socket.IO requires
72- a single worker process unless you also configure a Redis message queue:
53+ Then scaffold a per-game directory and start the server:
7354
74- pip install gunicorn
75- gunicorn -k eventlet -w 1 -b 127.0.0.1:5000 'run:app'
55+ mkdir my-game && cd my-game
56+ ceopardy init # writes data/ + game-media/ starter content
57+ # edit data/Questions.cp and data/1st.round to set up your game
58+ ceopardy serve # starts the server on http://127.0.0.1:5000/
59+ ceopardy serve --debug # add verbose logging + auto-reload
7660
77- Put nginx (or similar) in front for TLS and to expose it on the network — the
78- app itself binds to localhost because the host interface has no auth.
61+ Open the two URLs ` ceopardy serve ` prints:
7962
63+ - Viewer: < http://localhost:5000/ > — what the crowd sees on the projector.
64+ - Host: < http://localhost:5000/host > — what you (the operator) drive.
8065
81- ## Development
66+ ` ceopardy init ` never overwrites existing files; it's safe to re-run. The
67+ SQLite database, round files, and uploaded media all resolve relative to the
68+ directory you run ` ceopardy ` from, so ** keep one directory per game** .
8269
83- Run Flask and Vite side by side. Vite hot-reloads the UI and proxies
84- ` /api ` and ` /socket.io ` to Flask.
70+ > ** Note:** Ceopardy persists transactions to a SQLite database as the host
71+ > submits points, so a crash doesn't lose the game state. The flipside is
72+ > that games must be finalized (click "Game over") before a new one can be
73+ > started in the same directory.
8574
86- # terminal 1 - Flask
87- python run.py
8875
89- # terminal 2 - Vite dev server
90- npm run dev --prefix frontend
76+ ## Hacking on Ceopardy (developers)
9177
92- Then open http://localhost:5173/ .
78+ You need Python 3.11+, pip, virtualenv, and Node.js (LTS) .
9379
80+ git clone https://github.com/obilodeau/ceopardy.git
81+ cd ceopardy
82+ make venv # creates .venv/ + installs deps
83+ source .venv/bin/activate # bash/zsh
84+ source .venv/bin/activate.fish # fish
85+ make init # seeds data/ + game-media/
86+ make run # starts Flask (:5000) + Vite (:5173)
9487
95- ## Install as a CLI (pipx)
88+ Then open < http://localhost:5173/ > — Vite hot-reloads the UI and proxies
89+ ` /api ` and ` /socket.io ` to Flask on ` :5000 ` . ** In dev, always use the Vite
90+ URL** (` :5173 ` ); the Flask port serves the * built* SPA which gets stale.
9691
97- Ceopardy is distributed as a wheel attached to each
98- [ GitHub release] ( https://github.com/obilodeau/ceopardy/releases ) . Install the
99- latest one with pipx (requires ` curl ` and ` jq ` ):
92+ ### Optional: direnv
10093
101- pipx install "$(curl -fsSL https://api.github.com/repos/obilodeau/ceopardy/releases/latest | jq -r '.assets[] | select(.name | endswith(".whl")) | .browser_download_url')"
94+ If you use [ direnv] ( https://direnv.net/ ) , the repo ships an ` .envrc ` that
95+ auto-activates ` .venv ` on ` cd ` . Run ` make venv ` first (direnv won't), then
96+ ` direnv allow ` .
10297
103- Or pick a specific version by pointing pipx at a wheel URL from the
104- [ releases page] ( https://github.com/obilodeau/ceopardy/releases ) , e.g.:
98+ ### Before committing
10599
106- pipx install https://github.com/obilodeau/ceopardy/releases/download/v0.6.0/ceopardy-0.6.0-py3-none-any.whl
100+ Run the full CI suite — same checks GitHub Actions runs:
107101
108- Then scaffold a game directory and start the server:
102+ make ci # ruff lint + format check + prettier + vue-tsc + pytest
109103
110- mkdir my-game && cd my-game
111- ceopardy init # scaffolds data/ and game-media/ in CWD
112- # edit data/Questions.cp and data/1st.round
113- ceopardy # or `ceopardy serve` — starts the server
104+ To auto-fix Python formatting first:
114105
115- ` ceopardy init ` never overwrites existing files; it's safe to re-run. The
116- server, the SQLite database, and the question files all resolve relative to
117- the directory you run ` ceopardy ` from, so keep one directory per game.
106+ make format
118107
108+ See ` AGENTS.md ` for the conventions the codebase follows.
119109
120- ## Prepare a game
110+ ### Building a wheel locally
121111
122- Game data goes in ` data/ ` . There you should add round files (create a ` .round `
123- file) and questions in ` Questions.cp ` . The format is pretty self explanatory.
124- Run ` ceopardy init ` (or ` make init ` from the repo) to get a working starter
125- set; ` data/1st.round ` and ` data/Questions.cp ` are the minimal example.
126- User-supplied media referenced by questions (e.g. ` [img:photo.png] ` ) goes in
127- ` game-media/ ` next to ` data/ ` .
112+ ` make build ` reproduces the release path (frontend bundle + sdist + wheel):
128113
129- > ** Note:** In order to avoid dataloss due to a crash, Ceopardy is backed by a
130- > database where transactions are pushed when the hosts submit the points. This
131- > has the flipside requiring games to be finalized before a new one can be
132- > started. Make sure that you always push the "Game over" button before
133- > reloading to start a new game.
114+ make build
115+ pipx install --force dist/ceopardy-*.whl # test the wheel end-to-end
0 commit comments