forktex-cloud 0.2.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,59 @@
1
+ # Copyright (C) 2026 FORKTEX S.R.L.
2
+ #
3
+ # SPDX-License-Identifier: AGPL-3.0-or-later OR LicenseRef-ForkTex-Commercial
4
+ #
5
+ # This file is part of forktex-cloud.
6
+ #
7
+ # For commercial licensing -- including use in proprietary products, SaaS
8
+ # deployments, or any context where AGPL obligations cannot be met -- you
9
+ # MUST obtain a commercial license from FORKTEX S.R.L. (info@forktex.com).
10
+ #
11
+ # This program is free software: you can redistribute it and/or modify
12
+ # it under the terms of the GNU Affero General Public License as published by
13
+ # the Free Software Foundation, either version 3 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # This program is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU Affero General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU Affero General Public License
22
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
23
+
24
+ """Resolve ``${vault:KEY}`` references in environment dicts."""
25
+
26
+ from __future__ import annotations
27
+
28
+ import re
29
+ from typing import Any
30
+
31
+ from forktex_cloud.secrets.base import SecretsProvider
32
+
33
+ _VAULT_PATTERN = re.compile(r"\$\{vault:([^}]+)\}")
34
+
35
+
36
+ def has_vault_references(env_dict: dict[str, Any]) -> bool:
37
+ """Return True if any value contains a ``${vault:...}`` reference."""
38
+ for v in env_dict.values():
39
+ if isinstance(v, str) and _VAULT_PATTERN.search(v):
40
+ return True
41
+ return False
42
+
43
+
44
+ def resolve_secrets(
45
+ env_dict: dict[str, Any],
46
+ provider: SecretsProvider,
47
+ env: str = "default",
48
+ ) -> dict[str, Any]:
49
+ """Replace ``${vault:KEY}`` references with actual secret values."""
50
+ resolved: dict[str, Any] = {}
51
+ for k, v in env_dict.items():
52
+ if isinstance(v, str) and _VAULT_PATTERN.search(v):
53
+ resolved[k] = _VAULT_PATTERN.sub(
54
+ lambda m: provider.get(m.group(1), env),
55
+ v,
56
+ )
57
+ else:
58
+ resolved[k] = v
59
+ return resolved
@@ -0,0 +1,55 @@
1
+ # Copyright (C) 2026 FORKTEX S.R.L.
2
+ #
3
+ # SPDX-License-Identifier: AGPL-3.0-or-later OR LicenseRef-ForkTex-Commercial
4
+ #
5
+ # This file is part of forktex-cloud.
6
+ #
7
+ # For commercial licensing -- including use in proprietary products, SaaS
8
+ # deployments, or any context where AGPL obligations cannot be met -- you
9
+ # MUST obtain a commercial license from FORKTEX S.R.L. (info@forktex.com).
10
+ #
11
+ # This program is free software: you can redistribute it and/or modify
12
+ # it under the terms of the GNU Affero General Public License as published by
13
+ # the Free Software Foundation, either version 3 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # This program is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU Affero General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU Affero General Public License
22
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
23
+
24
+ auth_enabled: false
25
+
26
+ server:
27
+ http_listen_port: 3100
28
+
29
+ common:
30
+ path_prefix: /loki
31
+ storage:
32
+ filesystem:
33
+ chunks_directory: /loki/chunks
34
+ rules_directory: /loki/rules
35
+ replication_factor: 1
36
+ ring:
37
+ kvstore:
38
+ store: inmemory
39
+
40
+ schema_config:
41
+ configs:
42
+ - from: "2020-10-24"
43
+ store: tsdb
44
+ object_store: filesystem
45
+ schema: v13
46
+ index:
47
+ prefix: index_
48
+ period: 24h
49
+
50
+ limits_config:
51
+ reject_old_samples: true
52
+ reject_old_samples_max_age: 168h
53
+
54
+ analytics:
55
+ reporting_enabled: false
@@ -0,0 +1,46 @@
1
+ # Copyright (C) 2026 FORKTEX S.R.L.
2
+ #
3
+ # SPDX-License-Identifier: AGPL-3.0-or-later OR LicenseRef-ForkTex-Commercial
4
+ #
5
+ # This file is part of forktex-cloud.
6
+ #
7
+ # For commercial licensing -- including use in proprietary products, SaaS
8
+ # deployments, or any context where AGPL obligations cannot be met -- you
9
+ # MUST obtain a commercial license from FORKTEX S.R.L. (info@forktex.com).
10
+ #
11
+ # This program is free software: you can redistribute it and/or modify
12
+ # it under the terms of the GNU Affero General Public License as published by
13
+ # the Free Software Foundation, either version 3 of the License, or
14
+ # (at your option) any later version.
15
+ #
16
+ # This program is distributed in the hope that it will be useful,
17
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ # GNU Affero General Public License for more details.
20
+ #
21
+ # You should have received a copy of the GNU Affero General Public License
22
+ # along with this program. If not, see <https://www.gnu.org/licenses/>.
23
+
24
+ server:
25
+ http_listen_port: 9080
26
+ grpc_listen_port: 0
27
+
28
+ positions:
29
+ filename: /tmp/positions.yaml
30
+
31
+ clients:
32
+ - url: http://loki:3100/loki/api/v1/push
33
+
34
+ scrape_configs:
35
+ - job_name: docker
36
+ docker_sd_configs:
37
+ - host: unix:///var/run/docker.sock
38
+ refresh_interval: 5s
39
+ relabel_configs:
40
+ - source_labels: ["__meta_docker_container_name"]
41
+ regex: "/(.*)"
42
+ target_label: "container"
43
+ - source_labels: ["__meta_docker_container_log_stream"]
44
+ target_label: "logstream"
45
+ - source_labels: ["__meta_docker_container_label_com_docker_compose_service"]
46
+ target_label: "service"
@@ -0,0 +1,226 @@
1
+ Metadata-Version: 2.4
2
+ Name: forktex-cloud
3
+ Version: 0.2.3
4
+ Summary: Typed Python SDK for the ForkTex Cloud platform — provision, deploy, and manage VPS-backed apps via a declarative manifest.
5
+ License-Expression: AGPL-3.0-only
6
+ License-File: LICENSE
7
+ License-File: NOTICE
8
+ Keywords: forktex,cloud,deployment,vps,hetzner,ansible,blue-green,iac,infrastructure-as-code,sdk
9
+ Author: FORKTEX
10
+ Author-email: info@forktex.com
11
+ Requires-Python: >=3.12
12
+ Classifier: Development Status :: 5 - Production/Stable
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3 :: Only
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Programming Language :: Python :: 3.14
21
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
+ Classifier: Topic :: System :: Distributed Computing
23
+ Classifier: Topic :: System :: Installation/Setup
24
+ Classifier: Topic :: System :: Systems Administration
25
+ Classifier: Typing :: Typed
26
+ Requires-Dist: cryptography (>=42.0)
27
+ Requires-Dist: httpx (>=0.27.0,<1.0.0)
28
+ Requires-Dist: pydantic[email] (>=2.11.10,<3.0.0)
29
+ Requires-Dist: pyyaml (>=6.0)
30
+ Project-URL: Changelog, https://github.com/forktex/cloud/blob/master/sdk-py/CHANGELOG.md
31
+ Project-URL: Documentation, https://github.com/forktex/cloud/tree/master/docs
32
+ Project-URL: Homepage, https://forktex.com
33
+ Project-URL: Issues, https://github.com/forktex/cloud/issues
34
+ Project-URL: Repository, https://github.com/forktex/cloud
35
+ Description-Content-Type: text/markdown
36
+
37
+ # forktex-cloud
38
+
39
+ [![PyPI](https://img.shields.io/pypi/v/forktex-cloud.svg)](https://pypi.org/project/forktex-cloud/)
40
+ [![Python](https://img.shields.io/pypi/pyversions/forktex-cloud.svg)](https://pypi.org/project/forktex-cloud/)
41
+ [![License](https://img.shields.io/pypi/l/forktex-cloud.svg)](https://github.com/forktex/cloud/blob/master/sdk-py/LICENSE)
42
+
43
+ Standalone Python SDK for the [ForkTex Cloud](https://cloud.forktex.com) platform.
44
+
45
+ `forktex-cloud` is the typed `httpx` client + manifest plumbing that the `forktex` CLI uses to talk to the ForkTex Cloud control plane: project provisioning, server management, deployments, vault, manifest validation, and the docker-compose / Hetzner / Ansible bridge.
46
+
47
+ You can use it directly from any Python application — no `forktex` CLI required.
48
+
49
+ ## Install
50
+
51
+ ```bash
52
+ pip install forktex-cloud
53
+ ```
54
+
55
+ **Requires Python 3.12+.** Tested on 3.12, 3.13, 3.14.
56
+
57
+ ## Quick Start
58
+
59
+ ### Authenticated client
60
+
61
+ ```python
62
+ from forktex_cloud import ForktexCloudClient, CloudContext
63
+
64
+ ctx = CloudContext(controller="https://cloud.forktex.com", account_key="ftx-...")
65
+ with ForktexCloudClient.from_context(ctx) as client:
66
+ projects = client.list_projects()
67
+ servers = client.list_servers()
68
+ health = client.health()
69
+ ```
70
+
71
+ ### Direct auth
72
+
73
+ ```python
74
+ from forktex_cloud import ForktexCloudClient
75
+
76
+ # JWT bearer (user login)
77
+ with ForktexCloudClient("https://cloud.forktex.com", access_token="eyJ...") as client:
78
+ me = client.me()
79
+
80
+ # Org-scoped API key (CI/CD)
81
+ with ForktexCloudClient(
82
+ "https://cloud.forktex.com",
83
+ account_key="ftx-...",
84
+ org_id="00000000-0000-0000-0000-000000000001",
85
+ ) as client:
86
+ events = client.list_events(project_id="...")
87
+ status = client.server_status("server-uuid")
88
+ ```
89
+
90
+ ### Local dev (point at your `make local` stack)
91
+
92
+ ```python
93
+ client = ForktexCloudClient(
94
+ base_url="http://localhost:8000",
95
+ account_key="ftx-dev-key-2026",
96
+ org_id="<your-org-uuid>",
97
+ )
98
+ ```
99
+
100
+ ### Trigger a deploy pipeline
101
+
102
+ ```python
103
+ # Full up (provision + bootstrap + deploy + DNS + SSL)
104
+ job = client.up(project_dir=Path("./my-project")) # reads forktex.json
105
+ print(job.job_id, job.deployment_id, job.status)
106
+
107
+ # Code push to an existing server (no re-provision)
108
+ job = client.deploy(server_id="...", service="api") # Ansible deploy tag
109
+
110
+ # Tear down
111
+ job = client.down(keep_dns=True) # preserves DNS record
112
+ ```
113
+
114
+ ### Manifest loading + validation
115
+
116
+ ```python
117
+ from forktex_cloud import Manifest, ManifestError
118
+
119
+ # Validates eagerly against the canonical Pydantic schema at construction
120
+ try:
121
+ m = Manifest.load("forktex.json", env="production")
122
+ except ManifestError as e:
123
+ print(f"Invalid manifest: {e}")
124
+ raise
125
+
126
+ # Typed access to the cloud block (discriminated union over all 4 kinds)
127
+ print(m.cloud.kind) # "ProjectDeployment" | "StaticSite" | ...
128
+ print(m.cloud.metadata.name)
129
+ for svc in m.services_for_env(env="production"):
130
+ print(svc.id, svc.type, svc.image)
131
+
132
+ # Wire format round-trips cleanly (model_dump → parse_cloud_block)
133
+ as_dict = m.cloud.model_dump(by_alias=True, exclude_none=True)
134
+ ```
135
+
136
+ ### Secrets vault (server-side, org-scoped)
137
+
138
+ ```python
139
+ client.vault_set("POSTGRES_PASSWORD", "hunter2")
140
+ secret = client.vault_get("POSTGRES_PASSWORD") # -> VaultGetResponse
141
+ keys = client.vault_list() # -> list[str]
142
+ client.vault_delete("POSTGRES_PASSWORD")
143
+ ```
144
+
145
+ ## What's in the package
146
+
147
+ | Module | Purpose |
148
+ |---|---|
149
+ | `forktex_cloud.client` | Typed sync httpx client (`ForktexCloudClient`) + all OpenAPI-codegenned Pydantic models (`ServerRead`, `ProjectRead`, `EventRead`, `VaultGetResponse`, ...) |
150
+ | `forktex_cloud.manifest` | `Manifest` loader, discriminated-union schema (v1beta2), deep-merge for env overlays, `ManifestError` |
151
+ | `forktex_cloud.config` | `CloudContext` — controller URL, JWT / account-key, current org + project keys |
152
+ | `forktex_cloud.scaffold` | `forktex cloud init` template generator (ProjectDeployment / StaticSite / SingleContainer / NativeBuild) |
153
+ | `forktex_cloud.bridge` | docker-compose generator (local mode), Loki config, log formatters used by `forktex cloud up --env local` |
154
+ | `forktex_cloud.secrets` | Fernet vault + `${vault:KEY}` resolver for compile-time secret injection |
155
+ | `forktex_cloud.paths` | Cross-platform `.forktex/` + `~/.forktex/` filesystem spec (V1). See [docs/forktex-directory-spec.md](https://github.com/forktex/cloud/blob/master/docs/forktex-directory-spec.md) |
156
+
157
+ 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.
158
+
159
+ ## Top-level re-exports
160
+
161
+ ```python
162
+ from forktex_cloud import (
163
+ # Client
164
+ ForktexCloudClient, CloudAPIError,
165
+ # Config
166
+ CloudContext,
167
+ # Manifest
168
+ Manifest, ManifestError,
169
+ # Response models (from OpenAPI codegen)
170
+ ApiKeyCreated, ApiKeyRead,
171
+ EnvironmentRead, EventRead,
172
+ HealthRead, JobResponse, MeResponse,
173
+ OrgRead, ProjectRead, ServerRead, UserRead,
174
+ StatusResponse, TokenResponse, VaultGetResponse,
175
+ WorkspaceRead,
176
+ )
177
+ ```
178
+
179
+ ## Versioning
180
+
181
+ The SDK follows [SemVer](https://semver.org/). 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.
182
+
183
+ ## Repository
184
+
185
+ This SDK lives inside the [`forktex/cloud`](https://github.com/forktex/cloud) monorepo alongside the API server (`api/`) and React Native client (`client/`). The SDK package is independently versioned and published to PyPI.
186
+
187
+ - Docs: [https://github.com/forktex/cloud/tree/master/docs](https://github.com/forktex/cloud/tree/master/docs)
188
+ - Production runbook: [production-runbook.md](https://github.com/forktex/cloud/blob/master/docs/production-runbook.md)
189
+ - Issues: [https://github.com/forktex/cloud/issues](https://github.com/forktex/cloud/issues)
190
+
191
+ ## Development
192
+
193
+ The [`Makefile`](Makefile) is generated by `forktex fsd makefile sync` from [`forktex.json`](forktex.json) — do not hand-edit.
194
+
195
+ ```bash
196
+ make help # list every available target
197
+ make deps # editable install with the dev group
198
+ make format # ruff format
199
+ make lint # ruff check
200
+ make test # pytest tests/
201
+ make codegen-check # verify the generated client imports cleanly
202
+ make build # python3 -m build → dist/
203
+ make ci # format-check + lint + license-check + audit + test + build
204
+ make clean # remove caches and dist/
205
+ ```
206
+
207
+ `make ci` is the single command that gates a publish: format-check, lint, dual-license header check, dependency CVE audit, full test suite, and `python -m build` + `twine check`.
208
+
209
+ ### License headers
210
+
211
+ Every source file carries the AGPL-3.0 + Commercial dual-license SPDX header, applied idempotently via:
212
+
213
+ ```bash
214
+ make license-check # CI gate — fails if any source file is missing the header
215
+ make license-fix # add or refresh headers across src/, tests/, scripts/
216
+ make license-strip # remove headers (used before license-model changes)
217
+ ```
218
+
219
+ ## License
220
+
221
+ Dual-licensed — **AGPL-3.0-or-later** for open-source use, **commercial** for everything else (proprietary products, SaaS without source release, redistribution in closed-source form). See [`LICENSE`](LICENSE) and [`NOTICE`](NOTICE) for the full terms.
222
+
223
+ Commercial licensing inquiries: info@forktex.com.
224
+
225
+ The 1.0.x releases on PyPI remain under MIT; from **0.2.3** onwards the package ships AGPL-3.0+Commercial.
226
+
@@ -0,0 +1,30 @@
1
+ forktex_cloud/__init__.py,sha256=NUmtssYqSXwQmsEiM-q8BhZvVqYb1hYJL9Tcmmt4j2A,2651
2
+ forktex_cloud/bridge/__init__.py,sha256=R7xeSF6i0kjFuHokArxVblTy3_QPFyAsJXXWdPcR04M,1102
3
+ forktex_cloud/bridge/local_compose.py,sha256=-6w_QIsEc47fPZvSp3lEmguclyDKtePpZQfNDwlmMRs,10453
4
+ forktex_cloud/bridge/log_formatter.py,sha256=0wnHNH5JFmofR-xqAaBQJmRLIov2_O3lykAwnuA8IjE,2059
5
+ forktex_cloud/bridge/loki.py,sha256=cYL76e0SqpoI7X9YpvZwMehKbFFSfy_gzwNWqt8z0uQ,3744
6
+ forktex_cloud/bridge/persistence_defaults.py,sha256=hAMTg-gZlcogqNmJSzRVEwHCav4nzFUKaCnWhoXbPcQ,3862
7
+ forktex_cloud/client/__init__.py,sha256=ryD26sslNjop3bYCDjvy_nfXPDBq44FU2OKI1joZvQA,2392
8
+ forktex_cloud/client/client.py,sha256=Zc7FEP5rXD1fujIZ9GcssDBmkIPjLj7VeX-BFN-QS8A,22398
9
+ forktex_cloud/client/generated/__init__.py,sha256=u-SpzKCvUigI0CCc0iBXlevZOfBdcU4TDDv8uXGy4mA,38276
10
+ forktex_cloud/config.py,sha256=oeOFV0rPkMrDNiVEli-zP8gurjlvpWRJ9Ump7NEonzs,2426
11
+ forktex_cloud/manifest/__init__.py,sha256=zHW86vpxfBUPVEmQ9HbxkR5Xa4mjPdVtJrd9CVUDlTo,2100
12
+ forktex_cloud/manifest/errors.py,sha256=2qXugnSZRyhVLeBFKCmm55mMxtVTCbfBKcfvffgAl6o,1331
13
+ forktex_cloud/manifest/loader.py,sha256=AjZwSKMntiuXGfONosUAOd3lbwYxCLt36ht01qkvXBU,9929
14
+ forktex_cloud/manifest/merge.py,sha256=alBUVw7q1X4bbya1QzBaD1Y3BZuaBbgXpz_NvaWL8M4,2013
15
+ forktex_cloud/manifest/schema.py,sha256=05x-xfrH-vqGitmJD2VskXCl11YdJ7nQpyKhVkWHO-A,3171
16
+ forktex_cloud/paths.py,sha256=nuxr5fA-He-JyzSY3PM9P963gdPljCtMZMA1__De990,8801
17
+ forktex_cloud/scaffold/__init__.py,sha256=OpSAWLLho9D5TARs5q4k9hvswsUSp9oerFWbh5xkT3Q,1075
18
+ forktex_cloud/scaffold/templates.py,sha256=zhmnlBkePisYp5q8w5kwmcZ5YpdicbdI-2BpiiNs460,4417
19
+ forktex_cloud/secrets/__init__.py,sha256=ibv-l7jDTFgnzHknxNfvHo3vPHhjXz0PiKa0yRcVywU,1126
20
+ forktex_cloud/secrets/base.py,sha256=G91FYUMlZCR5UCm2ql7zo0gGeWfi8RJh3NPziDsyo_I,1790
21
+ forktex_cloud/secrets/factory.py,sha256=a8RYMxgtmtIalevZRnxKmBVZh3ELoreXdL3lFXnKfOI,2023
22
+ forktex_cloud/secrets/fernet.py,sha256=jNZVKZWnHoVxk8FVf87rYq6niNRAfpOOeIbGnS3AYBU,3446
23
+ forktex_cloud/secrets/resolver.py,sha256=VsByVtlqfxOnPshhrJKS3kiESAiF8VwHHTGRjy9tPIs,2080
24
+ forktex_cloud/templates/observability/loki.yml,sha256=2qQkdZP0Z9VVbqdBDEvTJ3GRNFDLTi5Z8YRspLdpSq4,1580
25
+ forktex_cloud/templates/observability/promtail.yml,sha256=6em4DEU6K8KYttF89nzB8NyedEkoJKkb3mHCC0AiWog,1668
26
+ forktex_cloud-0.2.3.dist-info/METADATA,sha256=PBX5pCPWKSCDSvzRuLejTR6c4wA4FTxGJgRJZk6B85c,9313
27
+ forktex_cloud-0.2.3.dist-info/WHEEL,sha256=Vz2fHgx6HFtSwhs8KvkHLqH5Ea4w1_rner5uNVGCeIE,88
28
+ forktex_cloud-0.2.3.dist-info/licenses/LICENSE,sha256=kz6KCanl6TKXrtl40HZqVKvTjyNx74uE01UMd0K4dRs,1921
29
+ forktex_cloud-0.2.3.dist-info/licenses/NOTICE,sha256=NGffqf9xgVbrPpPb5_V3fpm6CM0MdlPJE2XDcNXE05E,1076
30
+ forktex_cloud-0.2.3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: poetry-core 2.3.2
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,45 @@
1
+ forktex-cloud -- Dual License
2
+
3
+ Copyright (C) 2026 FORKTEX S.R.L.
4
+
5
+ This software is licensed under a dual-license model:
6
+
7
+ ============================================================================
8
+
9
+ 1. OPEN-SOURCE LICENSE -- GNU Affero General Public License v3.0 (AGPL-3.0)
10
+
11
+ You may use, modify, and redistribute this software under the terms of the
12
+ GNU Affero General Public License v3.0 or later, as published by the Free
13
+ Software Foundation. The full license text is available at:
14
+ https://www.gnu.org/licenses/agpl-3.0.html
15
+
16
+ Key obligations under AGPL-3.0:
17
+ - Any modified version MUST be released under the same AGPL-3.0 license.
18
+ - If you run a modified version on a server and let users interact with it
19
+ over a network, you MUST make the complete source code available to those
20
+ users under AGPL-3.0.
21
+ - You MUST preserve all copyright notices and attribution to FORKTEX S.R.L.
22
+
23
+ ============================================================================
24
+
25
+ 2. COMMERCIAL LICENSE
26
+
27
+ If you wish to use this software without the obligations of AGPL-3.0 --
28
+ for example, to keep your modifications proprietary, to embed this software
29
+ in a closed-source product, or to operate it as part of a commercial service
30
+ without releasing your source code -- you MUST obtain a commercial license
31
+ from FORKTEX S.R.L.
32
+
33
+ Commercial licensing includes, but is not limited to:
34
+ - SaaS / hosted deployments generating revenue
35
+ - Embedding in proprietary products or platforms
36
+ - Redistribution in closed-source form
37
+ - Use by organizations exceeding the AGPL-3.0 compliance scope
38
+
39
+ For commercial licensing inquiries, contact:
40
+ info@forktex.com
41
+
42
+ ============================================================================
43
+
44
+ Unless you have obtained a separate commercial license from FORKTEX S.R.L.,
45
+ your use of this software is governed exclusively by the AGPL-3.0 license.
@@ -0,0 +1,23 @@
1
+ forktex-cloud
2
+ Copyright (C) 2026 FORKTEX S.R.L.
3
+
4
+ forktex-cloud is the standalone Python SDK for the ForkTex Cloud platform.
5
+ It provides the typed httpx-based client and Pydantic models for provisioning
6
+ servers, deploying projects, managing static sites, single-container apps and
7
+ native builds, vault secrets, blue-green rollouts, and the declarative
8
+ forktex.json cloud manifest.
9
+
10
+ This program is free software: you can redistribute it and/or modify
11
+ it under the terms of the GNU Affero General Public License as published by
12
+ the Free Software Foundation, either version 3 of the License, or
13
+ (at your option) any later version.
14
+
15
+ This program is distributed in the hope that it will be useful,
16
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ GNU Affero General Public License for more details.
19
+
20
+ You should have received a copy of the GNU Affero General Public License
21
+ along with this program. If not, see <https://www.gnu.org/licenses/>.
22
+
23
+ For commercial licensing inquiries, contact: info@forktex.com