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.
@@ -0,0 +1,91 @@
1
+ """Shared UI styling utility for Streamlit pages."""
2
+
3
+ import streamlit as st
4
+
5
+
6
+ def apply_global_styles():
7
+ """Inject global CSS to hide Streamlit UI elements and apply common styling."""
8
+ st.markdown("""
9
+ <style>
10
+ /* =================================
11
+ 1. Hide Streamlit UI Elements
12
+ ================================= */
13
+
14
+ /* Hide top header bar */
15
+ header[data-testid="stHeader"] {
16
+ display: none !important;
17
+ }
18
+
19
+ /* Hide hamburger menu and Deploy button */
20
+ [data-testid="stToolbar"], .stDeployButton {
21
+ display: none !important;
22
+ }
23
+
24
+ /* Hide footer (Made with Streamlit) */
25
+ footer {
26
+ display: none !important;
27
+ }
28
+
29
+ /* Hide element toolbar on tables/dataframes */
30
+ [data-testid="stElementToolbar"] {
31
+ display: none !important;
32
+ }
33
+
34
+ /* Adjust main content padding (header hidden, content needs padding) */
35
+ .main .block-container {
36
+ padding-top: 2rem !important;
37
+ padding-bottom: 2rem !important;
38
+ }
39
+
40
+ /* =================================
41
+ 2. Button Styling
42
+ ================================= */
43
+
44
+ div[data-testid="stButton"] button {
45
+ white-space: nowrap !important;
46
+ border-radius: 6px !important;
47
+ min-width: 60px !important;
48
+ font-weight: 500 !important;
49
+ }
50
+
51
+ /* =================================
52
+ 3. Anti-Copy Protection
53
+ ================================= */
54
+
55
+ /* Disable text selection on key areas */
56
+ .element-container,
57
+ [data-testid="stDataFrame"],
58
+ [data-testid="stDataEditor"],
59
+ [data-testid="stCode"],
60
+ [data-testid="stJson"] {
61
+ user-select: none;
62
+ -webkit-user-select: none;
63
+ -moz-user-select: none;
64
+ -ms-user-select: none;
65
+ }
66
+
67
+ /* Hide copy buttons on st.code / st.json */
68
+ [data-testid="stCode"] button,
69
+ [data-testid="stJson"] button {
70
+ display: none !important;
71
+ }
72
+
73
+ /* =================================
74
+ 4. Component Styling
75
+ ================================= */
76
+
77
+ /* Expander header styling */
78
+ .streamlit-expanderHeader {
79
+ font-weight: 600;
80
+ background-color: #f9f9fb;
81
+ border-radius: 6px;
82
+ }
83
+
84
+ /* Data Editor border styling */
85
+ [data-testid="stDataEditor"] {
86
+ border: 1px solid #e6e9ef;
87
+ border-radius: 6px;
88
+ }
89
+
90
+ </style>
91
+ """, unsafe_allow_html=True)
@@ -0,0 +1,43 @@
1
+ """Shared helpers for the Streamlit workbench."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import subprocess
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from fraclab_sdk.config import SDKConfig
11
+
12
+ # Keep a dedicated workspace separate from the installed algorithm library.
13
+ WORKSPACE_ALGOS_SUBDIR = "workspace_algorithms"
14
+
15
+
16
+ def get_workspace_dir(config: SDKConfig) -> Path:
17
+ """Return the workspace directory for editable algorithms."""
18
+ workspace = config.sdk_home / WORKSPACE_ALGOS_SUBDIR
19
+ workspace.mkdir(parents=True, exist_ok=True)
20
+ return workspace
21
+
22
+
23
+ def run_workspace_script(workspace: Path, script: str, timeout: int = 30) -> subprocess.CompletedProcess:
24
+ """Run a Python snippet with the workspace on PYTHONPATH."""
25
+ pythonpath = [str(workspace)]
26
+ existing = os.environ.get("PYTHONPATH")
27
+ if existing:
28
+ pythonpath.append(existing)
29
+
30
+ env = {
31
+ **os.environ,
32
+ "PYTHONPATH": os.pathsep.join(pythonpath),
33
+ "PYTHONUNBUFFERED": "1",
34
+ }
35
+
36
+ return subprocess.run(
37
+ [sys.executable, "-c", script],
38
+ cwd=workspace,
39
+ env=env,
40
+ capture_output=True,
41
+ text=True,
42
+ timeout=timeout,
43
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: fraclab-sdk
3
- Version: 0.1.0
3
+ Version: 0.1.1
4
4
  Summary: SDK for managing snapshots, algorithms, and run execution
5
5
  Requires-Python: >=3.11,<4.0
6
6
  Classifier: Programming Language :: Python :: 3
@@ -8,19 +8,22 @@ Classifier: Programming Language :: Python :: 3.11
8
8
  Classifier: Programming Language :: Python :: 3.12
9
9
  Classifier: Programming Language :: Python :: 3.13
10
10
  Classifier: Programming Language :: Python :: 3.14
11
+ Provides-Extra: workbench
11
12
  Requires-Dist: fastapi (>=0.115.0,<0.116.0)
12
13
  Requires-Dist: matplotlib (>=3.9.2,<4.0.0)
13
14
  Requires-Dist: numpy (>=2.1.1,<3.0.0)
14
15
  Requires-Dist: pandas (>=2.2.3,<3.0.0)
16
+ Requires-Dist: pyarrow (>=16.0.0) ; extra == "workbench"
15
17
  Requires-Dist: pydantic (>=2.10.0,<3.0.0)
16
18
  Requires-Dist: rich (>=13.9.0,<14.0.0)
17
19
  Requires-Dist: scipy (>=1.13.1,<2.0.0)
20
+ Requires-Dist: streamlit (>=1.30) ; extra == "workbench"
18
21
  Requires-Dist: typer (>=0.15.0,<0.16.0)
19
22
  Description-Content-Type: text/markdown
20
23
 
21
24
  # Fraclab SDK Reference
22
25
 
23
- > 版本: 0.1.0
26
+ > 版本: 0.1.1
24
27
  > Python: >=3.11
25
28
 
26
29
  Fraclab SDK 是一个算法开发与执行框架,帮助算法开发者快速构建、测试和部署数据处理算法。
@@ -43,12 +46,26 @@ Fraclab SDK 是一个算法开发与执行框架,帮助算法开发者快速
43
46
 
44
47
  ## 安装
45
48
 
46
- 使用 wheel 文件安装:
49
+ 轻量安装(核心 SDK / CLI,自动带上科学计算依赖):
47
50
 
48
51
  ```bash
49
- pip install fraclab_sdk-0.1.0-py3-none-any.whl
52
+ pip install fraclab-sdk
50
53
  ```
51
54
 
55
+ 安装并启用 Workbench UI:
56
+
57
+ ```bash
58
+ pip install "fraclab-sdk[workbench]"
59
+ fraclab-workbench # CLI entry point
60
+ # 或
61
+ python -m fraclab_sdk.workbench
62
+ ```
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
+
52
69
  ---
53
70
 
54
71
  ## 快速开始:编写你的第一个算法
@@ -66,13 +83,63 @@ from fraclab_sdk.runtime import DataClient, ArtifactWriter
66
83
 
67
84
  ### 2. 编写算法入口
68
85
 
69
- 创建 `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
+ #### 最小可运行模板
70
117
 
71
118
  ```python
72
119
  # main.py
73
- from fraclab_sdk.runtime import DataClient, ArtifactWriter
74
- from pathlib import Path
120
+ def run(ctx):
121
+ """算法入口函数 - 最小模板。
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
+ #### 完整示例
75
140
 
