fraclab-sdk 0.1.0__tar.gz → 0.1.2__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.
Files changed (64) hide show
  1. fraclab_sdk-0.1.2/CHANGELOG.md +50 -0
  2. fraclab_sdk-0.1.0/README.md → fraclab_sdk-0.1.2/PKG-INFO +97 -7
  3. fraclab_sdk-0.1.0/PKG-INFO → fraclab_sdk-0.1.2/README.md +73 -28
  4. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/pyproject.toml +9 -2
  5. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/__init__.py +3 -0
  6. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/devkit/__init__.py +8 -0
  7. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/devkit/validate.py +836 -75
  8. fraclab_sdk-0.1.2/src/fraclab_sdk/specs/__init__.py +22 -0
  9. fraclab_sdk-0.1.2/src/fraclab_sdk/specs/output.py +33 -0
  10. fraclab_sdk-0.1.2/src/fraclab_sdk/version.py +5 -0
  11. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/Home.py +162 -0
  12. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/__init__.py +4 -0
  13. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/__main__.py +48 -0
  14. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/pages/1_Snapshots.py +577 -0
  15. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/pages/2_Browse.py +513 -0
  16. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/pages/3_Selection.py +464 -0
  17. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/pages/4_Run.py +331 -0
  18. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/pages/5_Results.py +298 -0
  19. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/pages/6_Algorithm_Edit.py +116 -0
  20. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/pages/7_Schema_Edit.py +160 -0
  21. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/pages/8_Output_Edit.py +155 -0
  22. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/pages/9_Export_Algorithm.py +386 -0
  23. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/pages/__init__.py +1 -0
  24. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/ui_styles.py +103 -0
  25. fraclab_sdk-0.1.2/src/fraclab_sdk/workbench/utils.py +43 -0
  26. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/algorithm/__init__.py +0 -0
  27. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/algorithm/export.py +0 -0
  28. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/algorithm/library.py +0 -0
  29. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/cli.py +0 -0
  30. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/config.py +0 -0
  31. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/devkit/compile.py +0 -0
  32. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/devkit/export.py +0 -0
  33. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/errors.py +0 -0
  34. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/materialize/__init__.py +0 -0
  35. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/materialize/fsops.py +0 -0
  36. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/materialize/hash.py +0 -0
  37. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/materialize/materializer.py +0 -0
  38. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/models/__init__.py +0 -0
  39. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/models/bundle_manifest.py +0 -0
  40. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/models/dataspec.py +0 -0
  41. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/models/drs.py +0 -0
  42. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/models/output_contract.py +0 -0
  43. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/models/run_output_manifest.py +0 -0
  44. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/results/__init__.py +0 -0
  45. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/results/preview.py +0 -0
  46. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/results/reader.py +0 -0
  47. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/run/__init__.py +0 -0
  48. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/run/logs.py +0 -0
  49. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/run/manager.py +0 -0
  50. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/run/subprocess_runner.py +0 -0
  51. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/runtime/__init__.py +0 -0
  52. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/runtime/artifacts.py +0 -0
  53. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/runtime/data_client.py +0 -0
  54. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/runtime/runner_main.py +0 -0
  55. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/runtime/snapshot_provider.py +0 -0
  56. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/selection/__init__.py +0 -0
  57. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/selection/model.py +0 -0
  58. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/selection/validate.py +0 -0
  59. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/snapshot/__init__.py +0 -0
  60. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/snapshot/index.py +0 -0
  61. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/snapshot/library.py +0 -0
  62. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/snapshot/loader.py +0 -0
  63. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/specs/manifest.py +0 -0
  64. {fraclab_sdk-0.1.0 → fraclab_sdk-0.1.2}/src/fraclab_sdk/utils/io.py +0 -0
