Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions board_configs/desktop/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ Applications instantiate an application coordinator only when they need one. Laz
roles still come from `board_peripherals`.

This bundle installs:
- `board_config.py`
- `board_peripherals.py`
- [`board_config.py`](board_config.py)
- [`board_peripherals.py`](board_peripherals.py)
- `boarddev.py`
- `audiodev/` (package)
- `usdl2.py`
Expand Down
8 changes: 4 additions & 4 deletions lib/audiodev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@ bytes in 8 KB chunks.

[`pygame_audio.py`](pygame_audio.py) and [`web_audio.py`](web_audio.py) cannot run on MicroPython or CircuitPython at
all (they need pygame-ce and Pyodide's `js` module), so a CPython-only idiom is
not a bug there. `pygame_audio.py` still uses the portable forms, because it
mirrors `sdl2_audio.py` closely enough to diff — see "Keep it in step with
`sdl2_audio.py`" below. `web_audio.py` shares nothing with them and stays as it is.
not a bug there. [`pygame_audio.py`](pygame_audio.py) still uses the portable forms, because it
mirrors [`sdl2_audio.py`](sdl2_audio.py) closely enough to diff — see "Keep it in step with
`sdl2_audio.py`" below. [`web_audio.py`](web_audio.py) shares nothing with them and stays as it is.

Verify with the real interpreters rather than by inspection — CPython accepts
everything above:
Expand Down Expand Up @@ -622,7 +622,7 @@ thread. Do not make it synchronous.
`PygamePCMOutput` mirrors `SDLPCMOutput` mechanism for mechanism: rate-based
stall detection, the hardware-only prebuffer gate, the off-thread rebuild with a
settle gap, the shadow buffer, and the same `recycles` / `lost_bytes` /
`requeued_bytes` counters. Every "do not simplify" rule in the `sdl2_audio.py`
`requeued_bytes` counters. Every "do not simplify" rule in the [`sdl2_audio.py`](sdl2_audio.py)
section above applies here unchanged, and the constants carry the same names and
values.

Expand Down
2 changes: 1 addition & 1 deletion palettes/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

- Run from `palettes/`: `PYTHONPATH=lib python3 -m unittest discover -s tests`, then `ruff check lib tests scripts`. These are the two checks CI runs.
- `palettes` has its own version in `VERSION`, apart from the pydevices release. A merged change to `VERSION` and `CHANGELOG.md` tags `palettes-vX.Y.Z` and publishes `pydevices-palettes`; the import and mip name stay `palettes`.
- `lib/palettes/_*.py` is generated or static color data, and `palettes.toml` is generated by publishing automation. Don't edit either by hand.
- `lib/palettes/_*.py` is generated or static color data, and [`palettes.toml`](palettes.toml) is generated by publishing automation. Don't edit either by hand.
- Docstrings use Google style with no Sphinx roles (no `:class:`); CI fails on one.
- More in [CONTRIBUTING.md](CONTRIBUTING.md).
- Examples follow the style in the [repo's AGENTS.md](../AGENTS.md): REUSE licence header, a docstring ending `Needs:`, `Run it:`, `Tested on:`, a settings block, a comment above each step, pygraphics rather than `framebuf`.
8 changes: 4 additions & 4 deletions palettes/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ code.
| `tests/` | An import smoke test, plus contracts for depth, index and name order and cube size. |
| `docs/` | The documentation site's source. |
| [`scripts/generate_palette_screenshots.py`](scripts/generate_palette_screenshots.py) | Redraws the images under [`docs/images`](docs/images/). |
| `manifest.py` | The freeze manifest for [`lib/palettes`](lib/palettes/), for MicroPython and CircuitPython firmware builds. |
| `palettes.toml` | The PyScript gallery's file list. Generated by publishing automation; don't edit it by hand. |
| `pyproject.toml`, `VERSION` | The setuptools metadata and the package version. |
| [`manifest.py`](manifest.py) | The freeze manifest for [`lib/palettes`](lib/palettes/), for MicroPython and CircuitPython firmware builds. |
| [`palettes.toml`](palettes.toml) | The PyScript gallery's file list. Generated by publishing automation; don't edit it by hand. |
| [`pyproject.toml`](pyproject.toml), `VERSION` | The setuptools metadata and the package version. |

## Run the tests

Expand All @@ -47,7 +47,7 @@ pip install -r docs/requirements.txt
sphinx-build -W --keep-going -b html docs _site
```

Read the Docs builds the same site from `.readthedocs.yaml`, with warnings as
Read the Docs builds the same site from [`.readthedocs.yaml`](.readthedocs.yaml), with warnings as
errors. The API pages are generated from the docstrings when you build.

## Release
Expand Down
4 changes: 2 additions & 2 deletions pdwidgets/AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# AGENTS.md

- Run from `pdwidgets/`. It imports `appdev`, `multimer`, `palettes` and `pygraphics` from source, so the bare test command fails with `No module named 'events'` unless they're installed. Put them on the path, with a pygraphics checkout at `$PYGRAPHICS`: `PYTHONPATH="lib:tests/stubs:../lib:../palettes/lib:$PYGRAPHICS/lib" python -m unittest discover -s tests`, then `ruff check lib tests scripts`.
- After you add or change a widget, run `python scripts/pdwidgets_widget_deps.py` to regenerate `lib/pdwidgets/widget-dependencies.md`. `lib/pdwidgets/icons/` and `pdwidgets.toml` are generated too; don't edit them by hand.
- After you add or change a widget, run `python scripts/pdwidgets_widget_deps.py` to regenerate [`lib/pdwidgets/widget-dependencies.md`](lib/pdwidgets/widget-dependencies.md). `lib/pdwidgets/icons/` and [`pdwidgets.toml`](pdwidgets.toml) are generated too; don't edit them by hand.
- A `Label` takes `value=` and a `Button` takes `label=`. There is no `text=`. Callbacks are `callback(sender, event)`.
- `pdwidgets` has its own version in `VERSION`, apart from the pydevices release; see [CONTRIBUTING.md](CONTRIBUTING.md#release) and its widget conventions.
- `tests/test_doc_examples.py` checks the Python blocks in the docs against the package, so a renamed argument fails there.
- [`tests/test_doc_examples.py`](tests/test_doc_examples.py) checks the Python blocks in the docs against the package, so a renamed argument fails there.
- Examples follow the style in the [repo's AGENTS.md](../AGENTS.md): REUSE licence header, a docstring ending `Needs:`, `Run it:`, `Tested on:`, a settings block, a comment above each step, pygraphics rather than `framebuf`.
8 changes: 4 additions & 4 deletions pdwidgets/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ the pieces fit.
| `scripts/` | Icon generation, the widget dependency graph and the README screenshot. |
| `tools/` | A render and event micro-benchmark, and a PNG smoke probe. |
| `docs/` | The documentation site's source. |
| `manifest.py` | The freeze manifest for [`lib/pdwidgets`](lib/pdwidgets/), for firmware builds. |
| `pdwidgets.toml` | The PyScript gallery's file list. Generated by publishing automation; don't edit it by hand. |
| `pyproject.toml`, `VERSION` | The setuptools metadata and the package version. |
| [`manifest.py`](manifest.py) | The freeze manifest for [`lib/pdwidgets`](lib/pdwidgets/), for firmware builds. |
| [`pdwidgets.toml`](pdwidgets.toml) | The PyScript gallery's file list. Generated by publishing automation; don't edit it by hand. |
| [`pyproject.toml`](pyproject.toml), `VERSION` | The setuptools metadata and the package version. |

## Run the tests

Expand Down Expand Up @@ -103,7 +103,7 @@ pip install -r docs/requirements.txt
sphinx-build -W --keep-going -b html docs _site
```

Read the Docs builds the same site from `.readthedocs.yaml`, with warnings as
Read the Docs builds the same site from [`.readthedocs.yaml`](.readthedocs.yaml), with warnings as
errors. The API pages are generated from the docstrings when you build.

## Release
Expand Down
4 changes: 2 additions & 2 deletions sayso/AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# AGENTS.md

- Run from `sayso/`: `PYTHONPATH=lib python3 -m unittest discover -s tests`. The offline tests need no credentials; `tests/test_live.py` talks to Spotify and skips without `sayso.local.json`.
- Run from `sayso/`: `PYTHONPATH=lib python3 -m unittest discover -s tests`. The offline tests need no credentials; [`tests/test_live.py`](tests/test_live.py) talks to Spotify and skips without `sayso.local.json`.
- Never commit `sayso.local.json`, `tokens.json` or `examples/write_examples.json`.
- To test without a network, replace `sayso.transport.requests` with a mock that has `get`/`post` (and `put`/`delete` for writes) before you build `SpotifyClient`.
- Spotify's Dev Mode removed `GET /users/{id}` and the legacy playlist track endpoints ([`PORTABILITY.md`](PORTABILITY.md)). Don't add `fetch_method` on `User`.
- `examples/*.py` and most `scripts/` need real credentials and a network; `scripts/endpoint_coverage.py` and `scripts/generate_object_specs.py` fetch Spotify's OpenAPI schema unless you pass a local path.
- `examples/*.py` and most `scripts/` need real credentials and a network; [`scripts/endpoint_coverage.py`](scripts/endpoint_coverage.py) and [`scripts/generate_object_specs.py`](scripts/generate_object_specs.py) fetch Spotify's OpenAPI schema unless you pass a local path.
- Examples follow the style in the [repo's AGENTS.md](../AGENTS.md): REUSE licence header, a docstring ending `Needs:`, `Run it:`, `Tested on:`, a settings block, a comment above each step, pygraphics rather than `framebuf`.
6 changes: 3 additions & 3 deletions sayso/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ Page-backed fields use `object_by_key` and a `page_method`:

`User` and other non-fetchable types only expose fields present in the embedding
response. Under February 2026 Dev Mode, `GET /users/{id}` is not available; use
`client.me()` for the authenticated user. See `PORTABILITY.md`.
`client.me()` for the authenticated user. See [`PORTABILITY.md`](PORTABILITY.md).

When hydration or lazy page load fails, the object layer raises `HydrationError`
with object type, endpoint, and Dev Mode hints. The original `TransportError` is
Expand Down Expand Up @@ -370,7 +370,7 @@ Some playback controls require Spotify Premium and an active device.
- **February 2026 Dev Mode** — several endpoints are removed or return 403
(for example `GET /users/{id}`, legacy `playlist_tracks`). Use `client.me()`
for the current user and `playlist.items` for playlist entries. See
`PORTABILITY.md` for details.
[`PORTABILITY.md`](PORTABILITY.md) for details.

See `ROADMAP.md` for implemented areas, next steps, and open design questions.
See [`ROADMAP.md`](ROADMAP.md) for implemented areas, next steps, and open design questions.
See `PORTABILITY.md` for CPython, MicroPython, and CircuitPython boundary notes.
2 changes: 1 addition & 1 deletion sayso/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ transport helpers, read methods, selected write methods, examples, and live test
- `Artist.albums` and `Playlist.items` wired to client page methods
- Discovery scripts (`sayso_*_discovery.py`) for object-graph walkthroughs
- Offline object-layer unit tests in [`tests/test_objects.py`](tests/test_objects.py)
- February 2026 Dev Mode API notes in `PORTABILITY.md`
- February 2026 Dev Mode API notes in [`PORTABILITY.md`](PORTABILITY.md)
- `SpotifyObject.__str__()` pretty-prints raw object data for `print()`
- Client Credentials auth
- Authorization Code auth helpers consolidated in `sayso.auth`
Expand Down
20 changes: 10 additions & 10 deletions sayso/apps/spotify_remote/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,16 @@ MicroPython (Linux and Windows) under the PyDevices stack.

| File | Role |
|------|------|
| `main.py` | Entry point: auth, playback polling, event loop |
| `spotify_ctrl.py` | sayso wrapper (no LVGL) |
| `ui.py` | LVGL widgets; root screen via `scr = lv.screen_active()` |
| `config.py` | Tunable limits (cover-art cache size, library list size) |
| `artwork_cache.py` | Downloads and caches cover art from Spotify CDN URLs |
| `image_view.py` | Small LVGL cover-art view with a placeholder fallback |
| `genre_seeds.py` | Static genre preset list when the API seed endpoint is unavailable |
| `__main__.py` | `-m spotify_remote` entry point (runs the loop itself) |
| `local_speaker.py` | Optional earful Connect speaker in the same process |
| `keyboard_test.py` | PyDevices keyboard smoke test (LVGL textarea input) |
| [`main.py`](main.py) | Entry point: auth, playback polling, event loop |
| [`spotify_ctrl.py`](spotify_ctrl.py) | sayso wrapper (no LVGL) |
| [`ui.py`](ui.py) | LVGL widgets; root screen via `scr = lv.screen_active()` |
| [`config.py`](config.py) | Tunable limits (cover-art cache size, library list size) |
| [`artwork_cache.py`](artwork_cache.py) | Downloads and caches cover art from Spotify CDN URLs |
| [`image_view.py`](image_view.py) | Small LVGL cover-art view with a placeholder fallback |
| [`genre_seeds.py`](genre_seeds.py) | Static genre preset list when the API seed endpoint is unavailable |
| [`__main__.py`](__main__.py) | `-m spotify_remote` entry point (runs the loop itself) |
| [`local_speaker.py`](local_speaker.py) | Optional earful Connect speaker in the same process |
| [`keyboard_test.py`](keyboard_test.py) | PyDevices keyboard smoke test (LVGL textarea input) |

## Prerequisites

Expand Down
2 changes: 1 addition & 1 deletion tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ the sibling `gallery` integration repository.

## The package library

`libbuild.py` needs Python 3.11 or later, `git`, and `mpy-cross`
[`libbuild.py`](libbuild.py) needs Python 3.11 or later, `git`, and `mpy-cross`
(`pip install mpy-cross`). From the repository root:

```bash
Expand Down
Loading