docforge-sdk 0.1.0__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.
- docforge_sdk/__init__.py +161 -0
- docforge_sdk/_exceptions.py +108 -0
- docforge_sdk/_requestspec.py +34 -0
- docforge_sdk/_transport_async.py +168 -0
- docforge_sdk/_transport_base.py +141 -0
- docforge_sdk/_transport_sync.py +168 -0
- docforge_sdk/_version.py +5 -0
- docforge_sdk/client.py +131 -0
- docforge_sdk/models/__init__.py +132 -0
- docforge_sdk/models/_shared.py +121 -0
- docforge_sdk/models/auth.py +130 -0
- docforge_sdk/models/blobs.py +25 -0
- docforge_sdk/models/collections.py +142 -0
- docforge_sdk/models/documents.py +49 -0
- docforge_sdk/models/explorer.py +238 -0
- docforge_sdk/models/health.py +20 -0
- docforge_sdk/models/ir.py +139 -0
- docforge_sdk/models/jobs.py +100 -0
- docforge_sdk/models/pipelines.py +182 -0
- docforge_sdk/models/search.py +110 -0
- docforge_sdk/py.typed +0 -0
- docforge_sdk/resources/__init__.py +53 -0
- docforge_sdk/resources/_base.py +46 -0
- docforge_sdk/resources/auth.py +264 -0
- docforge_sdk/resources/blobs.py +63 -0
- docforge_sdk/resources/collections.py +204 -0
- docforge_sdk/resources/documents.py +153 -0
- docforge_sdk/resources/explorer.py +342 -0
- docforge_sdk/resources/health.py +53 -0
- docforge_sdk/resources/jobs.py +161 -0
- docforge_sdk/resources/pipelines.py +291 -0
- docforge_sdk/resources/search.py +70 -0
- docforge_sdk-0.1.0.dist-info/METADATA +108 -0
- docforge_sdk-0.1.0.dist-info/RECORD +36 -0
- docforge_sdk-0.1.0.dist-info/WHEEL +4 -0
- docforge_sdk-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
# ====== Code Summary ======
|
|
2
|
+
# The pipelines resource — discovery + design of the pipeline graph surfaces. The graph JSON is OPAQUE
|
|
3
|
+
# to the SDK: blob/operations/action pass through as plain dicts, only the typed ENVELOPE comes back.
|
|
4
|
+
# All URL/body logic lives once in the pure _PipelinesSpecs mixin so the async/sync shells differ ONLY
|
|
5
|
+
# by ``await``.
|
|
6
|
+
|
|
7
|
+
# ====== Standard Library Imports ======
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
# ====== Local Project Imports ======
|
|
11
|
+
from .._requestspec import RequestSpec
|
|
12
|
+
from ..models.pipelines import (
|
|
13
|
+
EditResponse,
|
|
14
|
+
InspectResponse,
|
|
15
|
+
PipelineDesignResponse,
|
|
16
|
+
PipelineIndexResponse,
|
|
17
|
+
StageApplyResponse,
|
|
18
|
+
StageViewResponse,
|
|
19
|
+
)
|
|
20
|
+
from ._base import AsyncResource, SyncResource, _ResourceMixin
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class _PipelinesSpecs(_ResourceMixin):
|
|
24
|
+
"""Pure ``RequestSpec`` builders for the pipeline endpoints — the single source of URL/body logic."""
|
|
25
|
+
|
|
26
|
+
_PIPELINES_PATH = "/pipelines"
|
|
27
|
+
|
|
28
|
+
def _list_surfaces_spec(self) -> RequestSpec:
|
|
29
|
+
"""
|
|
30
|
+
Build the spec for discovering the available pipeline surfaces.
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
RequestSpec: A GET on the pipelines index.
|
|
34
|
+
"""
|
|
35
|
+
return RequestSpec("GET", self._PIPELINES_PATH)
|
|
36
|
+
|
|
37
|
+
def _get_design_spec(self, key: str, full: bool) -> RequestSpec:
|
|
38
|
+
"""
|
|
39
|
+
Build the spec for opening a pipeline's design payload.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
key (str): The pipeline key (e.g. ``"ingest"``).
|
|
43
|
+
full (bool): Whether to include the advanced palette blocks.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
RequestSpec: A GET on the pipeline resource, carrying the ``full`` query flag.
|
|
47
|
+
"""
|
|
48
|
+
return RequestSpec("GET", f"{self._PIPELINES_PATH}/{key}", params={"full": full})
|
|
49
|
+
|
|
50
|
+
def _inspect_spec(self, key: str, blob: dict[str, Any]) -> RequestSpec:
|
|
51
|
+
"""
|
|
52
|
+
Build the spec for inspecting an edited pipeline blob.
|
|
53
|
+
|
|
54
|
+
Args:
|
|
55
|
+
key (str): The pipeline key.
|
|
56
|
+
blob (dict[str, Any]): The opaque graph blob to inspect.
|
|
57
|
+
|
|
58
|
+
Returns:
|
|
59
|
+
RequestSpec: A POST to the pipeline's ``/inspect`` route.
|
|
60
|
+
"""
|
|
61
|
+
return RequestSpec("POST", f"{self._PIPELINES_PATH}/{key}/inspect", json={"blob": blob})
|
|
62
|
+
|
|
63
|
+
def _edit_spec(
|
|
64
|
+
self, key: str, blob: dict[str, Any], operations: list[dict[str, Any]]
|
|
65
|
+
) -> RequestSpec:
|
|
66
|
+
"""
|
|
67
|
+
Build the spec for applying graph operations to a pipeline blob.
|
|
68
|
+
|
|
69
|
+
Args:
|
|
70
|
+
key (str): The pipeline key.
|
|
71
|
+
blob (dict[str, Any]): The opaque graph blob the operations start from.
|
|
72
|
+
operations (list[dict[str, Any]]): The ordered, opaque edit operations.
|
|
73
|
+
|
|
74
|
+
Returns:
|
|
75
|
+
RequestSpec: A POST to the pipeline's ``/edit`` route.
|
|
76
|
+
"""
|
|
77
|
+
return RequestSpec(
|
|
78
|
+
"POST",
|
|
79
|
+
f"{self._PIPELINES_PATH}/{key}/edit",
|
|
80
|
+
json={"blob": blob, "operations": operations},
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def _view_stages_spec(self, key: str, blob: dict[str, Any]) -> RequestSpec:
|
|
84
|
+
"""
|
|
85
|
+
Build the spec for deriving the stage view of a pipeline blob.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
key (str): The pipeline key.
|
|
89
|
+
blob (dict[str, Any]): The opaque graph blob to view as stages.
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
RequestSpec: A POST to the pipeline's ``/stages/view`` route.
|
|
93
|
+
"""
|
|
94
|
+
return RequestSpec("POST", f"{self._PIPELINES_PATH}/{key}/stages/view", json={"blob": blob})
|
|
95
|
+
|
|
96
|
+
def _apply_stage_spec(
|
|
97
|
+
self, key: str, blob: dict[str, Any], action: dict[str, Any]
|
|
98
|
+
) -> RequestSpec:
|
|
99
|
+
"""
|
|
100
|
+
Build the spec for compiling a stage action into a pipeline blob.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
key (str): The pipeline key.
|
|
104
|
+
blob (dict[str, Any]): The opaque graph blob the action starts from.
|
|
105
|
+
action (dict[str, Any]): The opaque stage action to apply.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
RequestSpec: A POST to the pipeline's ``/stages/apply`` route.
|
|
109
|
+
"""
|
|
110
|
+
return RequestSpec(
|
|
111
|
+
"POST",
|
|
112
|
+
f"{self._PIPELINES_PATH}/{key}/stages/apply",
|
|
113
|
+
json={"blob": blob, "action": action},
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class AsyncPipelines(AsyncResource, _PipelinesSpecs):
|
|
118
|
+
"""Asynchronous pipeline discovery + design surface."""
|
|
119
|
+
|
|
120
|
+
async def list_surfaces(self) -> PipelineIndexResponse:
|
|
121
|
+
"""
|
|
122
|
+
Discover the pipeline design surfaces the backend serves.
|
|
123
|
+
|
|
124
|
+
Returns:
|
|
125
|
+
PipelineIndexResponse: One entry per available surface.
|
|
126
|
+
"""
|
|
127
|
+
return await self._transport.request(self._list_surfaces_spec(), PipelineIndexResponse)
|
|
128
|
+
|
|
129
|
+
async def get_design(self, key: str, full: bool = True) -> PipelineDesignResponse:
|
|
130
|
+
"""
|
|
131
|
+
Open a pipeline's design payload (palette + blob + issues).
|
|
132
|
+
|
|
133
|
+
Args:
|
|
134
|
+
key (str): The pipeline key (e.g. ``"ingest"``).
|
|
135
|
+
full (bool): Include the advanced palette blocks.
|
|
136
|
+
|
|
137
|
+
Returns:
|
|
138
|
+
PipelineDesignResponse: The design payload.
|
|
139
|
+
"""
|
|
140
|
+
return await self._transport.request(
|
|
141
|
+
self._get_design_spec(key, full), PipelineDesignResponse
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
async def inspect(self, key: str, blob: dict[str, Any]) -> InspectResponse:
|
|
145
|
+
"""
|
|
146
|
+
Inspect an edited pipeline blob (validity + issues + described tree).
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
key (str): The pipeline key.
|
|
150
|
+
blob (dict[str, Any]): The opaque graph blob to inspect.
|
|
151
|
+
|
|
152
|
+
Returns:
|
|
153
|
+
InspectResponse: The described mirror of the blob.
|
|
154
|
+
"""
|
|
155
|
+
return await self._transport.request(self._inspect_spec(key, blob), InspectResponse)
|
|
156
|
+
|
|
157
|
+
async def edit(
|
|
158
|
+
self, key: str, blob: dict[str, Any], operations: list[dict[str, Any]]
|
|
159
|
+
) -> EditResponse:
|
|
160
|
+
"""
|
|
161
|
+
Apply ordered graph operations to a pipeline blob, server-side.
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
key (str): The pipeline key.
|
|
165
|
+
blob (dict[str, Any]): The opaque graph blob the operations start from.
|
|
166
|
+
operations (list[dict[str, Any]]): The ordered, opaque edit operations.
|
|
167
|
+
|
|
168
|
+
Returns:
|
|
169
|
+
EditResponse: The edited blob plus validity + issues + described tree.
|
|
170
|
+
"""
|
|
171
|
+
return await self._transport.request(self._edit_spec(key, blob, operations), EditResponse)
|
|
172
|
+
|
|
173
|
+
async def view_stages(self, key: str, blob: dict[str, Any]) -> StageViewResponse:
|
|
174
|
+
"""
|
|
175
|
+
Derive the stage view of a pipeline blob.
|
|
176
|
+
|
|
177
|
+
Args:
|
|
178
|
+
key (str): The pipeline key.
|
|
179
|
+
blob (dict[str, Any]): The opaque graph blob to view as stages.
|
|
180
|
+
|
|
181
|
+
Returns:
|
|
182
|
+
StageViewResponse: The ordered stages plus the validity verdict.
|
|
183
|
+
"""
|
|
184
|
+
return await self._transport.request(self._view_stages_spec(key, blob), StageViewResponse)
|
|
185
|
+
|
|
186
|
+
async def apply_stage(
|
|
187
|
+
self, key: str, blob: dict[str, Any], action: dict[str, Any]
|
|
188
|
+
) -> StageApplyResponse:
|
|
189
|
+
"""
|
|
190
|
+
Compile a stage action into a pipeline blob.
|
|
191
|
+
|
|
192
|
+
Args:
|
|
193
|
+
key (str): The pipeline key.
|
|
194
|
+
blob (dict[str, Any]): The opaque graph blob the action starts from.
|
|
195
|
+
action (dict[str, Any]): The opaque stage action to apply.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
StageApplyResponse: The recompiled blob plus its stage view, validity and notices.
|
|
199
|
+
"""
|
|
200
|
+
return await self._transport.request(
|
|
201
|
+
self._apply_stage_spec(key, blob, action), StageApplyResponse
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
|
|
205
|
+
class SyncPipelines(SyncResource, _PipelinesSpecs):
|
|
206
|
+
"""Synchronous pipeline discovery + design surface."""
|
|
207
|
+
|
|
208
|
+
def list_surfaces(self) -> PipelineIndexResponse:
|
|
209
|
+
"""
|
|
210
|
+
Discover the pipeline design surfaces the backend serves.
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
PipelineIndexResponse: One entry per available surface.
|
|
214
|
+
"""
|
|
215
|
+
return self._transport.request(self._list_surfaces_spec(), PipelineIndexResponse)
|
|
216
|
+
|
|
217
|
+
def get_design(self, key: str, full: bool = True) -> PipelineDesignResponse:
|
|
218
|
+
"""
|
|
219
|
+
Open a pipeline's design payload (palette + blob + issues).
|
|
220
|
+
|
|
221
|
+
Args:
|
|
222
|
+
key (str): The pipeline key (e.g. ``"ingest"``).
|
|
223
|
+
full (bool): Include the advanced palette blocks.
|
|
224
|
+
|
|
225
|
+
Returns:
|
|
226
|
+
PipelineDesignResponse: The design payload.
|
|
227
|
+
"""
|
|
228
|
+
return self._transport.request(self._get_design_spec(key, full), PipelineDesignResponse)
|
|
229
|
+
|
|
230
|
+
def inspect(self, key: str, blob: dict[str, Any]) -> InspectResponse:
|
|
231
|
+
"""
|
|
232
|
+
Inspect an edited pipeline blob (validity + issues + described tree).
|
|
233
|
+
|
|
234
|
+
Args:
|
|
235
|
+
key (str): The pipeline key.
|
|
236
|
+
blob (dict[str, Any]): The opaque graph blob to inspect.
|
|
237
|
+
|
|
238
|
+
Returns:
|
|
239
|
+
InspectResponse: The described mirror of the blob.
|
|
240
|
+
"""
|
|
241
|
+
return self._transport.request(self._inspect_spec(key, blob), InspectResponse)
|
|
242
|
+
|
|
243
|
+
def edit(
|
|
244
|
+
self, key: str, blob: dict[str, Any], operations: list[dict[str, Any]]
|
|
245
|
+
) -> EditResponse:
|
|
246
|
+
"""
|
|
247
|
+
Apply ordered graph operations to a pipeline blob, server-side.
|
|
248
|
+
|
|
249
|
+
Args:
|
|
250
|
+
key (str): The pipeline key.
|
|
251
|
+
blob (dict[str, Any]): The opaque graph blob the operations start from.
|
|
252
|
+
operations (list[dict[str, Any]]): The ordered, opaque edit operations.
|
|
253
|
+
|
|
254
|
+
Returns:
|
|
255
|
+
EditResponse: The edited blob plus validity + issues + described tree.
|
|
256
|
+
"""
|
|
257
|
+
return self._transport.request(self._edit_spec(key, blob, operations), EditResponse)
|
|
258
|
+
|
|
259
|
+
def view_stages(self, key: str, blob: dict[str, Any]) -> StageViewResponse:
|
|
260
|
+
"""
|
|
261
|
+
Derive the stage view of a pipeline blob.
|
|
262
|
+
|
|
263
|
+
Args:
|
|
264
|
+
key (str): The pipeline key.
|
|
265
|
+
blob (dict[str, Any]): The opaque graph blob to view as stages.
|
|
266
|
+
|
|
267
|
+
Returns:
|
|
268
|
+
StageViewResponse: The ordered stages plus the validity verdict.
|
|
269
|
+
"""
|
|
270
|
+
return self._transport.request(self._view_stages_spec(key, blob), StageViewResponse)
|
|
271
|
+
|
|
272
|
+
def apply_stage(
|
|
273
|
+
self, key: str, blob: dict[str, Any], action: dict[str, Any]
|
|
274
|
+
) -> StageApplyResponse:
|
|
275
|
+
"""
|
|
276
|
+
Compile a stage action into a pipeline blob.
|
|
277
|
+
|
|
278
|
+
Args:
|
|
279
|
+
key (str): The pipeline key.
|
|
280
|
+
blob (dict[str, Any]): The opaque graph blob the action starts from.
|
|
281
|
+
action (dict[str, Any]): The opaque stage action to apply.
|
|
282
|
+
|
|
283
|
+
Returns:
|
|
284
|
+
StageApplyResponse: The recompiled blob plus its stage view, validity and notices.
|
|
285
|
+
"""
|
|
286
|
+
return self._transport.request(
|
|
287
|
+
self._apply_stage_spec(key, blob, action), StageApplyResponse
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
__all__ = ["AsyncPipelines", "SyncPipelines"]
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# ====== Code Summary ======
|
|
2
|
+
# The search resource — a hybrid search over one collection's chunks. All URL/body logic lives once in
|
|
3
|
+
# the pure _SearchSpecs mixin so AsyncSearch and SyncSearch differ ONLY by ``await``.
|
|
4
|
+
|
|
5
|
+
# ====== Local Project Imports ======
|
|
6
|
+
from .._requestspec import RequestSpec
|
|
7
|
+
from ..models.search import SearchRequest, SearchResponse
|
|
8
|
+
from ._base import AsyncResource, SyncResource, _ResourceMixin
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class _SearchSpecs(_ResourceMixin):
|
|
12
|
+
"""Pure ``RequestSpec`` builders for the search endpoint — the single source of URL/body logic."""
|
|
13
|
+
|
|
14
|
+
_COLLECTIONS_PATH = "/collections"
|
|
15
|
+
|
|
16
|
+
def _search_spec(self, collection_id: str, request: SearchRequest) -> RequestSpec:
|
|
17
|
+
"""
|
|
18
|
+
Build the spec for searching a collection.
|
|
19
|
+
|
|
20
|
+
Args:
|
|
21
|
+
collection_id (str): The collection to search.
|
|
22
|
+
request (SearchRequest): The query, filters and target modalities.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
RequestSpec: A POST to the collection's ``/search`` route carrying the query body.
|
|
26
|
+
"""
|
|
27
|
+
return RequestSpec(
|
|
28
|
+
"POST",
|
|
29
|
+
f"{self._COLLECTIONS_PATH}/{collection_id}/search",
|
|
30
|
+
json=request.model_dump(mode="json"),
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class AsyncSearch(AsyncResource, _SearchSpecs):
|
|
35
|
+
"""Asynchronous hybrid search."""
|
|
36
|
+
|
|
37
|
+
async def search(self, collection_id: str, request: SearchRequest) -> SearchResponse:
|
|
38
|
+
"""
|
|
39
|
+
Run a hybrid search over a collection and return ranked, hydrated chunk hits.
|
|
40
|
+
|
|
41
|
+
Args:
|
|
42
|
+
collection_id (str): The collection to search.
|
|
43
|
+
request (SearchRequest): The query, filters and target modalities.
|
|
44
|
+
|
|
45
|
+
Returns:
|
|
46
|
+
SearchResponse: The echoed query and its hits, best first.
|
|
47
|
+
"""
|
|
48
|
+
return await self._transport.request(
|
|
49
|
+
self._search_spec(collection_id, request), SearchResponse
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class SyncSearch(SyncResource, _SearchSpecs):
|
|
54
|
+
"""Synchronous hybrid search."""
|
|
55
|
+
|
|
56
|
+
def search(self, collection_id: str, request: SearchRequest) -> SearchResponse:
|
|
57
|
+
"""
|
|
58
|
+
Run a hybrid search over a collection and return ranked, hydrated chunk hits.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
collection_id (str): The collection to search.
|
|
62
|
+
request (SearchRequest): The query, filters and target modalities.
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
SearchResponse: The echoed query and its hits, best first.
|
|
66
|
+
"""
|
|
67
|
+
return self._transport.request(self._search_spec(collection_id, request), SearchResponse)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
__all__ = ["AsyncSearch", "SyncSearch"]
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: docforge-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Typed async + sync Python client for the DocForge REST API (standalone, zero server deps).
|
|
5
|
+
Project-URL: Homepage, https://github.com/Florian-BARRE/docforge
|
|
6
|
+
Project-URL: Repository, https://github.com/Florian-BARRE/docforge
|
|
7
|
+
Project-URL: Issues, https://github.com/Florian-BARRE/docforge/issues
|
|
8
|
+
Author: Florian Barré
|
|
9
|
+
License-Expression: MIT
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Keywords: api-client,async,client,docforge,document-intelligence,rag,retrieval,sdk
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Requires-Dist: httpx>=0.28
|
|
21
|
+
Requires-Dist: pydantic>=2.7
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
|
|
24
|
+
# docforge-sdk
|
|
25
|
+
|
|
26
|
+
A typed Python client for the [DocForge](https://github.com/Florian-BARRE/docforge) REST API. It
|
|
27
|
+
ships **both** an asynchronous and a synchronous client with an identical surface, is fully
|
|
28
|
+
type-hinted (`py.typed`), and has **zero dependency on the DocForge server tree** — it is a
|
|
29
|
+
clean-room client that talks to the API over HTTP only (`httpx` + `pydantic` + hand-written models
|
|
30
|
+
that mirror the public REST contract), so it can be vendored or published independently.
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install docforge-sdk
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Async usage
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
import asyncio
|
|
42
|
+
|
|
43
|
+
from docforge_sdk import AsyncClient, SearchRequest
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
async def main() -> None:
|
|
47
|
+
async with AsyncClient("http://localhost:10040", api_token="df_root_...") as client:
|
|
48
|
+
collections = await client.collections.list()
|
|
49
|
+
for collection in collections:
|
|
50
|
+
print(collection.id, collection.name)
|
|
51
|
+
|
|
52
|
+
hits = await client.search.search(
|
|
53
|
+
collections[0].id,
|
|
54
|
+
SearchRequest(query="quarterly revenue", limit=5),
|
|
55
|
+
)
|
|
56
|
+
for hit in hits.hits:
|
|
57
|
+
print(hit.score, hit.text)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
asyncio.run(main())
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Sync usage
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from docforge_sdk import Client, SearchRequest
|
|
67
|
+
|
|
68
|
+
with Client("http://localhost:10040", api_token="df_root_...") as client:
|
|
69
|
+
collections = client.collections.list()
|
|
70
|
+
hits = client.search.search(
|
|
71
|
+
collections[0].id,
|
|
72
|
+
SearchRequest(query="quarterly revenue", limit=5),
|
|
73
|
+
)
|
|
74
|
+
for hit in hits.hits:
|
|
75
|
+
print(hit.score, hit.text)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
The two clients expose the same resources and method signatures; the sync methods are the async ones
|
|
79
|
+
without `await`. Available resource groups: `auth`, `health`, `collections`, `documents`, `explorer`,
|
|
80
|
+
`search`, `jobs`, `blobs`, `pipelines`.
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
MIT — see [LICENSE](LICENSE). This SDK is deliberately licensed **MIT even though the parent DocForge
|
|
85
|
+
repository is GPLv3**: it is a standalone, clean-room client (HTTP models only, no server code), so a
|
|
86
|
+
permissive per-directory license is intentional and lets any project depend on it freely.
|
|
87
|
+
|
|
88
|
+
## Publishing (maintainers)
|
|
89
|
+
|
|
90
|
+
Releases publish to PyPI via **Trusted Publishing (OIDC)** — there is no API token stored in the
|
|
91
|
+
repo. To cut a release, tag a commit with the `sdk-v<version>` prefix (the version must match
|
|
92
|
+
`docforge_sdk/_version.py`) and push the tag:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
git tag sdk-v0.1.0
|
|
96
|
+
git push origin sdk-v0.1.0
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The `.github/workflows/release-sdk.yml` workflow then builds and uploads the sdist + wheel.
|
|
100
|
+
|
|
101
|
+
**One-time PyPI setup** (done once by the maintainer, before the first release):
|
|
102
|
+
|
|
103
|
+
1. Reserve the project name `docforge-sdk` on PyPI.
|
|
104
|
+
2. Under the project's *Publishing* settings, add a **GitHub trusted publisher** with:
|
|
105
|
+
- Owner: `Florian-BARRE`
|
|
106
|
+
- Repository: `docforge`
|
|
107
|
+
- Workflow name: `release-sdk.yml`
|
|
108
|
+
- Environment: `pypi`
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
docforge_sdk/__init__.py,sha256=XS61Q-rfIdy3TvxfSjw6zViGfUsUB9Y4ZKkjV_ltUZU,3876
|
|
2
|
+
docforge_sdk/_exceptions.py,sha256=BrfgSn2Yq6dKSFg_i9FHDdWrb9N1HwwwbVKH4nAadmQ,3592
|
|
3
|
+
docforge_sdk/_requestspec.py,sha256=HuRnpPA4O_lwXgByYekgJtpGNFss_fqZ6d_6ucSpfaY,1331
|
|
4
|
+
docforge_sdk/_transport_async.py,sha256=bYfuah01yxKMzRlsMhyABzkTIxr8huyAbSOfp1hwVEo,6129
|
|
5
|
+
docforge_sdk/_transport_base.py,sha256=120RPWiuhSD30TOKCqVC519nOgrOHIAMq5y8vkFhP_0,5317
|
|
6
|
+
docforge_sdk/_transport_sync.py,sha256=OVTjKtvshj13K_AmRrTtLkCyahHXHtfKhT4ufSd4Wx4,6022
|
|
7
|
+
docforge_sdk/_version.py,sha256=0LO1fk-0zhM_r0SLBJ2pX3jrF69BB9BM1EQETn22bDI,239
|
|
8
|
+
docforge_sdk/client.py,sha256=vaKECQr8AgjUI-UmXoZEBeKgyMX2PgQ4wPTc0aF4uQw,5301
|
|
9
|
+
docforge_sdk/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
10
|
+
docforge_sdk/models/__init__.py,sha256=s9pkJbyoRWTz_5NHZ092RQg5WAUGi8KqE3N5udBGqf8,3166
|
|
11
|
+
docforge_sdk/models/_shared.py,sha256=CmV2kKzJBVUj1Pkr0iq78fN51cNg7gEW-pMLM9D837c,3292
|
|
12
|
+
docforge_sdk/models/auth.py,sha256=gTqJOz3l4k_aGzVA4Y8dMFIEgWiRTguYE4y4UCzSCTA,5635
|
|
13
|
+
docforge_sdk/models/blobs.py,sha256=9e_xJiM6bc8F5gG97Bw7N0W2I2RjYyCxtvhDnooPZPc,888
|
|
14
|
+
docforge_sdk/models/collections.py,sha256=qKJK8tt2jYWP87ScTUL3vTLzk8xpMzqfw8zsz96PCKE,6525
|
|
15
|
+
docforge_sdk/models/documents.py,sha256=dJk5aC0uUy6Gda25yP3jpsrGs1XS8Lo1dWMz7McscNo,1809
|
|
16
|
+
docforge_sdk/models/explorer.py,sha256=hqWYNY-dJSYJlUNcRxv4njwoKvM8kzBfIZ4ShS9Y5OQ,10761
|
|
17
|
+
docforge_sdk/models/health.py,sha256=SSWeFtEh2R_eRBuIi2QXFEuy6lPDL03I9uaYC3ESNNk,602
|
|
18
|
+
docforge_sdk/models/ir.py,sha256=2LClyD6_XuJQllc5WUeA32UqM1z30kDNC87IQAo-8us,6269
|
|
19
|
+
docforge_sdk/models/jobs.py,sha256=I22srI1YGUdw1wwL5mOFe_43CMpplgpfXfOtmkFyQeM,3984
|
|
20
|
+
docforge_sdk/models/pipelines.py,sha256=tf5aggvfetPsODEMP-UN77zbiGNmgWqpmXeT5uk5W1k,8054
|
|
21
|
+
docforge_sdk/models/search.py,sha256=VKbO8JrgSiPN7yQt2vy9wxVu51JrYLtCWMz589l6QFU,4544
|
|
22
|
+
docforge_sdk/resources/__init__.py,sha256=kGQed_gnpoo7LE6ViDH7GPm56po6oX7AsLiwqbITV4E,1534
|
|
23
|
+
docforge_sdk/resources/_base.py,sha256=NoDy86ccGsyAZJEU2KjW3NYYJlsypvjmEkQtAdhaS04,1499
|
|
24
|
+
docforge_sdk/resources/auth.py,sha256=a_6tIAX13BXasMN3TDeX7STSdbjZ7QiGMNX62q9y2mo,10042
|
|
25
|
+
docforge_sdk/resources/blobs.py,sha256=SGAEF8XGytf72TQDOFaDEd89_Tj_w88JOOhxO0vrIBs,2182
|
|
26
|
+
docforge_sdk/resources/collections.py,sha256=4yfkQwCcbH5Gj4rkStQeEiTxgzRPl1B8u09KMWe-cTA,6949
|
|
27
|
+
docforge_sdk/resources/documents.py,sha256=p5hrYBwJeLn5Ay7TOfWAmc085h2F32KqbUgN8naHzBY,6114
|
|
28
|
+
docforge_sdk/resources/explorer.py,sha256=BoDY-45Mp-7r097VNpzQOV974kfc_tmLH-ebWNsSDxM,11429
|
|
29
|
+
docforge_sdk/resources/health.py,sha256=WL7_iTwu533R8s7yG8qhB_RUJV4eB6ytKXRDXcB3ILg,1723
|
|
30
|
+
docforge_sdk/resources/jobs.py,sha256=gI679qu26o6RbayUcEsYxOGvwc_atYp40LD1JQkfdpM,5062
|
|
31
|
+
docforge_sdk/resources/pipelines.py,sha256=2A4PY5-wt3nrl5e8vKpl59gE9ws4qXELs2SJci-2Z34,10474
|
|
32
|
+
docforge_sdk/resources/search.py,sha256=b9H5gaRHxSWUukxbNvYMRfxA4CKo_Y-6Es6FVKMlJ4s,2522
|
|
33
|
+
docforge_sdk-0.1.0.dist-info/METADATA,sha256=39g7orUkcmCPSB9YgQ2_zc6wmcdustB41Jlhr9K3Yko,3779
|
|
34
|
+
docforge_sdk-0.1.0.dist-info/WHEEL,sha256=lCkmxWfQsSc9CfIClYeavTdQeEX2toPqufh9gI35EQA,87
|
|
35
|
+
docforge_sdk-0.1.0.dist-info/licenses/LICENSE,sha256=tyuGDFWUibVB0DmTCdzAPFQPBobDYEuQr1pDHxNLTHU,1071
|
|
36
|
+
docforge_sdk-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Florian Barré
|
|
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.
|