relayfile-sdk 0.2.1__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.
- relayfile_sdk-0.2.1/.gitignore +77 -0
- relayfile_sdk-0.2.1/AGENTS.md +12 -0
- relayfile_sdk-0.2.1/PKG-INFO +85 -0
- relayfile_sdk-0.2.1/README.md +71 -0
- relayfile_sdk-0.2.1/pyproject.toml +21 -0
- relayfile_sdk-0.2.1/src/relayfile/__init__.py +78 -0
- relayfile_sdk-0.2.1/src/relayfile/client.py +1644 -0
- relayfile_sdk-0.2.1/src/relayfile/errors.py +37 -0
- relayfile_sdk-0.2.1/src/relayfile/on_write.py +456 -0
- relayfile_sdk-0.2.1/src/relayfile/provider.py +202 -0
- relayfile_sdk-0.2.1/src/relayfile/types.py +860 -0
- relayfile_sdk-0.2.1/tests/test_client.py +1051 -0
- relayfile_sdk-0.2.1/tests/test_on_write.py +376 -0
- relayfile_sdk-0.2.1/tests/test_provider.py +84 -0
- relayfile_sdk-0.2.1/tests/test_types.py +176 -0
- relayfile_sdk-0.2.1/uv.lock +280 -0
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# Go
|
|
2
|
+
*.exe
|
|
3
|
+
*.exe~
|
|
4
|
+
*.dll
|
|
5
|
+
*.so
|
|
6
|
+
*.dylib
|
|
7
|
+
*.test
|
|
8
|
+
*.out
|
|
9
|
+
.gocache/
|
|
10
|
+
|
|
11
|
+
# State files
|
|
12
|
+
*.state.json
|
|
13
|
+
*.state.json.tmp
|
|
14
|
+
|
|
15
|
+
# IDE
|
|
16
|
+
.idea/
|
|
17
|
+
.vscode/
|
|
18
|
+
*.swp
|
|
19
|
+
*.swo
|
|
20
|
+
|
|
21
|
+
# OS
|
|
22
|
+
.DS_Store
|
|
23
|
+
Thumbs.db
|
|
24
|
+
|
|
25
|
+
.agent-relay/
|
|
26
|
+
.relay/
|
|
27
|
+
.relayfile/evals/runs/
|
|
28
|
+
evals/suites/*/cases.jsonl
|
|
29
|
+
|
|
30
|
+
# Node (SDK)
|
|
31
|
+
node_modules/
|
|
32
|
+
.npm-cache/
|
|
33
|
+
dist/
|
|
34
|
+
*.tsbuildinfo
|
|
35
|
+
|
|
36
|
+
# Python
|
|
37
|
+
__pycache__/
|
|
38
|
+
*.pyc
|
|
39
|
+
*.egg-info/
|
|
40
|
+
.pytest_cache/
|
|
41
|
+
|
|
42
|
+
# Environment
|
|
43
|
+
.env
|
|
44
|
+
.env.*
|
|
45
|
+
|
|
46
|
+
# Local mount mirror
|
|
47
|
+
/.livefs/
|
|
48
|
+
|
|
49
|
+
# Compiled binaries
|
|
50
|
+
bin/
|
|
51
|
+
/relayfile
|
|
52
|
+
/relayfile-cli
|
|
53
|
+
/relayfile-mount
|
|
54
|
+
/relayfile-server
|
|
55
|
+
|
|
56
|
+
# Mount platform packages: keep the skeleton (package.json/README/bin/.gitkeep)
|
|
57
|
+
# tracked, but never commit the prebuilt binary copied in at release time.
|
|
58
|
+
# (The blanket `bin/` rule above would otherwise ignore these dirs entirely.)
|
|
59
|
+
!packages/mount-*/bin/
|
|
60
|
+
!packages/mount-*/bin/.gitkeep
|
|
61
|
+
packages/mount-*/bin/relayfile-mount
|
|
62
|
+
|
|
63
|
+
# Agent tool configs
|
|
64
|
+
.factory/
|
|
65
|
+
.gemini/
|
|
66
|
+
.mcp.json
|
|
67
|
+
opencode.json
|
|
68
|
+
site/node_modules/
|
|
69
|
+
site/dist/
|
|
70
|
+
|
|
71
|
+
# observer
|
|
72
|
+
.next/
|
|
73
|
+
packages/file-observer/out/
|
|
74
|
+
packages/agents/dist
|
|
75
|
+
.scratch/
|
|
76
|
+
.agentworkforce/
|
|
77
|
+
packages/**/.claude/
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Python SDK
|
|
2
|
+
|
|
3
|
+
Keep the Python SDK idiomatic and in parity with the TypeScript surface.
|
|
4
|
+
|
|
5
|
+
- Prefer snake_case names for Python-specific APIs; only keep camelCase when mirroring HTTP JSON keys from the wire format.
|
|
6
|
+
- Re-export public SDK symbols from `src/relayfile/__init__.py` whenever you add or remove client types, errors, or provider helpers.
|
|
7
|
+
- Maintain both sync and async client behavior when adding endpoints or retry/error handling.
|
|
8
|
+
- Test HTTP behavior with `pytest`, `pytest-asyncio`, `respx`, and `httpx.Response` mocks under `tests/`.
|
|
9
|
+
- Verify with `pytest packages/sdk/python/tests`.
|
|
10
|
+
- Workspace primitive SDK changes should remain additive: mirror the TypeScript
|
|
11
|
+
type surface, expose path helpers for digest/layout/schema virtual files, and
|
|
12
|
+
avoid adding client methods until the HTTP OpenAPI contract exists.
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: relayfile-sdk
|
|
3
|
+
Version: 0.2.1
|
|
4
|
+
Summary: Python SDK for the RelayFile virtual filesystem API
|
|
5
|
+
License-Expression: Apache-2.0
|
|
6
|
+
Requires-Python: >=3.10
|
|
7
|
+
Requires-Dist: httpx<1,>=0.27
|
|
8
|
+
Requires-Dist: websocket-client<2,>=1.7
|
|
9
|
+
Provides-Extra: dev
|
|
10
|
+
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
|
|
11
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
12
|
+
Requires-Dist: respx>=0.22; extra == 'dev'
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# relayfile
|
|
16
|
+
|
|
17
|
+
Python SDK for the RelayFile virtual filesystem API.
|
|
18
|
+
|
|
19
|
+
## Install
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install relayfile-sdk
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
The import namespace remains `relayfile`.
|
|
26
|
+
|
|
27
|
+
## Workspace Primitives (M1)
|
|
28
|
+
|
|
29
|
+
The SDK exposes the workspace primitive paths and data shapes used by digest,
|
|
30
|
+
layout, schema, and writeback tooling.
|
|
31
|
+
|
|
32
|
+
```python
|
|
33
|
+
from relayfile import (
|
|
34
|
+
DIGEST_PATHS,
|
|
35
|
+
RelayFileClient,
|
|
36
|
+
is_digest_path,
|
|
37
|
+
provider_layout_path,
|
|
38
|
+
resource_schema_path,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
client = RelayFileClient("https://api.relayfile.dev", token_provider)
|
|
42
|
+
|
|
43
|
+
# DIGEST_PATHS is the literal anchor-path taxonomy: the rolling daily
|
|
44
|
+
# files plus rolling and closing-window weekly files. Closed-window daily
|
|
45
|
+
# artifacts use the date-stamped form ``digests/YYYY-MM-DD.md``; filter
|
|
46
|
+
# events through ``is_digest_path`` to subscribe to the full taxonomy
|
|
47
|
+
# (anchor paths plus date-stamped form).
|
|
48
|
+
print(DIGEST_PATHS)
|
|
49
|
+
# (
|
|
50
|
+
# "digests/yesterday.md",
|
|
51
|
+
# "digests/today.md",
|
|
52
|
+
# "digests/this-week.md",
|
|
53
|
+
# "digests/last-week.md",
|
|
54
|
+
# )
|
|
55
|
+
assert is_digest_path("digests/today.md")
|
|
56
|
+
assert is_digest_path("digests/2026-05-12.md")
|
|
57
|
+
assert is_digest_path("digests/this-week.md")
|
|
58
|
+
assert is_digest_path("digests/last-week.md")
|
|
59
|
+
|
|
60
|
+
# Read canonical provider layout documentation.
|
|
61
|
+
layout = client.read_file(workspace_id, provider_layout_path("linear"))
|
|
62
|
+
|
|
63
|
+
# Read a writeback schema served beside a writeback resource.
|
|
64
|
+
schema = client.read_file(
|
|
65
|
+
workspace_id,
|
|
66
|
+
resource_schema_path("linear", "issues/AGE-16__abc/comments"),
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
# Writeback list mirrors `relayfile writeback list --state ...`. Rows come back
|
|
70
|
+
# as typed WritebackItem instances; dead-lettered rows carry an inline
|
|
71
|
+
# DeadLetterErrorPayload resolved from the .error.json sidecar.
|
|
72
|
+
#
|
|
73
|
+
# Naming note: the CLI flag uses `--state dead` (short form); the SDK and wire
|
|
74
|
+
# value is `"dead_lettered"` (the full WritebackState literal). The CLI
|
|
75
|
+
# translates `dead` -> `dead_lettered` before hitting the daemon.
|
|
76
|
+
pending = client.list_writebacks(workspace_id, state="pending")
|
|
77
|
+
# `list_pending_writebacks` is preserved as a thin alias for back-compat.
|
|
78
|
+
|
|
79
|
+
# Non-pending states (e.g. `"dead_lettered"`, `"succeeded"`, `"failed"`)
|
|
80
|
+
# currently raise NotImplementedError until the state-filtered endpoint
|
|
81
|
+
# (`GET /v1/workspaces/{ws}/writeback?state=...`) is added to the
|
|
82
|
+
# authoritative OpenAPI contract by the `update-relayfile-cli` slice
|
|
83
|
+
# (workspace-primitives work item 5). The typed return shape and the
|
|
84
|
+
# `DeadLetterErrorPayload` coercion are ready ahead of that landing.
|
|
85
|
+
```
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# relayfile
|
|
2
|
+
|
|
3
|
+
Python SDK for the RelayFile virtual filesystem API.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install relayfile-sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The import namespace remains `relayfile`.
|
|
12
|
+
|
|
13
|
+
## Workspace Primitives (M1)
|
|
14
|
+
|
|
15
|
+
The SDK exposes the workspace primitive paths and data shapes used by digest,
|
|
16
|
+
layout, schema, and writeback tooling.
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
from relayfile import (
|
|
20
|
+
DIGEST_PATHS,
|
|
21
|
+
RelayFileClient,
|
|
22
|
+
is_digest_path,
|
|
23
|
+
provider_layout_path,
|
|
24
|
+
resource_schema_path,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
client = RelayFileClient("https://api.relayfile.dev", token_provider)
|
|
28
|
+
|
|
29
|
+
# DIGEST_PATHS is the literal anchor-path taxonomy: the rolling daily
|
|
30
|
+
# files plus rolling and closing-window weekly files. Closed-window daily
|
|
31
|
+
# artifacts use the date-stamped form ``digests/YYYY-MM-DD.md``; filter
|
|
32
|
+
# events through ``is_digest_path`` to subscribe to the full taxonomy
|
|
33
|
+
# (anchor paths plus date-stamped form).
|
|
34
|
+
print(DIGEST_PATHS)
|
|
35
|
+
# (
|
|
36
|
+
# "digests/yesterday.md",
|
|
37
|
+
# "digests/today.md",
|
|
38
|
+
# "digests/this-week.md",
|
|
39
|
+
# "digests/last-week.md",
|
|
40
|
+
# )
|
|
41
|
+
assert is_digest_path("digests/today.md")
|
|
42
|
+
assert is_digest_path("digests/2026-05-12.md")
|
|
43
|
+
assert is_digest_path("digests/this-week.md")
|
|
44
|
+
assert is_digest_path("digests/last-week.md")
|
|
45
|
+
|
|
46
|
+
# Read canonical provider layout documentation.
|
|
47
|
+
layout = client.read_file(workspace_id, provider_layout_path("linear"))
|
|
48
|
+
|
|
49
|
+
# Read a writeback schema served beside a writeback resource.
|
|
50
|
+
schema = client.read_file(
|
|
51
|
+
workspace_id,
|
|
52
|
+
resource_schema_path("linear", "issues/AGE-16__abc/comments"),
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Writeback list mirrors `relayfile writeback list --state ...`. Rows come back
|
|
56
|
+
# as typed WritebackItem instances; dead-lettered rows carry an inline
|
|
57
|
+
# DeadLetterErrorPayload resolved from the .error.json sidecar.
|
|
58
|
+
#
|
|
59
|
+
# Naming note: the CLI flag uses `--state dead` (short form); the SDK and wire
|
|
60
|
+
# value is `"dead_lettered"` (the full WritebackState literal). The CLI
|
|
61
|
+
# translates `dead` -> `dead_lettered` before hitting the daemon.
|
|
62
|
+
pending = client.list_writebacks(workspace_id, state="pending")
|
|
63
|
+
# `list_pending_writebacks` is preserved as a thin alias for back-compat.
|
|
64
|
+
|
|
65
|
+
# Non-pending states (e.g. `"dead_lettered"`, `"succeeded"`, `"failed"`)
|
|
66
|
+
# currently raise NotImplementedError until the state-filtered endpoint
|
|
67
|
+
# (`GET /v1/workspaces/{ws}/writeback?state=...`) is added to the
|
|
68
|
+
# authoritative OpenAPI contract by the `update-relayfile-cli` slice
|
|
69
|
+
# (workspace-primitives work item 5). The typed return shape and the
|
|
70
|
+
# `DeadLetterErrorPayload` coercion are ready ahead of that landing.
|
|
71
|
+
```
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "relayfile-sdk"
|
|
7
|
+
version = "0.2.1"
|
|
8
|
+
description = "Python SDK for the RelayFile virtual filesystem API"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "Apache-2.0"
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
dependencies = ["httpx>=0.27,<1", "websocket-client>=1.7,<2"]
|
|
13
|
+
|
|
14
|
+
[project.optional-dependencies]
|
|
15
|
+
dev = ["pytest>=8", "pytest-asyncio>=0.24", "respx>=0.22"]
|
|
16
|
+
|
|
17
|
+
[tool.pytest.ini_options]
|
|
18
|
+
pythonpath = ["src"]
|
|
19
|
+
|
|
20
|
+
[tool.hatch.build.targets.wheel]
|
|
21
|
+
packages = ["src/relayfile"]
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from .client import RelayFileClient, AsyncRelayFileClient, RetryOptions
|
|
2
|
+
from .errors import (
|
|
3
|
+
RelayFileApiError,
|
|
4
|
+
RevisionConflictError,
|
|
5
|
+
QueueFullError,
|
|
6
|
+
InvalidStateError,
|
|
7
|
+
PayloadTooLargeError,
|
|
8
|
+
)
|
|
9
|
+
from .provider import (
|
|
10
|
+
DATE_STAMPED_DIGEST_PATH_PATTERN,
|
|
11
|
+
DIGEST_PATHS,
|
|
12
|
+
IntegrationProvider,
|
|
13
|
+
ListProviderFilesOptions,
|
|
14
|
+
WatchProviderEventsOptions,
|
|
15
|
+
WebhookInput,
|
|
16
|
+
compute_canonical_path,
|
|
17
|
+
is_digest_path,
|
|
18
|
+
provider_layout_path,
|
|
19
|
+
resource_schema_path,
|
|
20
|
+
)
|
|
21
|
+
from .types import (
|
|
22
|
+
DeadLetterErrorPayload,
|
|
23
|
+
DigestBullet,
|
|
24
|
+
DigestContext,
|
|
25
|
+
DigestHandler,
|
|
26
|
+
DigestSection,
|
|
27
|
+
DigestWindow,
|
|
28
|
+
LayoutManifest,
|
|
29
|
+
LayoutManifestAlias,
|
|
30
|
+
LayoutManifestResource,
|
|
31
|
+
WritebackActionType,
|
|
32
|
+
WritebackDeadLetterError,
|
|
33
|
+
WritebackDeadLetterErrorCode,
|
|
34
|
+
WritebackItem,
|
|
35
|
+
WritebackItemDetail,
|
|
36
|
+
WritebackSchemaRef,
|
|
37
|
+
WritebackState,
|
|
38
|
+
)
|
|
39
|
+
from .on_write import on_write, path_matches
|
|
40
|
+
|
|
41
|
+
__all__ = [
|
|
42
|
+
"RelayFileClient",
|
|
43
|
+
"AsyncRelayFileClient",
|
|
44
|
+
"RetryOptions",
|
|
45
|
+
"RelayFileApiError",
|
|
46
|
+
"RevisionConflictError",
|
|
47
|
+
"QueueFullError",
|
|
48
|
+
"InvalidStateError",
|
|
49
|
+
"PayloadTooLargeError",
|
|
50
|
+
"IntegrationProvider",
|
|
51
|
+
"DIGEST_PATHS",
|
|
52
|
+
"DATE_STAMPED_DIGEST_PATH_PATTERN",
|
|
53
|
+
"is_digest_path",
|
|
54
|
+
"WebhookInput",
|
|
55
|
+
"ListProviderFilesOptions",
|
|
56
|
+
"WatchProviderEventsOptions",
|
|
57
|
+
"compute_canonical_path",
|
|
58
|
+
"provider_layout_path",
|
|
59
|
+
"resource_schema_path",
|
|
60
|
+
"DeadLetterErrorPayload",
|
|
61
|
+
"DigestBullet",
|
|
62
|
+
"DigestContext",
|
|
63
|
+
"DigestHandler",
|
|
64
|
+
"DigestSection",
|
|
65
|
+
"DigestWindow",
|
|
66
|
+
"LayoutManifest",
|
|
67
|
+
"LayoutManifestAlias",
|
|
68
|
+
"LayoutManifestResource",
|
|
69
|
+
"WritebackActionType",
|
|
70
|
+
"WritebackDeadLetterError",
|
|
71
|
+
"WritebackDeadLetterErrorCode",
|
|
72
|
+
"WritebackItem",
|
|
73
|
+
"WritebackItemDetail",
|
|
74
|
+
"WritebackSchemaRef",
|
|
75
|
+
"WritebackState",
|
|
76
|
+
"on_write",
|
|
77
|
+
"path_matches",
|
|
78
|
+
]
|