fraclab-sdk 0.1.0__py3-none-any.whl → 0.1.1__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.
README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Fraclab SDK Reference
2
2
 
3
- > 版本: 0.1.0
3
+ > 版本: 0.1.1
4
4
  > Python: >=3.11
5
5
 
6
6
  Fraclab SDK 是一个算法开发与执行框架,帮助算法开发者快速构建、测试和部署数据处理算法。
@@ -23,12 +23,26 @@ Fraclab SDK 是一个算法开发与执行框架,帮助算法开发者快速
23
23
 
24
24
  ## 安装
25
25
 
26
- 使用 wheel 文件安装:
26
+ 轻量安装(核心 SDK / CLI,自动带上科学计算依赖):
27
27
 
28
28
  ```bash
29
- pip install fraclab_sdk-0.1.0-py3-none-any.whl
29
+ pip install fraclab-sdk
30
30
  ```
31
31
 
32
+ 安装并启用 Workbench UI:
33
+
34
+ ```bash
35
+ pip install "fraclab-sdk[workbench]"
36
+ fraclab-workbench # CLI entry point
37
+ # 或
38
+ python -m fraclab_sdk.workbench
39
+ ```
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
+
32
46
  ---
33
47
 
34
48
  ## 快速开始:编写你的第一个算法
@@ -46,13 +60,63 @@ from fraclab_sdk.runtime import DataClient, ArtifactWriter
46
60
 
47
61
  ### 2. 编写算法入口
48
62
 
49
- 创建 `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
+ #### 最小可运行模板
50
94
 
51
95
  ```python
52
96
  # main.py
53
- from fraclab_sdk.runtime import DataClient, ArtifactWriter
54
- from pathlib import Path
97
+ def run(ctx):
98
+ """算法入口函数 - 最小模板。
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
+ #### 完整示例
55
117
 
118
+ ```python
119
+ # main.py
56
120
  def run(ctx):
57
121
  """算法入口函数。
58
122
 
@@ -313,7 +377,7 @@ aw.write_scalar(
313
377
  "drsPath": "dist/drs.json"
314
378
  },
315
379
  "requires": {
316
- "sdk": "0.1.0",
380
+ "sdk": "0.1.1",
317
381
  "core": "1.0.0"
318
382
  },
319
383
  "repository": "https://github.com/example/my-algorithm",
