How-to Guides

Task-oriented recipes for maintaining the app. If you want to understand why things are built this way, see Explanation instead. For the test suite specifically, see Run the Tests.

Regenerate the workout data

src/daily_dose/data/workouts.json and src/daily_dose/www/images/ are generated by scripts/build_workouts_data.py. Re-run it after editing the legacy Rmd source (kept at scripts/_rmd_src/) or the workout photos.

The original photos aren’t kept in this repo. They’re 325MB of raw phone photos, compressed down to ~21MB in www/. To regenerate from scratch:

  1. Install the script’s one extra dependency (already in the dev extra): Pillow.

  2. Restore the original photos from the rmarkdown-archive branch, which still has them:

    git archive rmarkdown-archive -- images | tar -x
  3. Run the build script:

    python3 scripts/build_workouts_data.py

    It parses all five Rmd files, matches dated photos in images/, prefers the typed entry on any date that has both, and writes the deduplicated result to workouts.json. Every photo it keeps is re-encoded as a downsized JPEG (~1600px max dimension, quality 82) into src/daily_dose/www/images/.

    If a date heading in the Rmd source is malformed in a way the parser can’t safely handle (wrong heading level, trailing text after the date, …), the script raises ValueError naming the file and line instead of silently merging it into the previous entry. See Design Notes for why.

  4. Remove the restored source photos, which aren’t meant to be committed:

    rm -rf images/
  5. Confirm the data is sane:

    uv run pytest tests/test_data.py

Update the tutorial screenshots

The screenshots in Tutorials are checked-in PNGs, not generated at build time, so a UI change won’t update them on its own. To refresh them:

  1. Launch the app: shiny run daily_dose.app:app
  2. Install a headless browser once: pip install playwright && playwright install chromium
  3. Drive the running app with Playwright, screenshotting each state: initial load, after clicking Random Workout, and after clicking On This Day. Run Random Workout a few times to catch both a text and a photo entry.
  4. Save the results into tutorials/assets/, overwriting the existing files by name.

Deploy to Posit Connect Cloud

Connect Cloud deploys straight from a public GitHub repo, but it has two fixed expectations that don’t match this project’s layout: the app object must be importable from an app.py at the repo root, and dependencies come from a requirements.txt, not pyproject.toml. Both files already exist here for exactly that reason, and you shouldn’t need to touch either:

  • requirements.txt (repo root) holds a plain shiny[theme]>=1.0.0, mirroring pyproject.toml’s [project.dependencies] by hand. It has to be a real dependency list: Connect Cloud’s resolver doesn’t run pip install -e ., so an editable-install line here just fails outright (Error determining requirements: / does not appear to be a Python project) instead of installing anything, daily_dose included.
  • app.py (repo root) is a shim. Since daily_dose is never actually installed on Connect Cloud, it puts src/ on sys.path before importing from daily_dose.app import app. Local development still uses daily_dose.app:app directly (see the Tutorials launch command); this file exists only for Connect Cloud’s sake.

To deploy:

  1. Make sure the repo is public and the latest commit is pushed to main. Connect Cloud deploys from GitHub, not a local push.
  2. Sign in to Connect Cloud and click Publish.
  3. Choose Shiny as the app type and select this repository.
  4. Confirm the branch (main) and the primary file: app.py at the repo root, the shim, not src/daily_dose/app.py.
  5. Click Publish.

To publish an update later, push to main and use the republish action in Connect Cloud’s content list. It re-clones the repo and reinstalls from requirements.txt, so there’s no separate build step on your end.

Rebuild the docs site

One command from the repo root rebuilds the whole site:

great-docs build

That’s the homepage from README.md, this guide, Explanation, and the API Reference from daily_dose.core’s docstrings, all written into great-docs/_site/.