---
title: "Python"
description: "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."
url: https://typeship.dev/docs/sdks/python
markdown: https://typeship.dev/docs/sdks/python.md
section: "Get started"
---
> ## Documentation index
> Fetch the complete documentation index at https://typeship.dev/llms.txt (every page, one line each) or the full text at https://typeship.dev/llms-full.txt.
> Append .md to any docs URL, or send Accept: text/markdown, for the markdown twin of that page.

# 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](https://typeship.dev/openapi.yaml). 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

```bash
pip install typeship
```

Python 3.11 or newer. Nothing else is installed.

## Create a client

```python
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](https://typeship.dev/docs/platforms/sdk/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:

```python
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

```python
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:

```python
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](https://typeship.dev/docs/api) has every schema.

## Errors

Every call raises. Each documented status has its own class, and all of them are `ApiError`:

```python
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](https://typeship.dev/docs/typeship-api/api/errors) for the envelope and codes.

## Sitemap

[Every page of these docs](https://typeship.dev/llms.txt)
