Coffee Journal
Coffee tasting journal API: roast labels and tasting summaries as computed columns
One app.py with 1 table, 3 computed columns, 4 HTTP routes. Needs pixeltable[serve]>=0.7.14. Updated 2026-09-25.
app.py
"""Coffee Journal API built with Pixeltable.pxt schema update app.py coffeepxt service run app.py coffee"""import pixeltable as pxtimport pixeltable.functions as pxtffrom pixeltable.serving import FastAPIRouterfrom udfs import brew_blurb, roast_label# ---- tables ----TableModel = pxt.model_base()class Cups(TableModel, name='cups'):id = pxt.Column(value=pxtf.uuid.uuid7(), primary_key=True)bean: pxt.Stringorigin: pxt.Stringroast_level: pxt.String | Nonerating: pxt.Int | Nonenotes: pxt.String | Noneroast = roast_label(roast_level)bean_upper = pxtf.string.upper(bean)notes_blurb = brew_blurb(notes)# ---- queries ----@pxt.querydef top_cups(origin: str, min_rating: int):"""Best cups from one origin."""return Cups.where((Cups.origin == origin) & (Cups.rating >= min_rating)).select(Cups.id, Cups.bean, Cups.roast, Cups.rating, Cups.notes_blurb).order_by(Cups.rating, asc=False)# ---- routes ----cups_api = FastAPIRouter(name='cups_api')cups_api.add_insert_route(Cups, path='/cups',inputs=[Cups.bean, Cups.origin, Cups.roast_level, Cups.rating, Cups.notes],outputs=[Cups.id, Cups.roast, Cups.bean_upper, Cups.notes_blurb],)cups_api.add_update_route(Cups, path='/cups/update', inputs=[Cups.roast_level, Cups.rating],outputs=[Cups.id, Cups.roast, Cups.rating])cups_api.add_compute_route(Cups, path='/roast-label', inputs=[Cups.roast_level], outputs=[Cups.roast])cups_api.add_query_route(path='/cups/top', query=top_cups, method='get')
What app.py declares
Each row links to its line.
- runs on insert
- stored
- index
- route
serves cups_api
- POST/cupsinsert, cupstakes bean, origin, roast_level, rating, notes; returns id, roast, bean_upper, notes_blurbL40
- POST/cups/updateupdate, cupstakes roast_level, rating; returns id, roast, ratingL45
- POST/roast-labelcompute, cupstakes roast_level; returns roastL47
- GET/cups/topquery, top_cupstakes origin, min_ratingL48
Run it
Needs uv. The routes then answer on port 8000.
terminal
git clone https://github.com/pierrebrunelle/pixeltable-coffee-journalcd pixeltable-coffee-journaluv syncuv run pxt schema update app.py coffeeuv run python seed.py coffeeuv run pxt service run app.py coffee --port 8000
Related apps
- Forge Heat CyclesForge heat-cycle registry API: B-tree indexes, chained risk UDFs, and parallel shop-floor writersShares: UDFs
- Climbing Route ToposClimbing-route topo registry API: photo uploads with thumbnails, grayscale copies, grade bands and index-backed crag lookupsShares: UDFs
- Warehouse Pick ListsWarehouse pick-list REST API: units, pick zones, waves and tote labels as incremental computed columns over Json order linesShares: UDFs