Python
The Python client for typeship's own API. Generated by typeship from its own spec, so it is also a sample of what your Python users get.
typeship on PyPI is the Python SDK for the typeship API, generated by typeship from its own OpenAPI spec. It has the same shape as every Python SDK typeship generates: zero runtime dependencies, TypedDict payloads, typed exceptions, auto-pagination, retries, and an async client. If you want to see what your Python users will get before you generate anything, read this package.
Install
pip install typeshipPython 3.11 or newer. Nothing else is installed.
Create a client
import os
from typeship import TypeshipClient
client = TypeshipClient(bearer_token=os.environ["TYPESHIP_TOKEN"])The key comes from the console under api keys. Pass it, or set TYPESHIP_TOKEN. TypeshipClient takes the same options as any generated Python client: base_url, timeout, max_retries, default_headers, transport, on_request, on_response, on_error, debug, and validate. See Python.
Generate a package
generate.run runs the generator on a spec and returns the files. Nothing is stored. The free plan generates the first 25 operations; paid plans generate the whole spec:
from pathlib import Path
result = client.generate.run(
spec={"url": "https://api.acme.example.com/openapi.json"},
platforms=["sdk", "cli"],
language="python",
)
for file in result["files"]:
target = Path("out") / file["path"]
target.parent.mkdir(parents=True, exist_ok=True)
target.write_text(file["content"])
print(result["meta"]["operation_count"], "operations")Work with projects
project = client.projects.create(
name="Acme API",
spec_url="https://api.acme.example.com/openapi.json",
platforms=["sdk", "cli", "mcp"],
languages=["typescript", "python"],
destinations={
"typescript": {"repo": "acme/acme-node"},
"python": {"repo": "acme/acme-python"},
},
auto_regen=True,
)
# Regenerate on demand and read every language's files.
for generation in client.projects.generate(project["id"])["data"]:
if generation["status"] != "succeeded":
continue
print(generation["language"], generation["meta"]["file_count"])
# Walk history: the iterator fetches every page.
for generation in client.projects.list_generations(project["id"]):
print(generation["created_at"], generation["trigger"], generation["status"])Async
AsyncTypeshipClient has the same methods, awaitable:
import asyncio
from typeship import AsyncTypeshipClient
async def main() -> None:
async with AsyncTypeshipClient(bearer_token=os.environ["TYPESHIP_TOKEN"]) as client:
me = await client.account.me()
async for project in client.projects.list():
print(project["name"])
asyncio.run(main())Every method
| Resource | Methods |
|---|---|
generate | run(*, spec, platforms=None, language=None, package_name=None, config=None) |
projects | list(), create(*, name, ...), get(id), update(id, ...), delete(id), generate(id), list_generations(id) |
generations | get(id), get_file(id, *, path) |
spec_versions | list(project_id), get(id), get_content(id) |
account | me() |
usage | retrieve() |
api_keys | list(), revoke(id) |
Paginated methods have a _page twin (projects.list_page()) that returns one envelope. Bodies and responses use the API's snake_case names. api.md inside the package is the complete reference, and the API reference has every schema.
Errors
Every call raises. Each documented status has its own class, and all of them are ApiError:
from typeship import NotFoundError, PaymentRequiredError
try:
client.projects.generate("prj_...")
except PaymentRequiredError as exc:
# free plan allowance used up; exc.body["errors"][0]["message"] says so
...
except NotFoundError:
# no such project on this account
...See Errors for the envelope and codes.