kallfi-sdk 0.2.0__tar.gz

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,18 @@
1
+ node_modules/
2
+ dist/
3
+ coverage/
4
+ *.tgz
5
+ .DS_Store
6
+
7
+ python/.pytest_cache/
8
+ python/.ruff_cache/
9
+ python/.mypy_cache/
10
+ python/.venv/
11
+ python/build/
12
+ python/dist/
13
+ python/*.egg-info/
14
+ python/src/*.egg-info/
15
+ __pycache__/
16
+ *.py[cod]
17
+
18
+ .test-dist/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kallfi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.4
2
+ Name: kallfi-sdk
3
+ Version: 0.2.0
4
+ Summary: Server-side Python SDK for the Kallfi API.
5
+ Project-URL: Homepage, https://github.com/kallfi/kallfi-sdk
6
+ Project-URL: Repository, https://github.com/kallfi/kallfi-sdk.git
7
+ Project-URL: Issues, https://github.com/kallfi/kallfi-sdk/issues
8
+ Author: Kallfi
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Keywords: api,kallfi,sdk
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Typing :: Typed
19
+ Requires-Python: >=3.10
20
+ Requires-Dist: httpx<1,>=0.27
21
+ Requires-Dist: pydantic<3,>=2.9
22
+ Provides-Extra: test
23
+ Requires-Dist: build==1.2.2.post1; extra == 'test'
24
+ Requires-Dist: datamodel-code-generator==0.33.0; extra == 'test'
25
+ Requires-Dist: mypy<2,>=1.14; extra == 'test'
26
+ Requires-Dist: pytest==8.3.5; extra == 'test'
27
+ Requires-Dist: ruff<1,>=0.9; extra == 'test'
28
+ Description-Content-Type: text/markdown
29
+
30
+ # Kallfi Python SDK
31
+
32
+ Native synchronous and asynchronous Python clients for the Kallfi API. Python 3.10+.
33
+
34
+ ```sh
35
+ pip install kallfi-sdk
36
+ ```
37
+
38
+ `uv add` adds the dependency to a uv project and its lockfile. `uv pip install`
39
+ installs into the selected Python environment:
40
+
41
+ ```sh
42
+ uv add kallfi-sdk
43
+ uv pip install kallfi-sdk
44
+ ```
45
+
46
+ Install an immutable Git repository release when needed:
47
+
48
+ ```sh
49
+ pip install "kallfi-sdk @ git+https://github.com/kallfi/kallfi-sdk.git@v0.2.0#subdirectory=python"
50
+ uv add "kallfi-sdk @ git+https://github.com/kallfi/kallfi-sdk.git@v0.2.0#subdirectory=python"
51
+ uv pip install "kallfi-sdk @ git+https://github.com/kallfi/kallfi-sdk.git@v0.2.0#subdirectory=python"
52
+ ```
53
+
54
+ ```python
55
+ from kallfi import Kallfi
56
+
57
+ with Kallfi.from_env(surface="nsfw-disabled") as client:
58
+ response = client.call(
59
+ "createPost",
60
+ body={"caption": "Hello"},
61
+ idempotency_key="a-stable-key-for-this-intent",
62
+ )
63
+ print(response.status, response.data, response.request_id)
64
+ ```
65
+
66
+ The body must satisfy the operation's canonical request schema. This example
67
+ illustrates transport usage; it is not evidence that an operation is admitted.
68
+ `AsyncKallfi` exposes the same API with awaited calls and an async context manager.
69
+ Typed Pydantic request and response models are exported from `kallfi.models`.
70
+ The original typed Soul resources remain available. Operation responses now use
71
+ `operation.root.status`, because the canonical operation is a shared/surface union.
72
+
73
+ `call(operation_id, body=..., path_params=..., query=..., idempotency_key=...)`
74
+ accepts all 38 operation IDs in the bundled canonical OpenAPI snapshot. It returns
75
+ `APIResponse` containing status, parsed JSON data, request ID, Retry-After,
76
+ Location and Content-Type. Responses are bounded to 8 MiB by default; configure
77
+ `max_response_bytes` per call. HTTP errors raise `KallfiAPIError`; malformed JSON,
78
+ transport failures and timeouts have dedicated exceptions. Redirects are never
79
+ followed, including with an injected HTTP client. Mutations require an explicit
80
+ idempotency key of 1 to 128 characters and are never automatically retried. Async task cancellation
81
+ propagates normally. Configure the timeout at construction. Discovery consumes
82
+ the same timeout budget as the operation. Async calls enforce an overall
83
+ cancellation deadline. Sync calls use HTTPX phase/inactivity timeouts, pass the
84
+ remaining budget to the operation and check the deadline while consuming chunks;
85
+ they do not promise a strict wall-clock interrupt of a blocking slow stream.
86
+
87
+ The default surface is `nsfw-disabled` (`https://acr.kallfi.com`);
88
+ `nsfw-enabled` uses `https://acr.kallfi.red`. An explicit trusted origin must
89
+ agree with the surface. Custom remote origins are rejected; loopback origins
90
+ are available for local development. An injected HTTP client is caller-owned;
91
+ its base URL must match the selected surface; it must not preconfigure workspace
92
+ headers. SDK authentication and workspace headers are attached per request;
93
+ constructing clients does not mutate the shared HTTP client headers.
94
+
95
+ `workspace_id` is a fixed UUID selector sent as `X-Kallfi-Workspace-ID`.
96
+ Omit it for Personal. It is untrusted input, never an authorization grant.
97
+ Every explicit workspace read or mutation first makes a fresh, unauthenticated
98
+ same-origin `GET /v1/capabilities` request, bounded to 4096 bytes, without workspace,
99
+ idempotency or cookie
100
+ headers. HTTP 200 JSON must match the account-principal-v1 discovery protocol.
101
+ Missing, old, redirected, HTML or malformed responses raise
102
+ `WorkspaceUnsupportedError` with code `workspace_capability_unsupported` before
103
+ the operation is sent. There is no fallback to Personal and no capability cache.
104
+ Default Personal requests do not perform discovery.
105
+
106
+ Account operations reject explicit workspace selection. The server must verify
107
+ current membership, resource ownership and economy permissions. This selector
108
+ contract is prepared source, not a claim that the workspace runtime is deployed.
109
+ Credentials belong in server environments, never browser code. Media capability
110
+ URLs are not fetched automatically and API authorization is never forwarded.
111
+
112
+ ## Contract and publication
113
+
114
+ `openapi/openapi.v1.json` is the backend-owned 38-operation shared snapshot.
115
+ Its SHA256 is recorded in `src/kallfi/operations.json`; tests detect snapshot or
116
+ operation drift. `scripts/generate-models.sh` generates Pydantic models from it;
117
+ `scripts/check-models.sh` checks deterministic output.
118
+
119
+ ```sh
120
+ uv sync --all-extras --locked
121
+ uv run sh scripts/check-models.sh
122
+ uv run ruff check src tests
123
+ uv run mypy src
124
+ uv run pytest
125
+ uv build
126
+ ```
127
+
128
+ The distribution is `kallfi-sdk`; the Python import namespace remains `kallfi`.
129
+ It is MIT, maintained in
130
+ `kallfi/kallfi-sdk`. The existing GitHub workflow `publish-pypi.yml` publishes
131
+ an immutable release tag through PyPI trusted publishing, environment `pypi`.
132
+ Set repository variable `PYPI_TRUSTED_PUBLISHING_ENABLED=true` only once its
133
+ trusted publisher is configured. PyPI's pending publisher must name owner
134
+ `kallfi`, repository `kallfi-sdk`, workflow `publish-pypi.yml`, environment `pypi`,
135
+ project `kallfi-sdk`. Package version, npm version and release tag must agree.
136
+ No PyPI token is required for this path. An artifact build is not publication;
137
+ verify the public PyPI version and install its wheel after the workflow succeeds.
@@ -0,0 +1,108 @@
1
+ # Kallfi Python SDK
2
+
3
+ Native synchronous and asynchronous Python clients for the Kallfi API. Python 3.10+.
4
+
5
+ ```sh
6
+ pip install kallfi-sdk
7
+ ```
8
+
9
+ `uv add` adds the dependency to a uv project and its lockfile. `uv pip install`
10
+ installs into the selected Python environment:
11
+
12
+ ```sh
13
+ uv add kallfi-sdk
14
+ uv pip install kallfi-sdk
15
+ ```
16
+
17
+ Install an immutable Git repository release when needed:
18
+
19
+ ```sh
20
+ pip install "kallfi-sdk @ git+https://github.com/kallfi/kallfi-sdk.git@v0.2.0#subdirectory=python"
21
+ uv add "kallfi-sdk @ git+https://github.com/kallfi/kallfi-sdk.git@v0.2.0#subdirectory=python"
22
+ uv pip install "kallfi-sdk @ git+https://github.com/kallfi/kallfi-sdk.git@v0.2.0#subdirectory=python"
23
+ ```
24
+
25
+ ```python
26
+ from kallfi import Kallfi
27
+
28
+ with Kallfi.from_env(surface="nsfw-disabled") as client:
29
+ response = client.call(
30
+ "createPost",
31
+ body={"caption": "Hello"},
32
+ idempotency_key="a-stable-key-for-this-intent",
33
+ )
34
+ print(response.status, response.data, response.request_id)
35
+ ```
36
+
37
+ The body must satisfy the operation's canonical request schema. This example
38
+ illustrates transport usage; it is not evidence that an operation is admitted.
39
+ `AsyncKallfi` exposes the same API with awaited calls and an async context manager.
40
+ Typed Pydantic request and response models are exported from `kallfi.models`.
41
+ The original typed Soul resources remain available. Operation responses now use
42
+ `operation.root.status`, because the canonical operation is a shared/surface union.
43
+
44
+ `call(operation_id, body=..., path_params=..., query=..., idempotency_key=...)`
45
+ accepts all 38 operation IDs in the bundled canonical OpenAPI snapshot. It returns
46
+ `APIResponse` containing status, parsed JSON data, request ID, Retry-After,
47
+ Location and Content-Type. Responses are bounded to 8 MiB by default; configure
48
+ `max_response_bytes` per call. HTTP errors raise `KallfiAPIError`; malformed JSON,
49
+ transport failures and timeouts have dedicated exceptions. Redirects are never
50
+ followed, including with an injected HTTP client. Mutations require an explicit
51
+ idempotency key of 1 to 128 characters and are never automatically retried. Async task cancellation
52
+ propagates normally. Configure the timeout at construction. Discovery consumes
53
+ the same timeout budget as the operation. Async calls enforce an overall
54
+ cancellation deadline. Sync calls use HTTPX phase/inactivity timeouts, pass the
55
+ remaining budget to the operation and check the deadline while consuming chunks;
56
+ they do not promise a strict wall-clock interrupt of a blocking slow stream.
57
+
58
+ The default surface is `nsfw-disabled` (`https://acr.kallfi.com`);
59
+ `nsfw-enabled` uses `https://acr.kallfi.red`. An explicit trusted origin must
60
+ agree with the surface. Custom remote origins are rejected; loopback origins
61
+ are available for local development. An injected HTTP client is caller-owned;
62
+ its base URL must match the selected surface; it must not preconfigure workspace
63
+ headers. SDK authentication and workspace headers are attached per request;
64
+ constructing clients does not mutate the shared HTTP client headers.
65
+
66
+ `workspace_id` is a fixed UUID selector sent as `X-Kallfi-Workspace-ID`.
67
+ Omit it for Personal. It is untrusted input, never an authorization grant.
68
+ Every explicit workspace read or mutation first makes a fresh, unauthenticated
69
+ same-origin `GET /v1/capabilities` request, bounded to 4096 bytes, without workspace,
70
+ idempotency or cookie
71
+ headers. HTTP 200 JSON must match the account-principal-v1 discovery protocol.
72
+ Missing, old, redirected, HTML or malformed responses raise
73
+ `WorkspaceUnsupportedError` with code `workspace_capability_unsupported` before
74
+ the operation is sent. There is no fallback to Personal and no capability cache.
75
+ Default Personal requests do not perform discovery.
76
+
77
+ Account operations reject explicit workspace selection. The server must verify
78
+ current membership, resource ownership and economy permissions. This selector
79
+ contract is prepared source, not a claim that the workspace runtime is deployed.
80
+ Credentials belong in server environments, never browser code. Media capability
81
+ URLs are not fetched automatically and API authorization is never forwarded.
82
+
83
+ ## Contract and publication
84
+
85
+ `openapi/openapi.v1.json` is the backend-owned 38-operation shared snapshot.
86
+ Its SHA256 is recorded in `src/kallfi/operations.json`; tests detect snapshot or
87
+ operation drift. `scripts/generate-models.sh` generates Pydantic models from it;
88
+ `scripts/check-models.sh` checks deterministic output.
89
+
90
+ ```sh
91
+ uv sync --all-extras --locked
92
+ uv run sh scripts/check-models.sh
93
+ uv run ruff check src tests
94
+ uv run mypy src
95
+ uv run pytest
96
+ uv build
97
+ ```
98
+
99
+ The distribution is `kallfi-sdk`; the Python import namespace remains `kallfi`.
100
+ It is MIT, maintained in
101
+ `kallfi/kallfi-sdk`. The existing GitHub workflow `publish-pypi.yml` publishes
102
+ an immutable release tag through PyPI trusted publishing, environment `pypi`.
103
+ Set repository variable `PYPI_TRUSTED_PUBLISHING_ENABLED=true` only once its
104
+ trusted publisher is configured. PyPI's pending publisher must name owner
105
+ `kallfi`, repository `kallfi-sdk`, workflow `publish-pypi.yml`, environment `pypi`,
106
+ project `kallfi-sdk`. Package version, npm version and release tag must agree.
107
+ No PyPI token is required for this path. An artifact build is not publication;
108
+ verify the public PyPI version and install its wheel after the workflow succeeds.