Metadata-Version: 2.4
Name: gslides-builder
Version: 0.1.0
Summary: Build Google Slides from Python. No EMU math. No field masks. Just inches and hex colors.
Project-URL: Homepage, https://github.com/OpenRecruiterTools/google-slides-builder
Project-URL: Documentation, https://github.com/OpenRecruiterTools/google-slides-builder#readme
Project-URL: Repository, https://github.com/OpenRecruiterTools/google-slides-builder
Project-URL: Issues, https://github.com/OpenRecruiterTools/google-slides-builder/issues
Project-URL: Formatix AI, https://formatix.ai
Project-URL: Author LinkedIn, https://www.linkedin.com/in/dominic-g-6a9a5680/
Author-email: Dominic Gonsalves <dom@formatix.ai>
Maintainer-email: Formatix AI <dom@formatix.ai>
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: batchUpdate,google-slides,google-slides-api,google-workspace,presentation,slide-generation,slides,slides-builder
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Typing :: Typed
Requires-Python: >=3.10
Provides-Extra: dev
Requires-Dist: mypy>=1.10; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.4; extra == 'dev'
Provides-Extra: google
Requires-Dist: google-api-python-client>=2.0; extra == 'google'
Requires-Dist: google-auth-oauthlib>=1.0; extra == 'google'
Requires-Dist: google-auth>=2.0; extra == 'google'
Description-Content-Type: text/markdown

# gslides-builder

**Build Google Slides from Python. No EMU math. No field masks. Just inches and hex colors.**

