knowledge2 0.4.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.
Files changed (139) hide show
  1. knowledge2-0.4.0.dist-info/METADATA +556 -0
  2. knowledge2-0.4.0.dist-info/RECORD +139 -0
  3. knowledge2-0.4.0.dist-info/WHEEL +5 -0
  4. knowledge2-0.4.0.dist-info/top_level.txt +1 -0
  5. sdk/__init__.py +70 -0
  6. sdk/_async_base.py +525 -0
  7. sdk/_async_paging.py +57 -0
  8. sdk/_base.py +541 -0
  9. sdk/_logging.py +41 -0
  10. sdk/_paging.py +73 -0
  11. sdk/_preview.py +70 -0
  12. sdk/_raw_response.py +25 -0
  13. sdk/_request_options.py +51 -0
  14. sdk/_transport.py +144 -0
  15. sdk/_validation.py +25 -0
  16. sdk/_validation_response.py +36 -0
  17. sdk/_version.py +3 -0
  18. sdk/async_client.py +320 -0
  19. sdk/async_resources/__init__.py +45 -0
  20. sdk/async_resources/_mixin_base.py +42 -0
  21. sdk/async_resources/a2a.py +230 -0
  22. sdk/async_resources/agents.py +489 -0
  23. sdk/async_resources/audit.py +145 -0
  24. sdk/async_resources/auth.py +133 -0
  25. sdk/async_resources/console.py +409 -0
  26. sdk/async_resources/corpora.py +276 -0
  27. sdk/async_resources/deployments.py +106 -0
  28. sdk/async_resources/documents.py +592 -0
  29. sdk/async_resources/feeds.py +248 -0
  30. sdk/async_resources/indexes.py +208 -0
  31. sdk/async_resources/jobs.py +165 -0
  32. sdk/async_resources/metadata.py +48 -0
  33. sdk/async_resources/models.py +102 -0
  34. sdk/async_resources/onboarding.py +538 -0
  35. sdk/async_resources/orgs.py +37 -0
  36. sdk/async_resources/pipelines.py +523 -0
  37. sdk/async_resources/projects.py +90 -0
  38. sdk/async_resources/search.py +262 -0
  39. sdk/async_resources/training.py +357 -0
  40. sdk/async_resources/usage.py +91 -0
  41. sdk/client.py +417 -0
  42. sdk/config.py +182 -0
  43. sdk/errors.py +178 -0
  44. sdk/examples/auth_factory.py +34 -0
  45. sdk/examples/batch_operations.py +57 -0
  46. sdk/examples/document_upload.py +56 -0
  47. sdk/examples/e2e_lifecycle.py +213 -0
  48. sdk/examples/error_handling.py +61 -0
  49. sdk/examples/pagination.py +64 -0
  50. sdk/examples/quickstart.py +36 -0
  51. sdk/examples/request_options.py +44 -0
  52. sdk/examples/search.py +64 -0
  53. sdk/integrations/__init__.py +57 -0
  54. sdk/integrations/_client.py +101 -0
  55. sdk/integrations/langchain/__init__.py +6 -0
  56. sdk/integrations/langchain/retriever.py +166 -0
  57. sdk/integrations/langchain/tools.py +108 -0
  58. sdk/integrations/llamaindex/__init__.py +11 -0
  59. sdk/integrations/llamaindex/filters.py +78 -0
  60. sdk/integrations/llamaindex/retriever.py +162 -0
  61. sdk/integrations/llamaindex/tools.py +109 -0
  62. sdk/integrations/llamaindex/vector_store.py +320 -0
  63. sdk/models/__init__.py +18 -0
  64. sdk/models/_base.py +24 -0
  65. sdk/models/_registry.py +457 -0
  66. sdk/models/a2a.py +92 -0
  67. sdk/models/agents.py +109 -0
  68. sdk/models/audit.py +28 -0
  69. sdk/models/auth.py +49 -0
  70. sdk/models/chunks.py +20 -0
  71. sdk/models/common.py +14 -0
  72. sdk/models/console.py +103 -0
  73. sdk/models/corpora.py +48 -0
  74. sdk/models/deployments.py +13 -0
  75. sdk/models/documents.py +126 -0
  76. sdk/models/embeddings.py +24 -0
  77. sdk/models/evaluation.py +17 -0
  78. sdk/models/feedback.py +9 -0
  79. sdk/models/feeds.py +57 -0
  80. sdk/models/indexes.py +36 -0
  81. sdk/models/jobs.py +52 -0
  82. sdk/models/models.py +26 -0
  83. sdk/models/onboarding.py +323 -0
  84. sdk/models/orgs.py +11 -0
  85. sdk/models/pipelines.py +147 -0
  86. sdk/models/projects.py +19 -0
  87. sdk/models/search.py +149 -0
  88. sdk/models/training.py +57 -0
  89. sdk/models/usage.py +39 -0
  90. sdk/namespaces.py +386 -0
  91. sdk/py.typed +0 -0
  92. sdk/resources/__init__.py +45 -0
  93. sdk/resources/_mixin_base.py +40 -0
  94. sdk/resources/a2a.py +230 -0
  95. sdk/resources/agents.py +487 -0
  96. sdk/resources/audit.py +144 -0
  97. sdk/resources/auth.py +138 -0
  98. sdk/resources/console.py +411 -0
  99. sdk/resources/corpora.py +269 -0
  100. sdk/resources/deployments.py +105 -0
  101. sdk/resources/documents.py +597 -0
  102. sdk/resources/feeds.py +246 -0
  103. sdk/resources/indexes.py +210 -0
  104. sdk/resources/jobs.py +164 -0
  105. sdk/resources/metadata.py +53 -0
  106. sdk/resources/models.py +99 -0
  107. sdk/resources/onboarding.py +542 -0
  108. sdk/resources/orgs.py +35 -0
  109. sdk/resources/pipeline_builder.py +257 -0
  110. sdk/resources/pipelines.py +520 -0
  111. sdk/resources/projects.py +87 -0
  112. sdk/resources/search.py +277 -0
  113. sdk/resources/training.py +358 -0
  114. sdk/resources/usage.py +92 -0
  115. sdk/types/__init__.py +366 -0
  116. sdk/types/a2a.py +88 -0
  117. sdk/types/agents.py +133 -0
  118. sdk/types/audit.py +26 -0
  119. sdk/types/auth.py +45 -0
  120. sdk/types/chunks.py +18 -0
  121. sdk/types/common.py +10 -0
  122. sdk/types/console.py +99 -0
  123. sdk/types/corpora.py +42 -0
  124. sdk/types/deployments.py +11 -0
  125. sdk/types/documents.py +104 -0
  126. sdk/types/embeddings.py +22 -0
  127. sdk/types/evaluation.py +15 -0
  128. sdk/types/feedback.py +7 -0
  129. sdk/types/feeds.py +61 -0
  130. sdk/types/indexes.py +30 -0
  131. sdk/types/jobs.py +50 -0
  132. sdk/types/models.py +22 -0
  133. sdk/types/onboarding.py +395 -0
  134. sdk/types/orgs.py +9 -0
  135. sdk/types/pipelines.py +177 -0
  136. sdk/types/projects.py +14 -0
  137. sdk/types/search.py +116 -0
  138. sdk/types/training.py +55 -0
  139. sdk/types/usage.py +37 -0
