termix-sdk
Unofficial Python client SDK for the Termix REST API.
Generated from a spec this repo derives directly from the Termix backend
source, not from Termix's own hand-written openapi.json — see
Generating our own Termix API spec
for why. As of release-2.7.1-tag, that covers 477 of 491 real
endpoints; the rest are either genuinely out of scope (browser-redirect
OIDC flows, internal-only routes) or need a documented request/response
shape the spec doesn't have (3 file_manager streaming-upload endpoints).
Install
pip install termix-sdk
Requires Python 3.10+. The only runtime dependencies are httpx and
typing-extensions.
Quickstart
An API key (tmx_..., created in Termix under Settings → API Keys) is the
recommended way to authenticate — it skips the login/TOTP dance entirely:
from termix_sdk import TermixClient
client = TermixClient(base_url="https://termix.example.com", api_key="tmx_...")
for host in client.hosts.list():
print(host.name, host.ip)
client.close()
TermixClient is also a context manager:
with TermixClient(base_url="https://termix.example.com", api_key="tmx_...") as client:
host = client.hosts.retrieve("42")
Username/password login
TermixClient.login() handles Termix's login quirk for you: the backend
only puts the JWT in the response body (rather than only in a cookie a
Python client can't use) when the request looks like it came from a
native app, so this always sends that header.
from termix_sdk import TermixClient, PendingTOTP
result = TermixClient.login(
base_url="https://termix.example.com",
username="alice",
password="...",
)
if isinstance(result, PendingTOTP):
# The account has TOTP enabled and this device isn't trusted yet.
client = result.verify(input("6-digit code: "))
else:
client = result
Async
Every resource has an async twin, via a separate client rather than
_async suffixed methods:
import asyncio
from termix_sdk import AsyncTermixClient
async def main():
async with AsyncTermixClient(
base_url="https://termix.example.com", api_key="tmx_..."
) as client:
hosts = await client.hosts.list()
print([h.name for h in hosts])
asyncio.run(main())
SSH-backed sessions (file manager, Docker)
file_manager and docker open an SSH-backed session server-side
before you can call anything else on them. ssh_session() (and its
async twin async_ssh_session()) manage that lifecycle — connect,
optional keepalive, disconnect on exit, even on error:
from termix_sdk import ssh_session
with ssh_session(client.file_manager, host_id=42) as fm:
for entry in fm.list_files(path="/"):
print(entry)
# disconnected automatically here
Every method is still callable directly with an explicit session_id if
you'd rather manage the lifecycle yourself — ssh_session() is a
convenience layer on top, not a requirement.
Errors
Every non-2xx response raises a typed subclass of TermixError:
from termix_sdk import AuthenticationError, NotFoundError, RateLimitError, TermixError
try:
client.hosts.retrieve("does-not-exist")
except NotFoundError as e:
print(e.code, e.details)
except RateLimitError as e:
print("retry after", e.remaining_time, "seconds")
except TermixError as e:
print(e.http_status, e)
What's generated vs. hand-written
src/termix_sdk/resources/, models/, and types/ are generated by
tools/sdk-gen/generate.py from spec/termix-openapi.json and
tools/sdk-gen/config/resource-map.json — don't hand-edit them, changes
will be overwritten on the next run. Everything else (_client.py,
_error.py, _object.py, _session.py, _sse.py, ...) is hand-written
core, adapted from stripe/stripe-python
where noted — see NOTICE for the MIT attribution this carries.
Development
pip install -e ".[dev]"
pytest
ruff check .
mypy
See CONTRIBUTING.md for how the spec/generator/tests fit together and how to regenerate the SDK after a Termix release.
Documentation
- Generating our own Termix API spec: why the SDK does not rely on the official
openapi.json, and how the spec is derived from the Termix backend source (route discovery, auth, typed request bodies, every response per status code, Drizzle schema, test examples). - CHANGELOG.md
- CONTRIBUTING.md
License
MIT — see LICENSE. Portions adapted from stripe-python are also MIT; see NOTICE.
Release files for termix-sdk 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| termix_sdk-0.1.1.tar.gz | 157.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| termix_sdk-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 318.9 kB
Release files / termix_sdk-0.1.1.tar.gz
| Download URL | termix_sdk-0.1.1.tar.gz |
|---|---|
| Size | 157.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
df78325b91f1313539662673b93a8b2362a8232ad504c21e26cddeca3cf0962e
|
|
BLAKE2b-256 checksum How to use checksums |
2070959821c229da75ba2d07cdd9e2ca6d81239d5b3e69fc5f884376e97ff810
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency logRelease files / termix_sdk-0.1.1-py3-none-any.whl
| Download URL | termix_sdk-0.1.1-py3-none-any.whl |
|---|---|
| Size | 161.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f64640269bcef36aa26aac804fbfecc97e91c220cf8df4b1eb7536897c9af881
|
|
BLAKE2b-256 checksum How to use checksums |
b0743a0479dc78db094e1d65a73f3663615bf4b77064c3a5e9056ffa74756a25
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 21, 2026.
Transparency log