[![PyPI version](https://img.shields.io/pypi/v/gslides-builder.svg)](https://pypi.org/project/gslides-builder/)
[![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)](https://www.python.org/downloads/)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

A zero-dependency Python library that converts simple JSON layouts into Google Slides API `batchUpdate` requests. Think of it as the [PptxGenJS](https://github.com/gitbrent/PptxGenJS) equivalent for Google Slides.

**You describe slides in inches and hex colors. The library handles EMU conversion, field masks, nested color objects, transforms, and every API gotcha so you don't have to.**

## Installation

```bash
pip install gslides-builder
```

With optional Google API client (for executing requests directly):

```bash
pip install "gslides-builder[google]"
```

## Quick Start

```python
from google_slides_builder import SlideBuilder

builder = SlideBuilder()
requests = builder.build(layout={
    "slides": [
        {
            "background": {"color": "#1a1a2e"},
            "elements": [
                {
                    "type": "text",
                    "content": "Q4 Revenue Report",
                    "x": 1.0, "y": 2.0,
                    "width": 8.0, "height": 1.5,
                    "font_size": 36,
                    "color": "#FFFFFF",
                    "bold": True,
                    "alignment": "CENTER",
                }
            ]
        }
    ]
})

# `requests` is a list of dicts ready for the Google Slides API batchUpdate endpoint
```

### Execute with Google API

```python
from google_slides_builder import SlideBuilder
from google_slides_builder.client import GoogleSlidesClient

builder = SlideBuilder()
requests = builder.build(layout={...})

# Use your own Google credentials (OAuth2 or service account)
client = GoogleSlidesClient(credentials=creds)
presentation = client.create("Q4 Revenue Report", requests)
print(client.get_url(presentation))
# https://docs.google.com/presentation/d/abc123/edit
```

## Features

### Four Element Types

**Text** — single or multi-styled text boxes:

```python
{
    "type": "text",
    "content": "Hello World",
    "x": 1.0, "y": 2.0, "width": 8.0, "height": 1.5,
    "font_size": 24, "color": "#2B579A", "font": "Montserrat",
    "bold": True, "alignment": "CENTER",
    "vertical_align": "MIDDLE", "background": "#F0F0F0",
}
```

Multi-styled text with `runs`:

```python
{
    "type": "text",
    "x": 1.0, "y": 2.0, "width": 8.0, "height": 1.0,
    "runs": [
        {"text": "Revenue: ", "font_size": 18, "color": "#333333"},
        {"text": "$4.2M", "font_size": 18, "color": "#27AE60", "bold": True},
        {"text": " (+12% YoY)", "font_size": 14, "color": "#7F8C8D", "italic": True},
    ]
}
```

**Table** — with headers, alternating rows, and auto-splitting:

```python
{
    "type": "table",
    "headers": ["Name", "Role", "Revenue"],
    "rows": [
        ["Alice Chen", "VP Sales", "$1.2M"],
        ["Bob Park", "Director", "$890K"],
        ["Carol Wu", "Manager", "$650K"],
    ],
    "x": 0.5, "y": 1.5, "width": 9, "height": 3,
    "header_bg": "#2C3E50", "header_color": "#FFFFFF",
    "alt_row_bg": "#F5F5F5", "font_size": 11,
    "col_widths": [3, 3, 2],
}
```

Tables that exceed the slide height **automatically split across continuation slides** with repeated headers and "(continued 2/3)" labels.

**Shape** — rectangles, ellipses, accent bars, badges:

```python
{
    "type": "shape",
    "shape": "RECTANGLE",
    "x": 0, "y": 0, "width": 10, "height": 0.04,
    "fill": "#E74C3C",
    "outline": False,
}
```

Shapes can contain text that auto-shrinks to fit:

```python
{
    "type": "shape",
    "shape": "ELLIPSE",
    "x": 4, "y": 2, "width": 2, "height": 2,
    "fill": "#3498DB",
    "content": "85%", "font_size": 28, "color": "#FFFFFF",
    "alignment": "CENTER",
}
```

**Image** — from any HTTPS URL:

```python
{
    "type": "image",
    "url": "https://example.com/chart.png",
    "x": 1, "y": 1, "width": 4, "height": 3,
}
```

### Smart Behaviors

| Feature | What it does |
|---------|-------------|
| **EMU conversion** | You write inches, the library converts to EMU (914,400 per inch) |
| **Hex color conversion** | `"#2C3E50"` becomes `{"rgbColor": {"red": 0.17, "green": 0.24, "blue": 0.31}}` |
| **Alignment mapping** | `"LEFT"` / `"RIGHT"` auto-mapped to API's `"START"` / `"END"` |
| **Shape aliases** | `"CIRCLE"` -> `"ELLIPSE"`, `"SQUARE"` -> `"RECTANGLE"`, etc. |
| **Field mask generation** | Correct masks built automatically — never uses `"*"` |
| **Table auto-splitting** | Overflow rows split across slides with headers repeated |
| **Overlap detection** | Vertically overlapping text elements pushed apart |
| **Image-in-shape inset** | Images overlapping shapes auto-inset for visual framing |
| **Smart text fitting** | Font auto-shrinks to fit shapes; text boxes auto-expand |
| **SVG filtering** | Silently skips `.svg` URLs (unsupported by the Slides API) |
| **HTTPS enforcement** | Auto-upgrades `http://` image URLs to `https://` |
| **Bounds clamping** | Elements clamped to slide dimensions — no off-screen content |

### Font Overrides

Enforce consistent typography across all elements:

```python
requests = builder.build(
    layout=layout,
    font_overrides={"heading": "Montserrat", "body": "Open Sans"},
)
```

Headings (font_size >= 24pt) get the heading font; everything else gets the body font.

### Background Variety

Prevent monotonous presentations by providing a color palette:

```python
requests = builder.build(
    layout=layout,
    palette={"primary": "#1a1a2e", "background": "#f8f5f0"},
)
```

If >60% of slides share the same background, the builder automatically alternates with the palette colors.

## Layout JSON Schema

The full input schema:

```json
{
  "slides": [
    {
      "id": "optional_slide_id",
      "background": {
        "color": "#RRGGBB"
      },
      "elements": [
        {
          "type": "text | table | shape | image",
          ...
        }
      ]
    }
  ]
}
```

See [docs/layout-schema.md](docs/layout-schema.md) for the complete reference.

## How It Compares

| Feature | gslides-builder | gslides-api | slidio | Raw API |
|---------|:--------------------:|:-----------:|:------:|:-------:|
| Zero dependencies | Yes | No (Pydantic) | No | No |
| Inches (not EMU) | Yes | No | N/A | No |
| Hex colors | Yes | No | N/A | No |
| Auto field masks | Yes | Partial | No | Manual |
| Table auto-split | Yes | No | No | No |
| Overlap detection | Yes | No | No | No |
| Text auto-fitting | Yes | No | No | No |
| Shape aliases | Yes | No | No | No |
| Template-free | Yes | Yes | No | Yes |
| Multi-run text | Yes | Yes | No | Manual |

## When to Use This

- **You want programmatic control** over slide layout — not templates
- **Your data drives the content** — reports, dashboards, data pipelines
- **You're building with AI/LLMs** — feed JSON from GPT/Claude/Gemini, get slides
- **You need zero dependencies** — embed in Lambda, Cloud Functions, containers
- **You want the Google Slides API without the pain** — EMU math, field masks, nested objects

## When NOT to Use This

- You want to fill placeholders in existing templates → use [slidio](https://pypi.org/project/slidio/)
- You want pandas DataFrames as charts → use [gslides](https://pypi.org/project/gslides/)
- You want PowerPoint (.pptx) output → use [PptxGenJS](https://github.com/gitbrent/PptxGenJS) or [python-pptx](https://python-pptx.readthedocs.io/)

## Examples

See the [examples/](examples/) directory:

- `01_hello_world.py` — minimal single-slide presentation
- `02_styled_deck.py` — multi-slide deck with shapes, tables, images
- `03_from_data.py` — generate slides from a data dictionary
- `04_with_google_api.py` — full end-to-end with Google auth and execution

## API Reference

### `SlideBuilder`

```python
from google_slides_builder import SlideBuilder

builder = SlideBuilder()
requests = builder.build(
    layout={"slides": [...]},           # Required: layout JSON
    font_overrides={"heading": ".."},   # Optional: enforce fonts
    palette={"primary": "#.."},         # Optional: background variety
    known_image_urls={"https://.."},    # Optional: verified image URLs
)
```

### `GoogleSlidesClient`

```python
from google_slides_builder.client import GoogleSlidesClient

client = GoogleSlidesClient(credentials=creds)

# Create new presentation
presentation = client.create("Title", requests)

# Update existing presentation
client.update(presentation_id, requests)

# Get presentation
pres = client.get(presentation_id)

# Get browser URL
url = client.get_url(presentation)
```

## Need More Than Slides?

This library handles Google Slides. If you need **automated branded documents** across multiple formats, check out [Formatix AI](https://formatix.ai):

| | gslides-builder (this library) | [Formatix AI](https://formatix.ai) |
|---|:---:|:---:|
| Google Slides | Yes | Yes |
| **DOCX** (Word) | — | Yes |
| **PPTX** (PowerPoint) | — | Yes |
| **XLSX** (Excel) | — | Yes |
| Custom branded templates | — | Yes |
| AI-powered content generation | — | Yes |
| Brand kit auto-application | — | Yes |
| CV-to-branded-bio conversion | — | Yes |
| Batch document generation | — | Yes |
| API access | — | Yes |

**Formatix AI** creates fully branded, custom document templates — DOCX, PowerPoint, Excel, and Google Slides — all automated. Upload a CV, get a pixel-perfect branded bio. Feed in data, get a board-ready presentation. Your brand guidelines applied automatically, every time.

Used by executive search firms, consultancies, and enterprises to generate thousands of branded documents.

[Visit formatix.ai](https://formatix.ai) | [Contact Dominic](https://www.linkedin.com/in/dominic-g-6a9a5680/)

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md). PRs welcome.

## License

Apache 2.0 — see [LICENSE](LICENSE).

---

Built and maintained by [Dominic Gonsalves](https://www.linkedin.com/in/dominic-g-6a9a5680/) at [Formatix AI](https://formatix.ai) — automated branded document generation across DOCX, PPTX, XLSX, and Google Slides.
