feat(slides): extend the persisted batch primitive to Slides (presentations.batchUpdate) — 197 write calls to rebuild one 7-slide deck, 429s at 60/min
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 8.4k
- Forks
- 694
- Avg merge
- 15h 39m
- Merged PRs (30d)
- 89
Description
What already exists
gog batch is a complete persisted-batch facility: begin, list, show, end, abort, prune, plus --batch=<id> on docs write, docs insert, docs update, docs delete, docs format, docs cell-style, docs table-column-width, docs insert-image and docs insert-person. Open a batch against a document, accumulate requests across many CLI invocations, submit once as a single documents.batchUpdate.
It is Docs-only. On v0.39.0 gog batch begin accepts --doc and --name and nothing else, and no gog slides command carries --batch.
Why Slides needs it more than Docs did
Docs has docs write --replace --markdown, which renders a whole document body in one internal batchUpdate. Slides has no equivalent for shapes. create-from-markdown builds text on the default theme only, and there is no way to place a positioned shape, a coloured panel, a flow box or a native table from a source file. So any deck built with real structure is built element by element, and every gog slides mutation is its own process and its own presentations.batchUpdate carrying a single request.
Two properties of the current command surface multiply the count:
element create-shapecarries no fill or outline flags, so every shape costscreate-shapepluselement style.table cell stylestyles exactly one zero-based cell. There is no row, column or span selector, so an N-by-M table costs N×M style calls on top of N×Minsert-textcalls.
Measured cost
Rebuilding a seven-slide deck from a source file, a routine shape-heavy deck with two tables, one flow row, a caption band, a chat sequence and seven panels, issues 205 gog slides invocations: 8 raw reads and 197 writes. Per primitive, writes only:
| Primitive | Writes | Composition |
|---|---|---|
| Titles and lead lines across 7 slides | 23 | insert-text per placeholder plus one style-text per run |
| Native table, 6 rows x 2 cols | 29 | 1 delete of the previous table, 1 table create, 1 element transform, 2 table column size, 12 insert-text, 12 table cell style |
| Native table, 5 rows x 2 cols | 25 | same shape |
| Flow row, 5 boxes and 4 arrow connectors | 37 | 9 deletes, 18 create-shape/style pairs, 5 texts, 5 style runs |
| Chat sequence, 6 bubbles | 36 | 6 deletes, 6 create-shape/style pairs, 6 texts, 12 style runs |
| Panel row, 4 panels | 24 | 4 deletes, 4 create-shape/style pairs, 4 texts, 8 style runs |
| Panel row, 3 panels | 18 | same shape |
| Caption band | 5 | 1 delete, create-shape, style, insert-text, style-text |
The documented Slides quota is 60 write requests per minute per user per project (https://developers.google.com/workspace/slides/api/limits). 197 writes is 3.3x that ceiling, and because each invocation is a full process plus a round trip the run paces itself at roughly the quota rate. The rebuild fails partway through the fifth slide with:
429 rateLimitExceeded: Quota exceeded for quota metric 'Write requests' and limit
'Write requests per minute per user' of service 'slides.googleapis.com'
Batched, the same deck is one presentations.batchUpdate of 197 requests, well inside the 500-request cap. One quota item instead of 197, and seconds instead of minutes.
What a caller has to do today
Sleep between calls and hope, or drop out of gog entirely and drive presentations.batchUpdate from a Google API client library. The second is what happens in practice, which loses gog's auth handling for the sake of one endpoint.
Proposed surface
Keep the Docs shape verbatim, since consistency with a shipped command is easier to reason about than a new design:
gog batch begin --presentation=<id> [--name=<label>]
gog slides element create-shape --batch=<id> ...
gog slides element style --batch=<id> ...
gog slides insert-text --batch=<id> ...
gog slides style-text --batch=<id> ...
gog slides table create --batch=<id> ...
gog slides table cell style --batch=<id> ...
gog slides table column size --batch=<id> ...
gog slides element transform --batch=<id> ...
gog slides element delete --batch=<id> ...
gog batch end <id>
--dry-run, --continue-on-error, --auto-split and the revision lock behave as they do for Docs. presentations.batchUpdate is atomic in the same way documents.batchUpdate is, so strict-atomic-by-default carries over.
One Slides-specific note worth encoding: a request that creates an object with an explicit objectId and a later request that references that id can sit in the same batch, so a create-then-style pair batches cleanly. Object ids must be at least 5 characters and are unique across the whole presentation, so a batch built from per-slide commands needs no id rewriting.
Commands that should stay out of a batch: raw, read-slide, locate, list-slides, info and thumbnail are reads, and insert-image uploads bytes before it emits a request.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing the existing persisted Docs batch commands and the listed Slides mutation entry points, then compare how they emit documents.batchUpdate versus presentations.batchUpdate. Implement the proposed --presentation batch lifecycle and --batch flags for the listed write commands while excluding reads and insert-image. Done means one Slides batch submits the accumulated requests with the existing dry-run, error, auto-split, and revision-lock behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100