141
+ ```python
142
+ # main.py
76
143
  def run(ctx):
77
144
  """算法入口函数。
78
145
 
@@ -333,7 +400,7 @@ aw.write_scalar(
333
400
  "drsPath": "dist/drs.json"
334
401
  },
335
402
  "requires": {
336
- "sdk": "0.1.0",
403
+ "sdk": "0.1.1",
337
404
  "core": "1.0.0"
338
405
  },
339
406
  "repository": "https://github.com/example/my-algorithm",
@@ -1,4 +1,4 @@
1
- README.md,sha256=M6jzlivo3RM9xT8zoHprRD_dbYK0psdn_EGE7Of9Y6c,42564
1
+ README.md,sha256=XK2y0q8psA07V2QQHVSFLN4jpZVq5dLHgViwNYck_8M,44415
2
2
  fraclab_sdk/__init__.py,sha256=6SycB79WDBLT3QwAWVEMVHMOz_vETyo3ZZ0IbAsmTPE,924
3
3
  fraclab_sdk/algorithm/__init__.py,sha256=-tAQkdAWWh_MlQMszsz0XAUR9aJ8oOxu8gUsUTmLyHA,220
4
4
  fraclab_sdk/algorithm/export.py,sha256=axOWsDUF6K5Ru2eIb0hcjk8t4md4u-gnZGjK3JaRoGo,39
@@ -39,9 +39,26 @@ fraclab_sdk/snapshot/__init__.py,sha256=RPp-tt85xnecO4tkXLl1BClcjxVKvmAnhlpyomRz
39
39
  fraclab_sdk/snapshot/index.py,sha256=8hsRm6QB1taDhUk6cLqkrxQWzwj6E05I0YLB5S0H3Ms,2942
40
40
  fraclab_sdk/snapshot/library.py,sha256=3rq2s7nirI5blOzfGet1rtuk-f18qOq5MuAsUP2ruZw,7000
41
41
  fraclab_sdk/snapshot/loader.py,sha256=ni9gdFQjAcIavdA9AoMMMtEJeEypOzK0dEbvygaaAh4,7578
42
+ fraclab_sdk/specs/__init__.py,sha256=aOQ8FBSgRLmJGDYZFMOKqhWu0O1YllQcIZfC_gK-Oqs,452
42
43
  fraclab_sdk/specs/manifest.py,sha256=D3CyMt07p_uBI5Dw0NFfzUhzS2JZafaGxuxXFZ8J938,2597
44
+ fraclab_sdk/specs/output.py,sha256=Tg1eT6f31TaeKj8pZUABzXJeO55H5ieWAldw93iyRiY,729
43
45
  fraclab_sdk/utils/io.py,sha256=L4EoReyx13wQqj0qaloMcNGSuEanZDHEk5A8rI-OCJQ,786
44
- fraclab_sdk-0.1.0.dist-info/METADATA,sha256=zzxbqZvIESl9b1EpY2WNnrBlfrbPsGHS9KZXZLERaz4,43333
45
- fraclab_sdk-0.1.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
46
- fraclab_sdk-0.1.0.dist-info/entry_points.txt,sha256=DItrlEkztJy6iRBqOYj4XpMN6GVlHOcluAqhsL3QnSg,104
47
- fraclab_sdk-0.1.0.dist-info/RECORD,,
46
+ fraclab_sdk/workbench/Home.py,sha256=RhSNLH3t3m6LYIrBaryrsME8z5m4BrGDCTdYA352ig8,4487
47
+ fraclab_sdk/workbench/__init__.py,sha256=eZnXHbvRbv6unD1BZ4T7SmyYMF1UKd-Nt6t11QuYSvM,204
48
+ fraclab_sdk/workbench/__main__.py,sha256=Pkh79m5GnE20HlY72c4-7nshpy39jqkkbEIJ5k1lL1g,1333
49
+ fraclab_sdk/workbench/pages/1_Snapshots.py,sha256=522dIziu8-ZuSqI8y_ikeeAYukU0cPV5DcOVZM_awo8,21075
50
+ fraclab_sdk/workbench/pages/2_Browse.py,sha256=yqS0AfBVF4FXtb17elQ9oxU6fTuzl5XLk8c5f8xIW8c,17283
51
+ fraclab_sdk/workbench/pages/3_Selection.py,sha256=q2o_OF5AWa-tZFmJ2XAlVHcAWYKJAIYKncM9Egi8Wog,18319
52
+ fraclab_sdk/workbench/pages/4_Run.py,sha256=BIdzJ7ulWvD84XrIh_7xQ4O1nSuKDfARlAQ4AKJnFFc,12705
53
+ fraclab_sdk/workbench/pages/5_Results.py,sha256=7ZHID3LUDX7eRW38he0jzcF3rlJNy9CFRDwFgMuwuK8,11305
54
+ fraclab_sdk/workbench/pages/6_Algorithm_Edit.py,sha256=nkTv2rQgLQoiXB-RoS8RgUksv0CFhL0hmF0hvH2akNI,4113
55
+ fraclab_sdk/workbench/pages/7_Schema_Edit.py,sha256=PA_5FaPdGdVdO6n3MONCU9_6k3oYMK4DNZUhA0_IKhs,5019
56
+ fraclab_sdk/workbench/pages/8_Output_Edit.py,sha256=CcdBCdK-6YNE1P8cud0mx2zXcYlLAuRwbnv7n-7GLSs,5080
57
+ fraclab_sdk/workbench/pages/9_Export_Algorithm.py,sha256=3YaHc5K4zvxR0K-JS8sk_q59cbK-I6i9F1CdEKZBcpQ,8561
58
+ fraclab_sdk/workbench/pages/__init__.py,sha256=Et0iV4dhbgkeKKuhmffpYzhDjvWM7IheHh3feDQ4J2M,54
59
+ fraclab_sdk/workbench/ui_styles.py,sha256=o06r6Cv1VV8ita2-tmcGYxbdL6-JkPSY2K3AvnSYhuw,2656
60
+ fraclab_sdk/workbench/utils.py,sha256=0rcKo8_zIYHQ2kwuEjAf15ara6okpJViFPyW2F_SPx4,1179
61
+ fraclab_sdk-0.1.1.dist-info/METADATA,sha256=EsM2mrdD3yBelfuq1SmdMNkCJg0f1jRJkwFiVg5P_fw,45324
62
+ fraclab_sdk-0.1.1.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
63
+ fraclab_sdk-0.1.1.dist-info/entry_points.txt,sha256=R6jqSgmf7jB4xMgsTe0M-X9j6JtQQfaedku4Dppmwww,158
64
+ fraclab_sdk-0.1.1.dist-info/RECORD,,
@@ -1,4 +1,5 @@
1
1
  [console_scripts]
2
2
  fraclab-runner=fraclab_sdk.runtime.runner_main:main
3
3
  fraclab-sdk=fraclab_sdk.cli:main
4
+ fraclab-workbench=fraclab_sdk.workbench.__main__:main
4
5