@@ -0,0 +1,50 @@
1
+ # Changelog
2
+
3
+ ## 0.1.2
4
+
5
+ ### Validation System Upgrade
6
+ - **InputSpec strict validation**:
7
+ - `json_schema_extra` whitelist enforcement (unknown keys → ERROR, `x_*` prefix → WARNING for extensions)
8
+ - `show_when` canonical operators only: `equals`, `not_equals`, `gt`, `gte`, `lt`, `lte`, `in`, `not_in`
9
+ - Operator aliases (`eq`, `neq`, `nin`) emit WARNING and normalize to canonical form
10
+ - snake_case field path detection with camelCase fix suggestions (UI compatibility)
11
+ - JSON Schema path resolution with `$ref`, `allOf`, `anyOf/oneOf` handling (Pydantic v2 patterns)
12
+ - `enum_labels` must match enum values exactly (missing/extra keys → ERROR)
13
+ - Leaf fields missing `title` emit WARNING
14
+ - **OutputContract policy checks**:
15
+ - Schema structure validation per kind (`frame`, `object`, `blob`, `scalar`)
16
+ - `dimensions` cannot overlap with owner-level keys (`stageId`, `wellId`, `platformId`)
17
+ - `groupPath` depth limit warning (max 4 levels)
18
+ - Invariants validation: dataset references must exist, `sameOwner` level must match
19
+ - Relations validation: dataset/field references must exist, blob/scalar cannot have field relations
20
+ - **Algorithm signature validation**:
21
+ - `main.py` must exist with top-level `run` function
22
+ - `async def run` not supported (sandbox limitation)
23
+ - Exactly 1 positional parameter required (no `*args`, `**kwargs`, keyword-only args)
24
+ - **Export page integration**:
25
+ - Cached validation with mtime-based invalidation (avoids re-running on every rerender)
26
+ - Status badges for InputSpec, OutputContract, Algorithm
27
+ - Validation details expander with fix suggestions for snake_case issues
28
+ - Export blocked when validation errors exist
29
+
30
+ ### Other Changes
31
+ - Export page: Replace "File Status" with "Validation Status" as the primary integrity check; File Inspector in expander (expanded by default); Revalidate button inline with status badges.
32
+ - Schema/Output Edit pages: Show warnings even when validation passes; fix incorrect path passed to `validate_output_contract`.
33
+ - Single .py file import: Now creates full template structure (`schema/`, `dist/`) matching "Create New Algorithm".
34
+ - Algorithm scaffold: Now creates `dist/output_contract.json` template.
35
+ - Flatten exported algorithm zip structure (no top-level version folder in Workbench export).
36
+ - Manifest defaults: add `requires.sdk`, `repository`, `homepage`, `license` to scaffolds and bundled examples.
37
+ - Workbench Run/Results pages prompt users to use the InputSpec/OutputSpec editor Validate actions when UI or artifacts are missing.
38
+ - Workbench pages default sidebar to expanded to avoid being trapped when the Streamlit toolbar is hidden.
39
+ - Keep Streamlit toolbar visible (deploy button hidden) so the sidebar toggle is always accessible.
40
+ - Force sidebar to stay visible via CSS so navigation is always reachable.
41
+ - Hide the sidebar collapse control to keep navigation fixed open.
42
+
43
+ ## 0.1.1
44
+ - Package the Streamlit Workbench inside `fraclab_sdk` with the `fraclab-workbench` entrypoint; optional `workbench` extra pulls UI deps.
45
+ - Restore core scientific deps to the base install (numpy/pandas/scipy/matplotlib/fastapi/rich) while keeping Workbench UI deps optional.
46
+ - Add manifest defaults for `requires.sdk`, `repository`, `homepage`, `license`, and embed the SDK version constant for templating.
47
+ - Update bundled example manifests to include the new metadata fields.
48
+
49
+ ## 0.1.0
50
+ - Initial public SDK release with snapshots, algorithm library, run manager, CLI, and devkit tooling.
@@ -1,6 +1,29 @@
1
+ Metadata-Version: 2.4
2
+ Name: fraclab-sdk
3
+ Version: 0.1.2
4
+ Summary: SDK for managing snapshots, algorithms, and run execution
5
+ Requires-Python: >=3.11,<4.0
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: Programming Language :: Python :: 3.11
8
+ Classifier: Programming Language :: Python :: 3.12
9
+ Classifier: Programming Language :: Python :: 3.13
10
+ Classifier: Programming Language :: Python :: 3.14
11
+ Provides-Extra: workbench
12
+ Requires-Dist: fastapi (>=0.115.0,<0.116.0)
13
+ Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
14
+ Requires-Dist: numpy (>=2.1.1,<3.0.0)
15
+ Requires-Dist: pandas (>=2.2.3,<3.0.0)
16
+ Requires-Dist: pyarrow (>=16.0.0) ; extra == "workbench"
17
+ Requires-Dist: pydantic (>=2.10.0,<3.0.0)
18
+ Requires-Dist: rich (>=13.9.0,<14.0.0)
19
+ Requires-Dist: scipy (>=1.13.1,<2.0.0)
20
+ Requires-Dist: streamlit (>=1.30) ; extra == "workbench"
21
+ Requires-Dist: typer (>=0.15.0,<0.16.0)
22
+ Description-Content-Type: text/markdown
23
+
1
24
  # Fraclab SDK Reference