@@ -0,0 +1,22 @@
1
+ """Spec helpers and manifest definitions."""
2
+
3
+ from .manifest import FracLabAlgorithmManifestV1, ManifestVersion
4
+ from .output import (
5
+ BlobSchema,
6
+ FrameSchema,
7
+ ObjectSchema,
8
+ OutputContract,
9
+ OutputDatasetContract,
10
+ ScalarSchema,
11
+ )
12
+
13
+ __all__ = [
14
+ "FracLabAlgorithmManifestV1",
15
+ "ManifestVersion",
16
+ "OutputContract",
17
+ "OutputDatasetContract",
18
+ "BlobSchema",
19
+ "ObjectSchema",
20
+ "ScalarSchema",
21
+ "FrameSchema",
22
+ ]
@@ -0,0 +1,33 @@
1
+ """OutputSpec helpers re-exporting models for schema definitions."""
2
+
3
+ from fraclab_sdk.models.output_contract import (
4
+ BlobOutputSchema,
5
+ Cardinality,
6
+ DatasetKind,
7
+ DatasetRole,
8
+ FrameOutputSchema,
9
+ ObjectOutputSchema,
10
+ OutputContract,
11
+ OutputDatasetContract,
12
+ OwnerType,
13
+ ScalarOutputSchema,
14
+ )
15
+
16
+ # Backward-friendly aliases used by workspace schemas
17
+ BlobSchema = BlobOutputSchema
18
+ ObjectSchema = ObjectOutputSchema
19
+ ScalarSchema = ScalarOutputSchema
20
+ FrameSchema = FrameOutputSchema
21
+
22
+ __all__ = [
23
+ "BlobSchema",
24
+ "ObjectSchema",
25
+ "ScalarSchema",
26
+ "FrameSchema",
27
+ "OutputContract",
28
+ "OutputDatasetContract",
29
+ "OwnerType",
30
+ "DatasetKind",
31
+ "DatasetRole",
32
+ "Cardinality",
33
+ ]
@@ -0,0 +1,162 @@
1
+ """Fraclab SDK Workbench - Home Page."""
2
+
3
+ import streamlit as st
4
+
5
+ from fraclab_sdk.workbench import ui_styles
6
+ from fraclab_sdk.algorithm import AlgorithmLibrary
7
+ from fraclab_sdk.config import SDKConfig
8
+ from fraclab_sdk.run import RunManager
9
+ from fraclab_sdk.snapshot import SnapshotLibrary
10
+
11
+ st.set_page_config(
12
+ page_title="Fraclab SDK Workbench",
13
+ page_icon="🔬",
14
+ layout="wide",
15
+ initial_sidebar_state="expanded"
16
+ )
17
+
18
+ ui_styles.apply_global_styles()
19
+
20
+ # --- Page-Specific Styling ---
21
+ st.markdown("""
22
+ <style>
23
+ /* Title styling */
24
+ h1 {
25
+ font-family: 'Source Sans Pro', sans-serif;
26
+ font-weight: 700;
27
+ color: #1f2937;
28
+ }
29
+
30
+ /* Metric value highlight */
31
+ [data-testid="stMetricValue"] {
32
+ font-size: 2rem !important;
33
+ color: #2563eb;
34
+ }
35
+
36
+ /* Info box styling */
37
+ .info-box {
38
+ background-color: #f8fafc;
39
+ border: 1px solid #e2e8f0;
40
+ padding: 15px;
41
+ border-radius: 8px;
42
+ font-family: monospace;
43
+ color: #475569;
44
+ }
45
+
46
+ /* Hero section styling */
47
+ .hero-container {
48
+ padding: 2rem 0;
49
+ margin-bottom: 2rem;
50
+ border-bottom: 1px solid #e6e9ef;
51
+ }
52
+ .hero-sub {
53
+ font-size: 1.2rem;
54
+ color: #64748b;
55
+ }
56
+ </style>
57
+ """, unsafe_allow_html=True)
58
+
59
+
60
+ # --- 2. Hero Section ---
61
+ st.markdown("""
62
+ <div class="hero-container">
63
+ <h1>Fraclab SDK Workbench</h1>
64
+ <div class="hero-sub">The unified platform for algorithm development, testing, and deployment.</div>
65
+ </div>
66
+ """, unsafe_allow_html=True)
67
+
68
+
69
+ def show_dashboard():
70
+ """Show SDK status overview cards."""
71
+ try:
72
+ config = SDKConfig()
73
+ snapshot_lib = SnapshotLibrary(config)
74
+ algorithm_lib = AlgorithmLibrary(config)
75
+ run_manager = RunManager(config)
76
+
77
+ snap_count = len(snapshot_lib.list_snapshots())
78
+ algo_count = len(algorithm_lib.list_algorithms())
79
+ run_count = len(run_manager.list_runs())
80
+ sdk_home = config.sdk_home
81
+
82
+ except Exception as e:
83
+ st.error(f"Failed to initialize SDK: {e}")
84
+ return
85
+
86
+ # --- Metrics Dashboard ---
87
+ st.subheader("System Status")
88
+
89
+ c1, c2, c3 = st.columns(3)
90
+
91
+ with c1:
92
+ with st.container(border=True):
93
+ st.metric("📦 Snapshots", snap_count, delta="Data Bundles")
94
+
95
+ with c2:
96
+ with st.container(border=True):
97
+ st.metric("🧩 Algorithms", algo_count, delta="Calculations")
98
+
99
+ with c3:
100
+ with st.container(border=True):
101
+ st.metric("🚀 Runs", run_count, delta="Executions")
102
+
103
+ # --- Config Info ---
104
+ st.write("") # Spacer
105
+ with st.container(border=True):
106
+ col_lbl, col_val = st.columns([1, 6])
107
+ with col_lbl:
108
+ st.markdown("**SDK Home:**")
109
+ with col_val:
110
+ st.code(str(sdk_home), language="bash")
111
+
112
+
113
+ show_dashboard()
114
+
115
+ st.divider()
116
+
117
+ # --- 3. Visual Workflow Guide ---
118
+ st.subheader("Workflow Guide")
119
+
120
+ # Grid layout for workflow steps
121
+ row1_col1, row1_col2, row1_col3 = st.columns(3)
122
+ row2_col1, row2_col2 = st.columns(2)
123
+
124
+ # Step 1: Snapshots
125
+ with row1_col1:
126
+ with st.container(border=True):
127
+ st.markdown("#### 1. Import Data")
128
+ st.caption("Go to **Snapshots**")
129
+ st.markdown("Upload zip bundles containing your input data (Parquet/NDJSON) and Data Requirement Specs (DRS).")
130
+
131
+ # Step 2: Browse
132
+ with row1_col2:
133
+ with st.container(border=True):
134
+ st.markdown("#### 2. Inspect")
135
+ st.caption("Go to **Browse**")
136
+ st.markdown("Visualize dataset contents, check schemas, and verify file integrity before running calculations.")
137
+
138
+ # Step 3: Selection
139
+ with row1_col3:
140
+ with st.container(border=True):
141
+ st.markdown("#### 3. Configure")
142
+ st.caption("Go to **Selection**")
143
+ st.markdown("Pair an Algorithm with a Snapshot. Select specific data items and tweak JSON parameters.")
144
+
145
+ # Step 4: Run
146
+ with row2_col1:
147
+ with st.container(border=True):
148
+ st.markdown("#### 4. Execute")
149
+ st.caption("Go to **Run**")
150
+ st.markdown("Monitor pending jobs, view live execution status, and manage timeout settings.")
151
+
152
+ # Step 5: Results
153
+ with row2_col2:
154
+ with st.container(border=True):
155
+ st.markdown("#### 5. Analyze")
156
+ st.caption("Go to **Results**")
157
+ st.markdown("View generated artifacts, plots, metrics, and download output files.")
158
+
159
+ # Footer spacing
160
+ st.write("")
161
+ st.write("")
162
+ st.caption("© 2026 Fraclab SDK. All systems operational.")
@@ -0,0 +1,4 @@
1
+ """Workbench UI packaged with the Fraclab SDK."""
2
+
3
+ # Export a helper so callers can invoke programmatically without the CLI.
4
+ from fraclab_sdk.workbench.__main__ import main as run_workbench # noqa: F401
@@ -0,0 +1,48 @@
1
+ """CLI entrypoint for launching the Streamlit workbench."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import sys
7
+ from pathlib import Path
8
+ from typing import Sequence
9
+
10
+
11
+ def _require_optional_deps() -> None:
12
+ """Fail fast with a clear message when optional deps are missing."""
13
+ missing = []
14
+ try:
15
+ import streamlit # noqa: F401
16
+ except ImportError:
17
+ missing.append("streamlit>=1.30")
18
+ try:
19
+ import pandas # noqa: F401
20
+ except ImportError:
21
+ missing.append("pandas")
22
+
23
+ if missing:
24
+ deps = ", ".join(missing)
25
+ raise SystemExit(
26
+ f"Workbench dependencies missing ({deps}). "
27
+ "Install with `pip install fraclab-sdk[workbench]`."
28
+ )
29
+
30
+
31
+ def main(argv: Sequence[str] | None = None) -> None:
32
+ """Launch the Streamlit app using the bundled Home.py."""
33
+ _require_optional_deps()
34
+ from streamlit.web import cli as stcli
35
+
36
+ workbench_dir = Path(__file__).resolve().parent
37
+ home_path = workbench_dir / "Home.py"
38
+ if not home_path.exists():
39
+ raise SystemExit(f"Workbench entry script not found: {home_path}")
40
+
41
+ extra_args = list(argv) if argv is not None else sys.argv[1:]
42
+ sys.argv = ["streamlit", "run", str(home_path), *extra_args]
43
+ os.chdir(workbench_dir)
44
+ stcli.main()
45
+
46
+
47
+ if __name__ == "__main__":
48
+ main()