@@ -0,0 +1,520 @@
1
+ """Pipeline Spec resource mixin for the Knowledge2 SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from sdk._paging import Page, SyncPager
8
+ from sdk._preview import preview_resource
9
+ from sdk._request_options import RequestOptions
10
+ from sdk._validation import require_str
11
+ from sdk.resources._mixin_base import RequesterMixin
12
+
13
+
14
+ @preview_resource
15
+ class PipelinesMixin(RequesterMixin):
16
+ # ------------------------------------------------------------------
17
+ # CRUD
18
+ # ------------------------------------------------------------------
19
+
20
+ def create_pipeline_spec(
21
+ self,
22
+ *,
23
+ project_id: str,
24
+ name: str,
25
+ topology: dict[str, Any],
26
+ description: str | None = None,
27
+ request_options: RequestOptions | None = None,
28
+ ) -> dict[str, Any]:
29
+ """Create a new pipeline spec.
30
+
31
+ Args:
32
+ project_id: ID of the project that will own the pipeline spec.
33
+ name: Human-readable name for the pipeline spec.
34
+ topology: Topology document describing corpora, agents, feeds,
35
+ and subscriptions.
36
+ description: Optional description of the pipeline spec.
37
+
38
+ Returns:
39
+ The newly created pipeline spec record.
40
+
41
+ Raises:
42
+ Knowledge2Error: If the API request fails.
43
+ """
44
+ project_id = require_str(project_id, "project_id")
45
+ name = require_str(name, "name")
46
+ payload: dict[str, Any] = {
47
+ "project_id": project_id,
48
+ "name": name,
49
+ "topology": topology,
50
+ }
51
+ if description is not None:
52
+ payload["description"] = description
53
+ data = self._request(
54
+ "POST", "/v1/pipeline-specs", json=payload, request_options=request_options
55
+ )
56
+ return self._maybe_validate(data, "PipelineSpecResponse")
57
+
58
+ def get_pipeline_spec(
59
+ self,
60
+ pipeline_spec_id: str,
61
+ request_options: RequestOptions | None = None,
62
+ ) -> dict[str, Any]:
63
+ """Retrieve a single pipeline spec by ID.
64
+
65
+ Args:
66
+ pipeline_spec_id: Unique identifier of the pipeline spec.
67
+
68
+ Returns:
69
+ The pipeline spec record.
70
+
71
+ Raises:
72
+ NotFoundError: If the pipeline spec does not exist.
73
+ Knowledge2Error: If the API request fails.
74
+ """
75
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
76
+ data = self._request(
77
+ "GET",
78
+ f"/v1/pipeline-specs/{pipeline_spec_id}",
79
+ request_options=request_options,
80
+ )
81
+ return self._maybe_validate(data, "PipelineSpecResponse")
82
+
83
+ def list_pipeline_specs(
84
+ self,
85
+ *,
86
+ project_id: str | None = None,
87
+ limit: int = 100,
88
+ offset: int = 0,
89
+ request_options: RequestOptions | None = None,
90
+ ) -> Page[dict[str, Any]]:
91
+ """List pipeline specs accessible to the current credentials.
92
+
93
+ Args:
94
+ project_id: Optional project ID to filter by.
95
+ limit: Maximum number of pipeline specs to return per page.
96
+ offset: Number of pipeline specs to skip for pagination.
97
+
98
+ Returns:
99
+ A Page containing pipeline spec records with pagination metadata.
100
+
101
+ Raises:
102
+ Knowledge2Error: If the API request fails.
103
+ """
104
+ params: dict[str, Any] = {}
105
+ if project_id is not None:
106
+ params["project_id"] = project_id
107
+ return self._list_page(
108
+ "GET",
109
+ "/v1/pipeline-specs",
110
+ items_key="pipeline_specs",
111
+ params=params or None,
112
+ limit=limit,
113
+ offset=offset,
114
+ )
115
+
116
+ def iter_pipeline_specs(
117
+ self,
118
+ *,
119
+ project_id: str | None = None,
120
+ limit: int = 100,
121
+ request_options: RequestOptions | None = None,
122
+ ) -> SyncPager[dict[str, Any]]:
123
+ """Lazily paginate pipeline specs, yielding individual items.
124
+
125
+ Args:
126
+ project_id: Optional project ID to filter by.
127
+ limit: Page size used for each underlying API request.
128
+
129
+ Yields:
130
+ Individual pipeline spec response dicts.
131
+
132
+ Raises:
133
+ Knowledge2Error: If any underlying API request fails.
134
+ """
135
+ params: dict[str, Any] = {}
136
+ if project_id is not None:
137
+ params["project_id"] = project_id
138
+ return self._paginate(
139
+ "GET",
140
+ "/v1/pipeline-specs",
141
+ items_key="pipeline_specs",
142
+ params=params or None,
143
+ limit=limit,
144
+ )
145
+
146
+ def update_pipeline_spec(
147
+ self,
148
+ pipeline_spec_id: str,
149
+ *,
150
+ name: str | None = None,
151
+ description: str | None = None,
152
+ topology: dict[str, Any] | None = None,
153
+ request_options: RequestOptions | None = None,
154
+ ) -> dict[str, Any]:
155
+ """Update pipeline spec settings.
156
+
157
+ Args:
158
+ pipeline_spec_id: ID of the pipeline spec to update.
159
+ name: New name for the pipeline spec.
160
+ description: New description.
161
+ topology: New topology document.
162
+
163
+ Returns:
164
+ Updated pipeline spec record.
165
+
166
+ Raises:
167
+ NotFoundError: If the pipeline spec does not exist.
168
+ Knowledge2Error: If the API request fails.
169
+ """
170
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
171
+ payload: dict[str, Any] = {}
172
+ if name is not None:
173
+ payload["name"] = name
174
+ if description is not None:
175
+ payload["description"] = description
176
+ if topology is not None:
177
+ payload["topology"] = topology
178
+ data = self._request(
179
+ "PATCH",
180
+ f"/v1/pipeline-specs/{pipeline_spec_id}",
181
+ json=payload,
182
+ request_options=request_options,
183
+ )
184
+ return self._maybe_validate(data, "PipelineSpecResponse")
185
+
186
+ def delete_pipeline_spec(
187
+ self,
188
+ pipeline_spec_id: str,
189
+ request_options: RequestOptions | None = None,
190
+ ) -> None:
191
+ """Delete a pipeline spec.
192
+
193
+ Args:
194
+ pipeline_spec_id: Unique identifier of the pipeline spec to delete.
195
+
196
+ Returns:
197
+ None (the API returns 204 No Content on success).
198
+
199
+ Raises:
200
+ NotFoundError: If the pipeline spec does not exist.
201
+ Knowledge2Error: If the API request fails.
202
+ """
203
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
204
+ self._request(
205
+ "DELETE",
206
+ f"/v1/pipeline-specs/{pipeline_spec_id}",
207
+ request_options=request_options,
208
+ )
209
+
210
+ def get_pipeline_spec_schema(
211
+ self,
212
+ request_options: RequestOptions | None = None,
213
+ ) -> dict[str, Any]:
214
+ """Retrieve the JSON Schema for pipeline spec topologies.
215
+
216
+ Returns:
217
+ The topology JSON Schema document.
218
+
219
+ Raises:
220
+ Knowledge2Error: If the API request fails.
221
+ """
222
+ data = self._request("GET", "/v1/pipeline-specs/schema", request_options=request_options)
223
+ # Schema endpoint returns a raw JSON Schema document — no typed model to validate against.
224
+ return data
225
+
226
+ # ------------------------------------------------------------------
227
+ # Lifecycle
228
+ # ------------------------------------------------------------------
229
+
230
+ def dry_run_pipeline_spec(
231
+ self,
232
+ pipeline_spec_id: str,
233
+ request_options: RequestOptions | None = None,
234
+ ) -> dict[str, Any]:
235
+ """Perform a dry run of a pipeline spec without creating resources.
236
+
237
+ Args:
238
+ pipeline_spec_id: Unique identifier of the pipeline spec.
239
+
240
+ Returns:
241
+ The dry run result describing what would be created.
242
+
243
+ Raises:
244
+ NotFoundError: If the pipeline spec does not exist.
245
+ Knowledge2Error: If the API request fails.
246
+ """
247
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
248
+ data = self._request(
249
+ "POST",
250
+ f"/v1/pipeline-specs/{pipeline_spec_id}/dry-run",
251
+ request_options=request_options,
252
+ )
253
+ return self._maybe_validate(data, "DryRunResult")
254
+
255
+ def apply_pipeline_spec(
256
+ self,
257
+ pipeline_spec_id: str,
258
+ *,
259
+ activate_entities: bool = True,
260
+ request_options: RequestOptions | None = None,
261
+ ) -> dict[str, Any]:
262
+ """Apply a pipeline spec, creating or updating the described resources.
263
+
264
+ Args:
265
+ pipeline_spec_id: Unique identifier of the pipeline spec.
266
+ activate_entities: Whether to activate created entities after apply.
267
+
268
+ Returns:
269
+ The apply result describing created/updated resources.
270
+
271
+ Raises:
272
+ NotFoundError: If the pipeline spec does not exist.
273
+ Knowledge2Error: If the API request fails.
274
+ """
275
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
276
+ payload: dict[str, Any] = {"activate_entities": activate_entities}
277
+ data = self._request(
278
+ "POST",
279
+ f"/v1/pipeline-specs/{pipeline_spec_id}/apply",
280
+ json=payload,
281
+ request_options=request_options,
282
+ )
283
+ return self._maybe_validate(data, "ApplyResult")
284
+
285
+ def archive_pipeline_spec(
286
+ self,
287
+ pipeline_spec_id: str,
288
+ request_options: RequestOptions | None = None,
289
+ ) -> dict[str, Any]:
290
+ """Archive a pipeline spec.
291
+
292
+ Args:
293
+ pipeline_spec_id: Unique identifier of the pipeline spec.
294
+
295
+ Returns:
296
+ The archive result.
297
+
298
+ Raises:
299
+ NotFoundError: If the pipeline spec does not exist.
300
+ Knowledge2Error: If the API request fails.
301
+ """
302
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
303
+ data = self._request(
304
+ "POST",
305
+ f"/v1/pipeline-specs/{pipeline_spec_id}/archive",
306
+ request_options=request_options,
307
+ )
308
+ return self._maybe_validate(data, "ArchiveResult")
309
+
310
+ def unarchive_pipeline_spec(
311
+ self,
312
+ pipeline_spec_id: str,
313
+ request_options: RequestOptions | None = None,
314
+ ) -> dict[str, Any]:
315
+ """Unarchive a previously archived pipeline spec.
316
+
317
+ Args:
318
+ pipeline_spec_id: Unique identifier of the pipeline spec.
319
+
320
+ Returns:
321
+ The unarchive result.
322
+
323
+ Raises:
324
+ NotFoundError: If the pipeline spec does not exist.
325
+ Knowledge2Error: If the API request fails.
326
+ """
327
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
328
+ data = self._request(
329
+ "POST",
330
+ f"/v1/pipeline-specs/{pipeline_spec_id}/unarchive",
331
+ request_options=request_options,
332
+ )
333
+ return self._maybe_validate(data, "PipelineSpecResponse")
334
+
335
+ # ------------------------------------------------------------------
336
+ # Draft
337
+ # ------------------------------------------------------------------
338
+
339
+ def create_pipeline_spec_draft(
340
+ self,
341
+ pipeline_spec_id: str,
342
+ request_options: RequestOptions | None = None,
343
+ ) -> dict[str, Any]:
344
+ """Create a draft revision for a pipeline spec.
345
+
346
+ Args:
347
+ pipeline_spec_id: Unique identifier of the pipeline spec.
348
+
349
+ Returns:
350
+ The newly created draft record.
351
+
352
+ Raises:
353
+ NotFoundError: If the pipeline spec does not exist.
354
+ Knowledge2Error: If the API request fails.
355
+ """
356
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
357
+ data = self._request(
358
+ "POST",
359
+ f"/v1/pipeline-specs/{pipeline_spec_id}/draft",
360
+ request_options=request_options,
361
+ )
362
+ return self._maybe_validate(data, "PipelineSpecResponse")
363
+
364
+ def get_pipeline_spec_draft(
365
+ self,
366
+ pipeline_spec_id: str,
367
+ request_options: RequestOptions | None = None,
368
+ ) -> dict[str, Any]:
369
+ """Retrieve the current draft for a pipeline spec.
370
+
371
+ Args:
372
+ pipeline_spec_id: Unique identifier of the pipeline spec.
373
+
374
+ Returns:
375
+ The draft record.
376
+
377
+ Raises:
378
+ NotFoundError: If the pipeline spec or draft does not exist.
379
+ Knowledge2Error: If the API request fails.
380
+ """
381
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
382
+ data = self._request(
383
+ "GET",
384
+ f"/v1/pipeline-specs/{pipeline_spec_id}/draft",
385
+ request_options=request_options,
386
+ )
387
+ return self._maybe_validate(data, "PipelineSpecResponse")
388
+
389
+ def activate_pipeline_spec_draft(
390
+ self,
391
+ pipeline_spec_id: str,
392
+ *,
393
+ activate_entities: bool = True,
394
+ request_options: RequestOptions | None = None,
395
+ ) -> dict[str, Any]:
396
+ """Activate (apply) the current draft for a pipeline spec.
397
+
398
+ Args:
399
+ pipeline_spec_id: Unique identifier of the pipeline spec.
400
+ activate_entities: Whether to activate created entities.
401
+
402
+ Returns:
403
+ The draft activation result.
404
+
405
+ Raises:
406
+ NotFoundError: If the pipeline spec or draft does not exist.
407
+ Knowledge2Error: If the API request fails.
408
+ """
409
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
410
+ payload: dict[str, Any] = {"activate_entities": activate_entities}
411
+ data = self._request(
412
+ "POST",
413
+ f"/v1/pipeline-specs/{pipeline_spec_id}/draft/activate",
414
+ json=payload,
415
+ request_options=request_options,
416
+ )
417
+ return self._maybe_validate(data, "DraftActivateResult")
418
+
419
+ def discard_pipeline_spec_draft(
420
+ self,
421
+ pipeline_spec_id: str,
422
+ request_options: RequestOptions | None = None,
423
+ ) -> None:
424
+ """Discard the current draft for a pipeline spec.
425
+
426
+ Args:
427
+ pipeline_spec_id: Unique identifier of the pipeline spec.
428
+
429
+ Returns:
430
+ None (the API returns 204 No Content on success).
431
+
432
+ Raises:
433
+ NotFoundError: If the pipeline spec or draft does not exist.
434
+ Knowledge2Error: If the API request fails.
435
+ """
436
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
437
+ self._request(
438
+ "DELETE",
439
+ f"/v1/pipeline-specs/{pipeline_spec_id}/draft",
440
+ request_options=request_options,
441
+ )
442
+
443
+ # ------------------------------------------------------------------
444
+ # Drift
445
+ # ------------------------------------------------------------------
446
+
447
+ def get_pipeline_spec_graph(
448
+ self,
449
+ pipeline_spec_id: str,
450
+ request_options: RequestOptions | None = None,
451
+ ) -> dict[str, Any]:
452
+ """Get the graph representation of a pipeline spec topology.
453
+
454
+ Args:
455
+ pipeline_spec_id: Unique identifier of the pipeline spec.
456
+
457
+ Returns:
458
+ The graph with nodes and edges.
459
+
460
+ Raises:
461
+ NotFoundError: If the pipeline spec does not exist.
462
+ Knowledge2Error: If the API request fails.
463
+ """
464
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
465
+ data = self._request(
466
+ "GET",
467
+ f"/v1/pipeline-specs/{pipeline_spec_id}/graph",
468
+ request_options=request_options,
469
+ )
470
+ return self._maybe_validate(data, "GraphResponse")
471
+
472
+ def diff_pipeline_spec(
473
+ self,
474
+ pipeline_spec_id: str,
475
+ request_options: RequestOptions | None = None,
476
+ ) -> dict[str, Any]:
477
+ """Get the diff between the pipeline spec and live resources.
478
+
479
+ Args:
480
+ pipeline_spec_id: Unique identifier of the pipeline spec.
481
+
482
+ Returns:
483
+ The drift report describing differences.
484
+
485
+ Raises:
486
+ NotFoundError: If the pipeline spec does not exist.
487
+ Knowledge2Error: If the API request fails.
488
+ """
489
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
490
+ data = self._request(
491
+ "GET",
492
+ f"/v1/pipeline-specs/{pipeline_spec_id}/diff",
493
+ request_options=request_options,
494
+ )
495
+ return self._maybe_validate(data, "DriftReport")
496
+
497
+ def refresh_pipeline_spec(
498
+ self,
499
+ pipeline_spec_id: str,
500
+ request_options: RequestOptions | None = None,
501
+ ) -> dict[str, Any]:
502
+ """Refresh a pipeline spec from live resource state.
503
+
504
+ Args:
505
+ pipeline_spec_id: Unique identifier of the pipeline spec.
506
+
507
+ Returns:
508
+ The refresh result.
509
+
510
+ Raises:
511
+ NotFoundError: If the pipeline spec does not exist.
512
+ Knowledge2Error: If the API request fails.
513
+ """
514
+ pipeline_spec_id = require_str(pipeline_spec_id, "pipeline_spec_id")
515
+ data = self._request(
516
+ "POST",
517
+ f"/v1/pipeline-specs/{pipeline_spec_id}/refresh",
518
+ request_options=request_options,
519
+ )
520
+ return self._maybe_validate(data, "RefreshResult")
@@ -0,0 +1,87 @@
1
+ """Project resource mixin for the Knowledge2 SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from sdk._paging import Page, SyncPager
8
+ from sdk._request_options import RequestOptions
9
+ from sdk.resources._mixin_base import RequesterMixin
10
+ from sdk.types import ProjectResponse
11
+
12
+
13
+ class ProjectsMixin(RequesterMixin):
14
+ def create_project(
15
+ self,
16
+ name: str,
17
+ *,
18
+ org_id: str | None = None,
19
+ org_name: str | None = None,
20
+ request_options: RequestOptions | None = None,
21
+ ) -> ProjectResponse:
22
+ """Create a new project within an organisation.
23
+
24
+ If neither *org_id* nor *org_name* is supplied, the client's
25
+ default ``org_id`` (if set) is used.
26
+
27
+ Args:
28
+ name: Display name for the project.
29
+ org_id: Explicit organisation ID to own the project.
30
+ org_name: Organisation name (resolved server-side if
31
+ *org_id* is not provided).
32
+
33
+ Returns:
34
+ The newly created project record.
35
+
36
+ Raises:
37
+ Knowledge2Error: If the API request fails.
38
+ """
39
+ payload: dict[str, Any] = {"name": name}
40
+ resolved_org_id = org_id or getattr(self, "org_id", None)
41
+ if resolved_org_id:
42
+ payload["org_id"] = resolved_org_id
43
+ if org_name:
44
+ payload["org_name"] = org_name
45
+ data = self._request("POST", "/v1/projects", json=payload, request_options=request_options)
46
+ return self._maybe_validate(data, "ProjectResponse")
47
+
48
+ def list_projects(
49
+ self,
50
+ limit: int = 100,
51
+ offset: int = 0,
52
+ request_options: RequestOptions | None = None,
53
+ ) -> Page[dict[str, Any]]:
54
+ """List projects accessible to the current credentials.
55
+
56
+ Args:
57
+ limit: Maximum number of projects to return per page.
58
+ offset: Number of projects to skip for pagination.
59
+
60
+ Returns:
61
+ A Page containing project records with pagination metadata.
62
+
63
+ Raises:
64
+ Knowledge2Error: If the API request fails.
65
+ """
66
+ return self._list_page(
67
+ "GET", "/v1/projects", items_key="projects", limit=limit, offset=offset
68
+ )
69
+
70
+ def iter_projects(
71
+ self,
72
+ *,
73
+ limit: int = 100,
74
+ request_options: RequestOptions | None = None,
75
+ ) -> SyncPager[dict[str, Any]]:
76
+ """Iterate over projects, automatically paginating.
77
+
78
+ Args:
79
+ limit: Page size used for each underlying API request.
80
+
81
+ Yields:
82
+ Individual project dicts.
83
+
84
+ Raises:
85
+ Knowledge2Error: If any underlying API request fails.
86
+ """
87
+ return self._paginate("GET", "/v1/projects", items_key="projects", limit=limit)