2
25
 
3
- > 版本: 0.1.0
26
+ > 版本: 0.1.1
4
27
  > Python: >=3.11
5
28
 
6
29
  Fraclab SDK 是一个算法开发与执行框架,帮助算法开发者快速构建、测试和部署数据处理算法。
@@ -23,12 +46,26 @@ Fraclab SDK 是一个算法开发与执行框架,帮助算法开发者快速
23
46
 
24
47
  ## 安装
25
48
 
26
- 使用 wheel 文件安装:
49
+ 轻量安装(核心 SDK / CLI,自动带上科学计算依赖):
50
+
51
+ ```bash
52
+ pip install fraclab-sdk
53
+ ```
54
+
55
+ 安装并启用 Workbench UI:
27
56
 
28
57
  ```bash
29
- pip install fraclab_sdk-0.1.0-py3-none-any.whl
58
+ pip install "fraclab-sdk[workbench]"
59
+ fraclab-workbench # CLI entry point
60
+ # 或
61
+ python -m fraclab_sdk.workbench
30
62
  ```
31
63
 
64
+ ### 依赖说明
65
+
66
+ - 核心安装会自动安装并锁定:`numpy>=2.1.1`, `pandas>=2.2.3`, `scipy>=1.13.1`, `matplotlib>=3.9.2`, `fastapi>=0.115.0`, `rich>=13.9.0`。无需手动再装,避免版本冲突。
67
+ - 可选 `workbench` 额外安装 UI 依赖:`streamlit>=1.30`, `pyarrow>=16.0.0`(`pandas` 已在核心里)。
68
+
32
69
  ---
33
70
 
34
71
  ## 快速开始:编写你的第一个算法
@@ -46,13 +83,63 @@ from fraclab_sdk.runtime import DataClient, ArtifactWriter
46
83
 
47
84
  ### 2. 编写算法入口
48
85
 
49
- 创建 `main.py` 作为算法入口文件:
86
+ 创建 `main.py` 作为算法入口文件。
87
+
88
+ #### 入口函数签名约定
89
+
90
+ **算法入口函数必须严格遵循以下签名:**
91
+
92
+ ```python
93
+ def run(ctx):
94
+ ...
95
+ ```
96
+
97
+ | 约定 | 要求 | 说明 |
98
+ |------|------|------|
99
+ | 文件名 | `main.py` | 必须是 `main.py`,不能是其他名称 |
100
+ | 函数名 | `run` | 必须是 `run`,区分大小写 |
101
+ | 参数 | 仅 `ctx` 一个参数 | SDK 使用 `module.run(ctx)` 调用,**不支持**其他签名 |
102
+ | 返回值 | 无要求 | 返回值会被忽略 |
103
+
104
+ > **警告**: 以下写法都会导致运行失败:
105
+ > ```python
106
+ > # ❌ 错误: 参数名不影响,但参数个数必须是 1
107
+ > def run(ctx, extra_arg): # TypeError: run() missing required argument
108
+ >
109
+ > # ❌ 错误: 函数名错误
110
+ > def execute(ctx): # AttributeError: module has no attribute 'run'
111
+ >
112
+ > # ❌ 错误: 放在其他文件
113
+ > # algorithm.py 中定义 run() # 不会被加载
114
+ > ```
115
+
116
+ #### 最小可运行模板
50
117
 
