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
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.
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.
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:
- The
api_keyoption passed to the constructor. - The
PPTX_API_KEYenvironment variable.
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).
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
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.
| Error | When |
|---|---|
| PptxNetworkError | httpx raised (DNS, TLS, timeout, connection reset) |
| PptxApiError | HTTP 4xx / 5xx response with JSON or text body |
| PptxValidationError | HTTP 422 with validationErrors[] from opf.generate |
| PptxRateLimitError | HTTP 429 (exposes retry_after_seconds) |
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.
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.
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:
from pptx_dev import Pptx pptx = Pptx(base_url="http://localhost:3000/api")