extraslide
A Python library that converts Google Slides to/from SML (Slide Markup Language) - an XML-based format optimized for AI agent editing.
Overview
extraslide enables AI agents (Claude Code, Codex, etc.) to read and edit Google Slides through a simple workflow:
- Pull - Download a presentation as editable SML files
- Edit - Agent modifies the SML based on user instructions
- Diff - Preview changes before applying (dry run)
- Push - Apply changes to Google Slides
The library handles all the complexity of the Google Slides API - agents just edit XML.
Installation
pip install extraslide
# or
uvx extraslide --help
The Pull-Edit-Diff-Push Workflow
Step 1: Pull
Download a presentation to a local folder:
uvx extraslide pull "https://docs.google.com/presentation/d/1abc.../edit"
This creates a folder structure:
1abc.../
presentation.json # Metadata (title, ID, dimensions)
id_mapping.json # clean_id -> google_object_id mapping
styles.json # Styles for each element (position, fill, stroke, text)
slides/
01/content.sml # Slide 1 content
02/content.sml # Slide 2 content
...
.pristine/
presentation.zip # Original state for diff comparison
.raw/
presentation.json # Raw API response (for debugging)
Step 2: Edit
The agent edits slides/NN/content.sml files based on user instructions. SML uses a minimal XML syntax:
<Slide>
<TextBox id="e1" x="100" y="50" w="500" h="80">
<P><T>Quarterly Report</T></P>
</TextBox>
<Rect id="e2" x="50" y="200" w="300" h="150"/>
</Slide>
Common edits:
- Change text content inside
<T>tags - Modify positions (
x,y) or sizes (w,h) - Add/delete elements
- Copy elements (duplicate with same ID, new position, omit w/h)
See copy-workflow.md for the copy-based editing guide.
Step 3: Diff (Preview)
See what changes will be applied without modifying the original:
uvx extraslide diff 1abc.../
This compares the current slides/ content against the .pristine/ copy and outputs the Google Slides API requests that would be generated. No API calls are made.
Step 4: Push
Apply the changes to Google Slides:
uvx extraslide push 1abc.../
The library sends a batchUpdate request to the Google Slides API. All edits appear in Google Drive version history with proper attribution.
SML Format
Each slide is stored as a separate content.sml file with minimal XML:
<Slide>
<TextBox id="e1" x="100" y="50" w="500" h="80">
<P><T>Title text</T></P>
</TextBox>
<Rect id="e2" x="50" y="200" w="300" h="150"/>
<Group id="g1" x="400" y="100">
<Ellipse id="e3" x="0" y="0" w="50" h="50"/>
<Ellipse id="e4" x="60" y="0" w="50" h="50"/>
</Group>
</Slide>
Elements
| Element | Description |
|---|---|
<TextBox> |
Text container with paragraphs |
<Rect>, <Ellipse>, <RoundRect> |
Basic shapes |
<Line> |
Lines and connectors |
<Image> |
Images |
<Table> |
Tables with <Row> and <Cell> |
<Group> |
Grouped elements (children use relative positions) |
<Video> |
Embedded videos |
<SheetsChart> |
Linked Google Sheets charts |
Text Content
Text uses a paragraph (<P>) and text run (<T>) structure:
<TextBox id="e1" x="50" y="100" w="400" h="200">
<P><T>Regular text </T><T>more text</T></P>
<P><T>Second paragraph</T></P>
</TextBox>
Positions and Sizes
All positions (x, y) and sizes (w, h) are in points:
<Rect id="e1" x="100" y="200" w="300" h="150"/>
For elements inside groups, positions are relative to the group's origin.
Copying Elements
To copy an element, duplicate its XML with:
- Same
idas the source element - New
x,yposition - Omit
wandh(this signals a copy)
<!-- Original -->
<Rect id="e1" x="100" y="100" w="200" h="100"/>
<!-- Copy (omit w/h to signal copy) -->
<Rect id="e1" x="400" y="100"/>
See copy-workflow.md for details.
CLI Reference
# Pull a presentation
uvx extraslide pull <url_or_id> [output_dir]
uvx extraslide pull "https://docs.google.com/presentation/d/1abc.../edit"
uvx extraslide pull "https://docs.google.com/presentation/d/1abc.../edit" ./my-folder
# Preview changes (dry run)
uvx extraslide diff <folder>
uvx extraslide diff ./1abc.../
# Apply changes
uvx extraslide push <folder>
uvx extraslide push ./1abc.../
Also works as a Python module:
python -m extraslide pull ...
python -m extraslide diff ...
python -m extraslide push ...
Important Notes
Re-pull After Push
After pushing changes, the local SML becomes stale. Always re-pull before making more edits:
uvx extraslide push ./1abc.../
uvx extraslide pull "https://docs.google.com/presentation/d/1abc.../edit" # Re-pull!
# Now safe to edit again
What Can Be Edited
- Text content and styling
- Shape properties (fill, stroke, position, size)
- Add/delete slides
- Add/delete elements
- Copy existing elements
- Tables (content and basic styling)
- Images (can reference existing, limited creation support)
- Charts (read-only, linked to source spreadsheet)
Styles
Element styles (fill, stroke, text formatting) are stored in styles.json and automatically applied when copying elements. You don't need to specify styles in the SML - just copy an element and modify the text/position.
Documentation
- Copy-Based Editing Guide - How to copy and modify elements
- SML Syntax Specification - Full format reference
Requirements
- Python 3.10+
- A valid Google Slides access token supplied by the caller
Project Status
Alpha - The library is functional but still evolving. SML format and CLI may change.
License
Metadata
Release files for extraslide 0.2.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| extraslide-0.2.3.tar.gz | 239.6 kB | With provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| extraslide-0.2.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 288.4 kB
Release files / extraslide-0.2.3.tar.gz
| Download URL | extraslide-0.2.3.tar.gz |
|---|---|
| Size | 239.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
636ee161151a8820d3dd3d33b9fa2e7eae15bbe9fabb2a0234b8904ba7d13a66
|
|
BLAKE2b-256 checksum How to use checksums |
1c935c00238dc0d5469c8ecbd58174ebc7b2d82f976b1d095042374ff1530a4d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 27, 2026.
Transparency logRelease files / extraslide-0.2.3-py3-none-any.whl
| Download URL | extraslide-0.2.3-py3-none-any.whl |
|---|---|
| Size | 48.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b648709ee4af23bddd252d54f1b180c61bd508221fe341c93c1fe297d83b31e9
|
|
BLAKE2b-256 checksum How to use checksums |
47d81c8f8b427f8dce3f13a161156435d4ed1a7f24058924d1d67c8e85e90712
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 27, 2026.
Transparency logSecurity for extraslide 0.2.3
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for extraslide-0.2.3.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 27, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.