51
118
  ```python
52
119
  # main.py
53
- from fraclab_sdk.runtime import DataClient, ArtifactWriter
54
- from pathlib import Path
120
+ def run(ctx):
121
+ """算法入口函数 - 最小模板。
55
122
 
123
+ Args:
124
+ ctx: RunContext,包含:
125
+ - ctx.data_client: DataClient 实例
126
+ - ctx.params: dict[str, Any],用户参数
127
+ - ctx.artifacts: ArtifactWriter 实例
128
+ - ctx.logger: logging.Logger 实例
129
+ - ctx.run_context: dict,运行上下文
130
+ """
131
+ logger = ctx.logger
132
+ logger.info("算法开始执行")
133
+
134
+ # 你的逻辑...
135
+
136
+ logger.info("算法执行完成")
137
+ ```
138
+
139
+ #### 完整示例
140
+
141
+ ```python
142
+ # main.py
56
143
  def run(ctx):
57
144
  """算法入口函数。
58
145
 
@@ -313,7 +400,7 @@ aw.write_scalar(
313
400
  "drsPath": "dist/drs.json"
314
401
  },
315
402
  "requires": {
316
- "sdk": "0.1.0",
403
+ "sdk": "0.1.1",
317
404
  "core": "1.0.0"
318
405
  },
319
406
  "repository": "https://github.com/example/my-algorithm",
@@ -826,6 +913,8 @@ $ fraclab-sdk run tail f9e8d7c6
826
913
  $ fraclab-sdk run tail f9e8d7c6 --stderr
827
914
  ```
828
915
 
916
+ > Workbench 提示:结果页面会展示本次运行的输出目录路径(含 `_logs` 日志),即使运行失败也能点开路径定位调试。
917
+
829
918
  #### 6. 运行目录结构
830
919
 
831
920
  执行完成后,`~/.fraclab/runs/<run_id>/` 目录结构:
@@ -1599,3 +1688,4 @@ drs_hash = compute_sha256("drs.json")
1599
1688
  print(f"dsSha256: {ds_hash}")
1600
1689
  print(f"drsSha256: {drs_hash}")
1601
1690
  ```
1691
+
@@ -1,26 +1,6 @@
1
- Metadata-Version: 2.4
2
- Name: fraclab-sdk
3
- Version: 0.1.0
4
- Summary: SDK for managing snapshots, algorithms, and run execution
5
- Requires-Python: >=3.11,<4.0
6
- Classifier: Programming Language :: Python :: 3
7
- Classifier: Programming Language :: Python :: 3.11
8
- Classifier: Programming Language :: Python :: 3.12
9
- Classifier: Programming Language :: Python :: 3.13
10
- Classifier: Programming Language :: Python :: 3.14
11
- Requires-Dist: fastapi (>=0.115.0,<0.116.0)
12
- Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
13
- Requires-Dist: numpy (>=2.1.1,<3.0.0)
14
- Requires-Dist: pandas (>=2.2.3,<3.0.0)
15
- Requires-Dist: pydantic (>=2.10.0,<3.0.0)
16
- Requires-Dist: rich (>=13.9.0,<14.0.0)
17
- Requires-Dist: scipy (>=1.13.1,<2.0.0)
18
- Requires-Dist: typer (>=0.15.0,<0.16.0)
19
- Description-Content-Type: text/markdown
20
-
21
1
  # Fraclab SDK Reference
22
2
 
23
- > 版本: 0.1.0
3
+ > 版本: 0.1.1
24
4
  > Python: >=3.11
25
5
 
26
6
  Fraclab SDK 是一个算法开发与执行框架,帮助算法开发者快速构建、测试和部署数据处理算法。
@@ -43,12 +23,26 @@ Fraclab SDK 是一个算法开发与执行框架,帮助算法开发者快速
43
23
 
44
24
  ## 安装
45
25
 
46
- 使用 wheel 文件安装:
26
+ 轻量安装(核心 SDK / CLI,自动带上科学计算依赖):
27
+
28
+ ```bash
29
+ pip install fraclab-sdk
30
+ ```
31
+
32
+ 安装并启用 Workbench UI:
47
33
 
48
34
  ```bash
