Python SDK

Python SDK (planned)

A typed client for the pptx.dev REST API is planned. It is not published to PyPI, so there is nothing to install today. The examples below show the intended API shape; call the REST API directly in the meantime.

Availability

Not available yet

No pptx-dev package is published on PyPI, so there is no install command. Until it ships, call the REST API directly (for example with httpx).

First call

Create a client with your Clerk API key and validate an OPF document. Validation is always free.

Python
from pptx_dev import Pptx

pptx = Pptx()  # reads PPTX_API_KEY from env

result = pptx.opf.validate({
    "$schema": "https://openpresentation.org/schema/opf/v1",
    "name": "Hello",
    "slides": [{ "title": "Hello, world" }]
})

print(result["valid"], result["errors"], result["warnings"])

Async client

The same surface is available as AsyncPptx for use inside asyncio, FastAPI, or any async framework.

Python
import asyncio
from pptx_dev import AsyncPptx

async def main() -> None:
    async with AsyncPptx() as pptx:
        info = await pptx.health()
        print(info)

asyncio.run(main())

Authentication

The client resolves a bearer token in this order:

  1. The api_key option passed to the constructor.
  2. The PPTX_API_KEY environment variable.
Python
from pptx_dev import Pptx

pptx = Pptx(api_key="ak_...")

Get your Clerk API key from the API Keys page.

Canonical OPF dictionaries

Pass canonical OPF as a plain dict. The SDK's historical Pydantic helpers still require the retired meta/elements format and are awaiting migration; they do not describe the current wire contract (migration: issue #136).

Python
from pathlib import Path
from pptx_dev import Pptx

doc = {
    "$schema": "https://openpresentation.org/schema/opf/v1",
    "name": "Q1 Review",
    "filename": "q1-review",
    "slides": [{"title": "Q1 Review"}],
}

pptx = Pptx()
pptx_bytes = pptx.opf.generate(doc, format="pptx")
Path("q1-review.pptx").write_bytes(pptx_bytes)

Parse an existing .pptx

Python
from pathlib import Path
from pptx_dev import Pptx

pptx = Pptx()
data = Path("deck.pptx").read_bytes()

upload = pptx.parse.upload(data, filename="deck.pptx")
slide0 = pptx.parse.slide(upload["parseId"], 0)
print(slide0["textRuns"])

Error handling

All errors extend PptxError.

ErrorWhen
PptxNetworkErrorhttpx raised (DNS, TLS, timeout, connection reset)
PptxApiErrorHTTP 4xx / 5xx response with JSON or text body
PptxValidationErrorHTTP 422 with validationErrors[] from opf.generate
PptxRateLimitErrorHTTP 429 (exposes retry_after_seconds)
Python
from pptx_dev import Pptx, PptxValidationError, PptxRateLimitError

pptx = Pptx()

try:
    pptx.opf.generate(bad_doc)
except PptxValidationError as err:
    print("OPF schema errors:", err.validation_errors)
except PptxRateLimitError as err:
    print("Retry after:", err.retry_after_seconds, "s")

Every error exposes request_id when the server returned an X-Request-Id header.

LangChain

Drop-in tools for LangChain agents. Requires the langchain extra.

Python
from pptx_dev import Pptx
from pptx_dev.integrations.langchain import pptx_toolkit

pptx = Pptx()
tools = pptx_toolkit(pptx)
# pass `tools` to a LangChain agent

LlamaIndex

Drop-in tool spec for LlamaIndex agents. Requires the llamaindex extra.

Python
from pptx_dev import Pptx
from pptx_dev.integrations.llamaindex import pptx_tool_spec

pptx = Pptx()
tools = pptx_tool_spec(pptx).to_tool_list()
# pass `tools` to a LlamaIndex agent

Custom base URL

For local development against a Next.js dev server, or self-hosted deployments:

Python
from pptx_dev import Pptx

pptx = Pptx(base_url="http://localhost:3000/api")