forktex-cloud
Standalone Python SDK for the ForkTex Cloud platform.
forktex-cloud is the typed httpx client + manifest plumbing for the ForkTex Cloud control plane: project provisioning, server management, deployments, vault, manifest validation, and the docker-compose / Hetzner / Ansible bridge. It was the library behind the retired forktex cloud … CLI; today it is used directly from Python applications, the platform's own runner, and CI.
Install
pip install forktex-cloud
Requires Python ≥ 3.14 (requires-python = ">=3.14,<4.0").
Quick Start
Authenticated client
from forktex_cloud import Cloud, CloudContext
ctx = CloudContext(controller="https://cloud.forktex.com", account_key="ftx-...")
with Cloud.from_context(ctx) as client:
projects = client.list_projects()
servers = client.list_servers()
health = client.health()
Direct auth
from forktex_cloud import Cloud
# JWT bearer (user login)
with Cloud("https://cloud.forktex.com", access_token="eyJ...") as client:
me = client.me()
# Org-scoped API key (CI/CD)
with Cloud(
"https://cloud.forktex.com",
account_key="ftx-...",
org_id="00000000-0000-0000-0000-000000000001",
) as client:
events = client.list_events(project_id="...")
status = client.server_status("server-uuid")
Local dev (point at your make local stack)
client = Cloud(
base_url="http://localhost:8000",
account_key="ftx-dev-key-2026",
org_id="<your-org-uuid>",
)
For integration tests or proxying through a mock/live transport, pass the
optional `transport=` argument to `Cloud(...)` and provide any `httpx`
transport implementation.
Trigger a deploy pipeline
# Preview what an apply WOULD do (read-only, no mutation):
plan = client.plan(project_dir=Path("./my-project"), env="production")
print(plan.manifest_diff) # added / removed / changed paths
for role in plan.ansible_plan:
print(f" {role.role}: {role.changed} changed, {role.failed} failed")
for d in role.diffs:
print(f" {d.task}: {d.before_header}") # file-level diff hints
# Full apply (provision + bootstrap + deploy + DNS + SSL)
job = client.apply(project_dir=Path("./my-project")) # reads forktex.json
print(job.job_id, job.deployment_id, job.status)
# Code push to an existing server (no re-provision)
job = client.deploy(server_id="...", service="api") # Ansible deploy tag
# Tear down
job = client.destroy(keep_dns=True) # preserves DNS record
Manifest loading + validation
from forktex_cloud import Manifest, ManifestError
# Validates eagerly against the canonical Pydantic schema at construction
try:
m = Manifest.load("forktex.json", env="production")
except ManifestError as e:
print(f"Invalid manifest: {e}")
raise
# Typed access to the cloud block (discriminated union over all 4 kinds)
print(m.cloud.kind) # "ProjectDeployment" | "StaticSite" | ...
print(m.cloud.metadata.name)
for svc in m.services_for_env(env="production"):
print(svc.id, svc.type, svc.image)
# Wire format round-trips cleanly (model_dump → parse_cloud_block)
as_dict = m.cloud.model_dump(by_alias=True, exclude_none=True)
Secrets vault (server-side, org-scoped)
client.vault_set("POSTGRES_PASSWORD", "hunter2")
secret = client.vault_get("POSTGRES_PASSWORD") # -> VaultGetResponse
keys = client.vault_list() # -> list[str]
client.vault_delete("POSTGRES_PASSWORD")
What's in the package
| Module | Purpose |
|---|---|
forktex_cloud.client |
Typed sync httpx client (Cloud) + all OpenAPI-codegenned Pydantic models (ServerRead, ProjectRead, EventRead, VaultGetResponse, ...) |
forktex_cloud.manifest |
Manifest loader, discriminated-union schema (v1), deep-merge for env overlays, ManifestError |
forktex_cloud.config |
CloudContext — controller URL, JWT / account-key, current org + project keys |
forktex_cloud.scaffold |
forktex.json template generator (formerly driven by the retired forktex cloud init CLI) |
forktex_cloud.bridge |
docker-compose generator (local mode: local_compose_from_manifest, used by the repo's scripts/local_stack.py / make start; formerly by the retired forktex cloud apply --env local CLI), Loki config, log formatters |
forktex_cloud.secrets |
Fernet vault + ${vault:KEY} resolver for compile-time secret injection |
forktex_cloud.paths |
Cross-platform .forktex/ + ~/.forktex/ filesystem spec (V1). See docs/forktex-directory-spec.md |
All response models come from the OpenAPI codegen pipeline — one source of truth shared between the server and every consumer. No hand-written model drift.
Top-level re-exports
from forktex_cloud import (
# Client
Cloud, CloudAPIError,
# Config
CloudContext,
# Manifest
Manifest, ManifestError,
# Response models (from OpenAPI codegen)
ApiKeyCreated, ApiKeyRead,
EnvironmentRead, EventRead,
HealthRead, JobResponse, MeResponse,
OrgRead, ProjectRead, ServerRead, UserRead,
StatusResponse, TokenResponse, VaultGetResponse,
WorkspaceRead,
)
Versioning
The SDK follows SemVer. The client's response models are generated from the server's OpenAPI spec at a fixed SPEC_VERSION + SPEC_HASH (inspectable at runtime via forktex_cloud.client.generated.SPEC_VERSION). When the server OpenAPI changes, the SDK is regenerated and released with a bumped version.
Repository
This SDK lives inside the forktex/cloud monorepo alongside the API server (api/) and React Native client (client/). The SDK package is independently versioned and published to PyPI.
- Docs: https://github.com/forktex/cloud/tree/master/docs
- Operations guide: operations.md
- Issues: https://github.com/forktex/cloud/issues
License
MIT — see LICENSE.
Metadata
Release files for forktex-cloud 2.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| forktex_cloud-2.3.0.tar.gz | 60.2 kB | Without provenance | Details for forktex_cloud-2.3.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| forktex_cloud-2.3.0-py3-none-any.whl | Python 3 | none | any | Details for forktex_cloud-2.3.0-py3-none-any.whl |
Total release size: 128.3 kB
Release files / forktex_cloud-2.3.0.tar.gz
| Download URL | forktex_cloud-2.3.0.tar.gz |
|---|---|
| Size | 60.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
072917e294b33fcc15daf863be655413a1f321cb3e208f8026ced62ffb2faf09
|
|
BLAKE2b-256 checksum How to use checksums |
a62415a9b53afef6068c4eec013721db2190dbc5cc787576b901b26556492ffc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Release files / forktex_cloud-2.3.0-py3-none-any.whl
| Download URL | forktex_cloud-2.3.0-py3-none-any.whl |
|---|---|
| Size | 68.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
00ca563d47ff2b9ad3b3930f2244c875a4f04ffe4a8b533ca59a7bffbc96e942
|
|
BLAKE2b-256 checksum How to use checksums |
3e479791e40ac4e02eea8f76f4fbcf8e11bd791895bacebba3e77df4b7f22316
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.2
|
Security for forktex-cloud 2.3.0
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.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.