49
- pip install fraclab_sdk-0.1.0-py3-none-any.whl
35
+ pip install "fraclab-sdk[workbench]"
36
+ fraclab-workbench # CLI entry point
37
+ # 或
38
+ python -m fraclab_sdk.workbench
50
39
  ```
51
40
 
41
+ ### 依赖说明
42
+
43
+ - 核心安装会自动安装并锁定:`numpy>=2.1.1`, `pandas>=2.2.3`, `scipy>=1.13.1`, `matplotlib>=3.9.2`, `fastapi>=0.115.0`, `rich>=13.9.0`。无需手动再装,避免版本冲突。
44
+ - 可选 `workbench` 额外安装 UI 依赖:`streamlit>=1.30`, `pyarrow>=16.0.0`(`pandas` 已在核心里)。
45
+
52
46
  ---
53
47
 
54
48
  ## 快速开始:编写你的第一个算法
@@ -66,13 +60,63 @@ from fraclab_sdk.runtime import DataClient, ArtifactWriter
66
60
 
67
61
  ### 2. 编写算法入口
68
62
 
69
- 创建 `main.py` 作为算法入口文件:
63
+ 创建 `main.py` 作为算法入口文件。
64
+
65
+ #### 入口函数签名约定
66
+
67
+ **算法入口函数必须严格遵循以下签名:**
68
+
69
+ ```python
70
+ def run(ctx):
71
+ ...
72
+ ```
73
+
74
+ | 约定 | 要求 | 说明 |
75
+ |------|------|------|
76
+ | 文件名 | `main.py` | 必须是 `main.py`,不能是其他名称 |
77
+ | 函数名 | `run` | 必须是 `run`,区分大小写 |
78
+ | 参数 | 仅 `ctx` 一个参数 | SDK 使用 `module.run(ctx)` 调用,**不支持**其他签名 |
79
+ | 返回值 | 无要求 | 返回值会被忽略 |
80
+
81
+ > **警告**: 以下写法都会导致运行失败:
82
+ > ```python
83
+ > # ❌ 错误: 参数名不影响,但参数个数必须是 1
84
+ > def run(ctx, extra_arg): # TypeError: run() missing required argument
85
+ >
86
+ > # ❌ 错误: 函数名错误
87
+ > def execute(ctx): # AttributeError: module has no attribute 'run'
88
+ >
89
+ > # ❌ 错误: 放在其他文件
90
+ > # algorithm.py 中定义 run() # 不会被加载
91
+ > ```
92
+
93
+ #### 最小可运行模板
70
94
 
71
95
  ```python
72
96
  # main.py
73
- from fraclab_sdk.runtime import DataClient, ArtifactWriter
74
- from pathlib import Path
97
+ def run(ctx):
98
+ """算法入口函数 - 最小模板。
75
99
 
100
+ Args:
101
+ ctx: RunContext,包含:
102
+ - ctx.data_client: DataClient 实例
103
+ - ctx.params: dict[str, Any],用户参数
104
+ - ctx.artifacts: ArtifactWriter 实例
105
+ - ctx.logger: logging.Logger 实例
106
+ - ctx.run_context: dict,运行上下文
107
+ """
108
+ logger = ctx.logger
109
+ logger.info("算法开始执行")
110
+
111
+ # 你的逻辑...
112
+
113
+ logger.info("算法执行完成")
114
+ ```
115
+
116
+ #### 完整示例
117
+
118
+ ```python
119
+ # main.py
76
120
  def run(ctx):
77
121
  """算法入口函数。
78
122
 
@@ -333,7 +377,7 @@ aw.write_scalar(
333
377
  "drsPath": "dist/drs.json"
334
378
  },
335
379
  "requires": {
336
- "sdk": "0.1.0",
380
+ "sdk": "0.1.1",
337
381
  "core": "1.0.0"
338
382
  },
339
383
  "repository": "https://github.com/example/my-algorithm",
@@ -846,6 +890,8 @@ $ fraclab-sdk run tail f9e8d7c6
846
890
  $ fraclab-sdk run tail f9e8d7c6 --stderr
847
891
  ```
848
892
 
893
+ > Workbench 提示:结果页面会展示本次运行的输出目录路径(含 `_logs` 日志),即使运行失败也能点开路径定位调试。
894
+
849
895
  #### 6. 运行目录结构
850
896
 
851
897
  执行完成后,`~/.fraclab/runs/<run_id>/` 目录结构:
@@ -1619,4 +1665,3 @@ drs_hash = compute_sha256("drs.json")
1619
1665
  print(f"dsSha256: {ds_hash}")
1620
1666
  print(f"drsSha256: {drs_hash}")
1621
1667
  ```
1622
-
@@ -1,11 +1,12 @@
1
1
  [tool.poetry]
2
2
  name = "fraclab-sdk"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "SDK for managing snapshots, algorithms, and run execution"
5
5
  authors = []
6
6
  readme = "README.md"
7
7
  include = [
8
- { path = "README.md", format = ["sdist", "wheel"] }
8
+ { path = "README.md", format = ["sdist", "wheel"] },
9
+ { path = "CHANGELOG.md", format = ["sdist", "wheel"] },
9
10
  ]
10
11
  packages = [{ include = "fraclab_sdk", from = "src" }]
11
12
 
@@ -19,15 +20,21 @@ pandas = "^2.2.3"
19
20
  scipy = "^1.13.1"
20
21
  matplotlib = "^3.9.2"
21
22
  fastapi = "^0.115.0"
23
+ streamlit = {version = ">=1.30", optional = true}
24
+ pyarrow = {version = ">=16.0.0", optional = true}
22
25
 
23
26
  [tool.poetry.group.dev.dependencies]
24
27
  ruff = "^0.8.0"
25
28
  pytest = "^8.3.0"
26
29
  pytest-cov = "^6.0.0"
27
30
 
31
+ [tool.poetry.extras]
32
+ workbench = ["streamlit", "pyarrow"]
33
+
28
34
  [tool.poetry.scripts]
29
35
  fraclab-runner = "fraclab_sdk.runtime.runner_main:main"
30
36
  fraclab-sdk = "fraclab_sdk.cli:main"
37
+ fraclab-workbench = "fraclab_sdk.workbench.__main__:main"
31
38
 
32
39
  [build-system]
33
40
  requires = ["poetry-core"]
@@ -7,6 +7,7 @@ from fraclab_sdk.results import ResultReader
7
7
  from fraclab_sdk.run import RunManager, RunMeta, RunResult, RunStatus
8
8
  from fraclab_sdk.selection.model import SelectionModel
9
9
  from fraclab_sdk.snapshot import SnapshotHandle, SnapshotLibrary, SnapshotMeta
10
+ from fraclab_sdk.version import __version__
10
11
 
11
12
  __all__ = [
12
13
  # Config
@@ -31,4 +32,6 @@ __all__ = [
31
32
  "RunStatus",
32
33
  # Results
33
34
  "ResultReader",
35
+ # Package metadata
36
+ "__version__",
34
37
  ]
@@ -9,6 +9,10 @@ This module provides tools for:
9
9
  from fraclab_sdk.devkit.compile import compile_algorithm
10
10
  from fraclab_sdk.devkit.export import export_algorithm_package
11
11
  from fraclab_sdk.devkit.validate import (
12
+ ValidationIssue,
13
+ ValidationResult,
14
+ ValidationSeverity,
15
+ validate_algorithm_signature,
12
16
  validate_bundle,
13
17
  validate_inputspec,
14
18
  validate_output_contract,
@@ -18,6 +22,10 @@ from fraclab_sdk.devkit.validate import (
18
22
  __all__ = [
19
23
  "compile_algorithm",
20
24
  "export_algorithm_package",
25
+ "ValidationSeverity",
26
+ "ValidationIssue",
27
+ "ValidationResult",
28
+ "validate_algorithm_signature",
21
29
  "validate_bundle",
22
30
  "validate_inputspec",
23
31
  "validate_output_contract",