biopro-sdk 1.0.0__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.
- biopro_sdk-1.0.0/PKG-INFO +142 -0
- biopro_sdk-1.0.0/README.md +130 -0
- biopro_sdk-1.0.0/pyproject.toml +27 -0
- biopro_sdk-1.0.0/setup.cfg +4 -0
- biopro_sdk-1.0.0/src/biopro_sdk/__init__.py +145 -0
- biopro_sdk-1.0.0/src/biopro_sdk/contrib/__init__.py +38 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/__init__.py +38 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/ai.py +403 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/analysis.py +206 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/base.py +267 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/docs.py +44 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/events.py +87 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/interfaces.py +44 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/managed_task.py +50 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/preferences.py +37 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/signals.py +45 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/state.py +59 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/trust_manager.py +439 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/trust_overrides.py +109 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/trust_path.py +45 -0
- biopro_sdk-1.0.0/src/biopro_sdk/core/trust_storage.py +102 -0
- biopro_sdk-1.0.0/src/biopro_sdk/sdk_cli.py +368 -0
- biopro_sdk-1.0.0/src/biopro_sdk/ui/__init__.py +33 -0
- biopro_sdk-1.0.0/src/biopro_sdk/ui/components.py +246 -0
- biopro_sdk-1.0.0/src/biopro_sdk/ui/wizard.py +444 -0
- biopro_sdk-1.0.0/src/biopro_sdk/utils/__init__.py +64 -0
- biopro_sdk-1.0.0/src/biopro_sdk/utils/dialogs.py +265 -0
- biopro_sdk-1.0.0/src/biopro_sdk/utils/io.py +176 -0
- biopro_sdk-1.0.0/src/biopro_sdk/utils/logging.py +38 -0
- biopro_sdk-1.0.0/src/biopro_sdk/utils/sign_plugin.py +92 -0
- biopro_sdk-1.0.0/src/biopro_sdk/utils/validation.py +116 -0
- biopro_sdk-1.0.0/src/biopro_sdk.egg-info/PKG-INFO +142 -0
- biopro_sdk-1.0.0/src/biopro_sdk.egg-info/SOURCES.txt +35 -0
- biopro_sdk-1.0.0/src/biopro_sdk.egg-info/dependency_links.txt +1 -0
- biopro_sdk-1.0.0/src/biopro_sdk.egg-info/entry_points.txt +2 -0
- biopro_sdk-1.0.0/src/biopro_sdk.egg-info/requires.txt +2 -0
- biopro_sdk-1.0.0/src/biopro_sdk.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: biopro-sdk
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Software Development Kit and CLI for BioPro desktop plugins.
|
|
5
|
+
Author: Kalaimaran Balasothy
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Operating System :: OS Independent
|
|
8
|
+
Requires-Python: >=3.11
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
Requires-Dist: cryptography>=41.0.0
|
|
11
|
+
Requires-Dist: PyQt6>=6.5.0
|
|
12
|
+
|
|
13
|
+
# 🔌 BioPro SDK
|
|
14
|
+
|
|
15
|
+
The Software Development Kit (SDK) and Command-Line Interface (CLI) for building, validating, and signing plugins for the **BioPro** desktop scientific suite.
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 🚀 Key Features
|
|
20
|
+
|
|
21
|
+
- **Decoupled Architecture**: Build and test PyQt6-based scientific plugins independently of the main desktop app.
|
|
22
|
+
- **Fail-Safe Dynamic Theme Fallbacks**: Visual components automatically load custom HSL-tailored colors when running standalone inside CI/CD test gates or external visualizers.
|
|
23
|
+
- **Merkle-Tree Cryptographic Integrity**: Built-in Ed25519 signing and verification tools to secure user environments against remote execution and tampering.
|
|
24
|
+
- **PyPI-Ready Packaging**: Complete declarative `pyproject.toml` config, built to publish natively under the `biopro-sdk` package.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 🛠️ Installation
|
|
29
|
+
|
|
30
|
+
Install the SDK directly into your plugin's virtual environment:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install biopro-sdk
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
*(Or during development, install in editable mode):*
|
|
37
|
+
```bash
|
|
38
|
+
git clone https://github.com/KalaimaranB/BioPro-SDK.git
|
|
39
|
+
cd BioPro-SDK
|
|
40
|
+
pip install -e .
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## 📦 Creating a Custom BioPro Plugin
|
|
46
|
+
|
|
47
|
+
To build a valid plugin, implement the `BioProPlugin` interface and declare your entrypoints.
|
|
48
|
+
|
|
49
|
+
### 1. `manifest.json`
|
|
50
|
+
Every plugin must include a manifest file in its root directory:
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"id": "my_custom_plugin",
|
|
54
|
+
"name": "My Custom Plugin",
|
|
55
|
+
"version": "1.0.0",
|
|
56
|
+
"author": "Dr. Kalaimaran",
|
|
57
|
+
"description": "High-performance scientific analysis plugin.",
|
|
58
|
+
"category": "analysis",
|
|
59
|
+
"min_core_version": "1.0.0",
|
|
60
|
+
"entrypoint": "plugin:MyPluginClass"
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### 2. `plugin.py`
|
|
65
|
+
```python
|
|
66
|
+
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel
|
|
67
|
+
from biopro_sdk.core.interfaces import BioProPlugin
|
|
68
|
+
from biopro_sdk.ui import PrimaryButton
|
|
69
|
+
|
|
70
|
+
class MyPluginClass(BioProPlugin):
|
|
71
|
+
"""A professional-grade BioPro plugin."""
|
|
72
|
+
|
|
73
|
+
def initialize(self) -> None:
|
|
74
|
+
self.logger.info("Initializing custom plugin...")
|
|
75
|
+
|
|
76
|
+
def create_panel(self, parent=None) -> QWidget:
|
|
77
|
+
panel = QWidget(parent)
|
|
78
|
+
layout = QVBoxLayout(panel)
|
|
79
|
+
|
|
80
|
+
title = QLabel("Welcome to Custom Analysis Panel")
|
|
81
|
+
btn = PrimaryButton("Execute Step")
|
|
82
|
+
|
|
83
|
+
layout.addWidget(title)
|
|
84
|
+
layout.addWidget(btn)
|
|
85
|
+
return panel
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## 🛡️ Cryptographic Trust Architecture
|
|
91
|
+
|
|
92
|
+
BioPro implements a professional-grade **Chain of Trust** to protect laboratory environments:
|
|
93
|
+
|
|
94
|
+
```
|
|
95
|
+
[ Root Authority ] (Hardcoded Core Key)
|
|
96
|
+
│
|
|
97
|
+
▼ (signs)
|
|
98
|
+
[ Developer Key ] (Dev Certificate)
|
|
99
|
+
│
|
|
100
|
+
▼ (signs)
|
|
101
|
+
[ Plugin Manifest ] (Ed25519 Signature + Merkle-Tree Hashes)
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### 1. Generate Your Cryptographic Identity
|
|
105
|
+
```bash
|
|
106
|
+
biopro-sdk setup-identity
|
|
107
|
+
```
|
|
108
|
+
- Local Private Key: `~/.biopro/dev_private_key.pem`
|
|
109
|
+
- Developer Certificate: `~/.biopro/dev_cert.bin`
|
|
110
|
+
|
|
111
|
+
### 2. Sign Your Plugin payload
|
|
112
|
+
Calculates Merkle-hashes for all your files recursively, excludes development directories automatically, updates `manifest.json`, and writes `signature.bin`:
|
|
113
|
+
```bash
|
|
114
|
+
biopro-sdk sign <path/to/plugin>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 3. Modularity Compliance Check
|
|
118
|
+
Verify your plugin matches QA and security standards:
|
|
119
|
+
```bash
|
|
120
|
+
biopro-sdk evaluate <path/to/plugin>
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 📘 Standalone Preview Support
|
|
126
|
+
Since the SDK decouples all theme components from the desktop core using robust try-except fallbacks, you can instantiate and preview components standalone in development:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
import sys
|
|
130
|
+
from PyQt6.QtWidgets import QApplication
|
|
131
|
+
from biopro_sdk.ui import PrimaryButton, WizardPanel
|
|
132
|
+
|
|
133
|
+
app = QApplication(sys.argv)
|
|
134
|
+
widget = WizardPanel() # Renders beautifully even without the main app!
|
|
135
|
+
widget.show()
|
|
136
|
+
sys.exit(app.exec())
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
## 📄 License
|
|
142
|
+
This project is licensed under the MIT License.
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# 🔌 BioPro SDK
|
|
2
|
+
|
|
3
|
+
The Software Development Kit (SDK) and Command-Line Interface (CLI) for building, validating, and signing plugins for the **BioPro** desktop scientific suite.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 🚀 Key Features
|
|
8
|
+
|
|
9
|
+
- **Decoupled Architecture**: Build and test PyQt6-based scientific plugins independently of the main desktop app.
|
|
10
|
+
- **Fail-Safe Dynamic Theme Fallbacks**: Visual components automatically load custom HSL-tailored colors when running standalone inside CI/CD test gates or external visualizers.
|
|
11
|
+
- **Merkle-Tree Cryptographic Integrity**: Built-in Ed25519 signing and verification tools to secure user environments against remote execution and tampering.
|
|
12
|
+
- **PyPI-Ready Packaging**: Complete declarative `pyproject.toml` config, built to publish natively under the `biopro-sdk` package.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 🛠️ Installation
|
|
17
|
+
|
|
18
|
+
Install the SDK directly into your plugin's virtual environment:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install biopro-sdk
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
*(Or during development, install in editable mode):*
|
|
25
|
+
```bash
|
|
26
|
+
git clone https://github.com/KalaimaranB/BioPro-SDK.git
|
|
27
|
+
cd BioPro-SDK
|
|
28
|
+
pip install -e .
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## 📦 Creating a Custom BioPro Plugin
|
|
34
|
+
|
|
35
|
+
To build a valid plugin, implement the `BioProPlugin` interface and declare your entrypoints.
|
|
36
|
+
|
|
37
|
+
### 1. `manifest.json`
|
|
38
|
+
Every plugin must include a manifest file in its root directory:
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"id": "my_custom_plugin",
|
|
42
|
+
"name": "My Custom Plugin",
|
|
43
|
+
"version": "1.0.0",
|
|
44
|
+
"author": "Dr. Kalaimaran",
|
|
45
|
+
"description": "High-performance scientific analysis plugin.",
|
|
46
|
+
"category": "analysis",
|
|
47
|
+
"min_core_version": "1.0.0",
|
|
48
|
+
"entrypoint": "plugin:MyPluginClass"
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 2. `plugin.py`
|
|
53
|
+
```python
|
|
54
|
+
from PyQt6.QtWidgets import QWidget, QVBoxLayout, QLabel
|
|
55
|
+
from biopro_sdk.core.interfaces import BioProPlugin
|
|
56
|
+
from biopro_sdk.ui import PrimaryButton
|
|
57
|
+
|
|
58
|
+
class MyPluginClass(BioProPlugin):
|
|
59
|
+
"""A professional-grade BioPro plugin."""
|
|
60
|
+
|
|
61
|
+
def initialize(self) -> None:
|
|
62
|
+
self.logger.info("Initializing custom plugin...")
|
|
63
|
+
|
|
64
|
+
def create_panel(self, parent=None) -> QWidget:
|
|
65
|
+
panel = QWidget(parent)
|
|
66
|
+
layout = QVBoxLayout(panel)
|
|
67
|
+
|
|
68
|
+
title = QLabel("Welcome to Custom Analysis Panel")
|
|
69
|
+
btn = PrimaryButton("Execute Step")
|
|
70
|
+
|
|
71
|
+
layout.addWidget(title)
|
|
72
|
+
layout.addWidget(btn)
|
|
73
|
+
return panel
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 🛡️ Cryptographic Trust Architecture
|
|
79
|
+
|
|
80
|
+
BioPro implements a professional-grade **Chain of Trust** to protect laboratory environments:
|
|
81
|
+
|
|
82
|
+
```
|
|
83
|
+
[ Root Authority ] (Hardcoded Core Key)
|
|
84
|
+
│
|
|
85
|
+
▼ (signs)
|
|
86
|
+
[ Developer Key ] (Dev Certificate)
|
|
87
|
+
│
|
|
88
|
+
▼ (signs)
|
|
89
|
+
[ Plugin Manifest ] (Ed25519 Signature + Merkle-Tree Hashes)
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 1. Generate Your Cryptographic Identity
|
|
93
|
+
```bash
|
|
94
|
+
biopro-sdk setup-identity
|
|
95
|
+
```
|
|
96
|
+
- Local Private Key: `~/.biopro/dev_private_key.pem`
|
|
97
|
+
- Developer Certificate: `~/.biopro/dev_cert.bin`
|
|
98
|
+
|
|
99
|
+
### 2. Sign Your Plugin payload
|
|
100
|
+
Calculates Merkle-hashes for all your files recursively, excludes development directories automatically, updates `manifest.json`, and writes `signature.bin`:
|
|
101
|
+
```bash
|
|
102
|
+
biopro-sdk sign <path/to/plugin>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### 3. Modularity Compliance Check
|
|
106
|
+
Verify your plugin matches QA and security standards:
|
|
107
|
+
```bash
|
|
108
|
+
biopro-sdk evaluate <path/to/plugin>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 📘 Standalone Preview Support
|
|
114
|
+
Since the SDK decouples all theme components from the desktop core using robust try-except fallbacks, you can instantiate and preview components standalone in development:
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
import sys
|
|
118
|
+
from PyQt6.QtWidgets import QApplication
|
|
119
|
+
from biopro_sdk.ui import PrimaryButton, WizardPanel
|
|
120
|
+
|
|
121
|
+
app = QApplication(sys.argv)
|
|
122
|
+
widget = WizardPanel() # Renders beautifully even without the main app!
|
|
123
|
+
widget.show()
|
|
124
|
+
sys.exit(app.exec())
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 📄 License
|
|
130
|
+
This project is licensed under the MIT License.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "biopro-sdk"
|
|
7
|
+
version = "1.0.0"
|
|
8
|
+
description = "Software Development Kit and CLI for BioPro desktop plugins."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
authors = [
|
|
12
|
+
{ name = "Kalaimaran Balasothy" }
|
|
13
|
+
]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Operating System :: OS Independent",
|
|
17
|
+
]
|
|
18
|
+
dependencies = [
|
|
19
|
+
"cryptography>=41.0.0",
|
|
20
|
+
"PyQt6>=6.5.0",
|
|
21
|
+
]
|
|
22
|
+
|
|
23
|
+
[project.scripts]
|
|
24
|
+
biopro-sdk = "biopro_sdk.sdk_cli:main"
|
|
25
|
+
|
|
26
|
+
[tool.setuptools.packages.find]
|
|
27
|
+
where = ["src"]
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
"""BioPro SDK — Complete plugin development framework.
|
|
2
|
+
|
|
3
|
+
Provides everything needed to build plugins:
|
|
4
|
+
|
|
5
|
+
Core Components:
|
|
6
|
+
- PluginBase: Main plugin class to inherit from
|
|
7
|
+
- PluginState: State management with undo/redo
|
|
8
|
+
- PluginSignals: Standard signals for communication
|
|
9
|
+
- AnalysisBase: Abstract analysis logic class
|
|
10
|
+
- AnalysisWorker: Background worker for threads
|
|
11
|
+
|
|
12
|
+
UI Components:
|
|
13
|
+
- PrimaryButton, SecondaryButton, DangerButton: Semantic buttons
|
|
14
|
+
- ModuleCard, HeaderLabel: Styled components
|
|
15
|
+
- WizardStep, WizardPanel: Multi-step interface framework
|
|
16
|
+
|
|
17
|
+
Utilities:
|
|
18
|
+
- Dialogs: File, message, and input dialogs
|
|
19
|
+
- I/O: JSON and configuration management
|
|
20
|
+
- Validation: Input validation helpers
|
|
21
|
+
|
|
22
|
+
Contrib (Optional):
|
|
23
|
+
- Image utilities: Common image processing functions
|
|
24
|
+
|
|
25
|
+
Example:
|
|
26
|
+
>>> from biopro_sdk.core import PluginBase, PluginState
|
|
27
|
+
>>> from biopro_sdk.ui import PrimaryButton, WizardPanel
|
|
28
|
+
>>> from biopro_sdk.utils import show_error
|
|
29
|
+
>>>
|
|
30
|
+
>>> class MyState(PluginState):
|
|
31
|
+
... image_path: str = ""
|
|
32
|
+
...
|
|
33
|
+
>>> class MyPlugin(PluginBase):
|
|
34
|
+
... def __init__(self, plugin_id: str):
|
|
35
|
+
... super().__init__(plugin_id)
|
|
36
|
+
... self.state = MyState()
|
|
37
|
+
...
|
|
38
|
+
... def get_state(self) -> PluginState:
|
|
39
|
+
... return self.state
|
|
40
|
+
...
|
|
41
|
+
... def set_state(self, state: PluginState) -> None:
|
|
42
|
+
... self.state = state
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from . import contrib, core, ui, utils
|
|
46
|
+
from .core import (
|
|
47
|
+
AnalysisBase,
|
|
48
|
+
AnalysisWorker,
|
|
49
|
+
PluginBase,
|
|
50
|
+
PluginSignals,
|
|
51
|
+
PluginState,
|
|
52
|
+
PreferenceManagerProtocol,
|
|
53
|
+
diagnostics,
|
|
54
|
+
)
|
|
55
|
+
from .core.ai import AIAssistant, AIServerManager, ai_manager
|
|
56
|
+
from .core.docs import PluginDocumentation, docs_registry
|
|
57
|
+
from .core.events import CentralEventBus
|
|
58
|
+
from .ui import (
|
|
59
|
+
DangerButton,
|
|
60
|
+
HeaderLabel,
|
|
61
|
+
ModuleCard,
|
|
62
|
+
PrimaryButton,
|
|
63
|
+
SecondaryButton,
|
|
64
|
+
StepIndicator,
|
|
65
|
+
SubtitleLabel,
|
|
66
|
+
WizardPanel,
|
|
67
|
+
WizardStep,
|
|
68
|
+
)
|
|
69
|
+
from .utils import (
|
|
70
|
+
PluginConfig,
|
|
71
|
+
PluginPreferenceManager,
|
|
72
|
+
ask_ok_cancel,
|
|
73
|
+
ask_yes_no,
|
|
74
|
+
get_directory,
|
|
75
|
+
get_double,
|
|
76
|
+
get_image_path,
|
|
77
|
+
get_number,
|
|
78
|
+
get_save_path,
|
|
79
|
+
get_text,
|
|
80
|
+
load_json,
|
|
81
|
+
save_json,
|
|
82
|
+
show_error,
|
|
83
|
+
show_info,
|
|
84
|
+
show_warning,
|
|
85
|
+
validate_directory_exists,
|
|
86
|
+
validate_file_exists,
|
|
87
|
+
validate_non_negative,
|
|
88
|
+
validate_not_empty,
|
|
89
|
+
validate_positive,
|
|
90
|
+
validate_value_range,
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
__all__ = [
|
|
94
|
+
# Submodules
|
|
95
|
+
"core",
|
|
96
|
+
"ui",
|
|
97
|
+
"utils",
|
|
98
|
+
"contrib",
|
|
99
|
+
# Core
|
|
100
|
+
"PluginBase",
|
|
101
|
+
"PluginState",
|
|
102
|
+
"PluginSignals",
|
|
103
|
+
"AnalysisBase",
|
|
104
|
+
"AnalysisWorker",
|
|
105
|
+
"PreferenceManagerProtocol",
|
|
106
|
+
"CentralEventBus",
|
|
107
|
+
"PluginDocumentation",
|
|
108
|
+
"docs_registry",
|
|
109
|
+
"AIAssistant",
|
|
110
|
+
"AIServerManager",
|
|
111
|
+
"ai_manager",
|
|
112
|
+
# UI
|
|
113
|
+
"PrimaryButton",
|
|
114
|
+
"SecondaryButton",
|
|
115
|
+
"DangerButton",
|
|
116
|
+
"ModuleCard",
|
|
117
|
+
"HeaderLabel",
|
|
118
|
+
"SubtitleLabel",
|
|
119
|
+
"StepIndicator",
|
|
120
|
+
"WizardStep",
|
|
121
|
+
"WizardPanel",
|
|
122
|
+
# Utils
|
|
123
|
+
"get_image_path",
|
|
124
|
+
"get_save_path",
|
|
125
|
+
"get_directory",
|
|
126
|
+
"show_info",
|
|
127
|
+
"show_warning",
|
|
128
|
+
"show_error",
|
|
129
|
+
"ask_yes_no",
|
|
130
|
+
"ask_ok_cancel",
|
|
131
|
+
"get_text",
|
|
132
|
+
"get_number",
|
|
133
|
+
"get_double",
|
|
134
|
+
"load_json",
|
|
135
|
+
"save_json",
|
|
136
|
+
"PluginConfig",
|
|
137
|
+
"PluginPreferenceManager",
|
|
138
|
+
"validate_file_exists",
|
|
139
|
+
"validate_directory_exists",
|
|
140
|
+
"validate_value_range",
|
|
141
|
+
"validate_positive",
|
|
142
|
+
"validate_non_negative",
|
|
143
|
+
"validate_not_empty",
|
|
144
|
+
"diagnostics",
|
|
145
|
+
]
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""BioPro SDK Contrib — Optional utilities to support plugin development.
|
|
2
|
+
|
|
3
|
+
Image utilities for common analysis operations. Use these to keep plugin
|
|
4
|
+
code DRY and focused on domain-specific logic.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
try:
|
|
8
|
+
from biopro.shared.analysis.image_utils import (
|
|
9
|
+
adjust_contrast,
|
|
10
|
+
auto_detect_inversion,
|
|
11
|
+
crop_to_content,
|
|
12
|
+
enhance_for_band_detection,
|
|
13
|
+
invert_image,
|
|
14
|
+
load_and_convert,
|
|
15
|
+
rotate_image,
|
|
16
|
+
)
|
|
17
|
+
except ImportError:
|
|
18
|
+
# Standalone fallback: raise ImportError only if called, keeping SDK CLI lightweight
|
|
19
|
+
def _raise_import_error(*args, **kwargs):
|
|
20
|
+
raise ImportError("This utility requires 'biopro-core' or 'scikit-image' to be installed.")
|
|
21
|
+
|
|
22
|
+
adjust_contrast = _raise_import_error
|
|
23
|
+
auto_detect_inversion = _raise_import_error
|
|
24
|
+
crop_to_content = _raise_import_error
|
|
25
|
+
enhance_for_band_detection = _raise_import_error
|
|
26
|
+
invert_image = _raise_import_error
|
|
27
|
+
load_and_convert = _raise_import_error
|
|
28
|
+
rotate_image = _raise_import_error
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"adjust_contrast",
|
|
32
|
+
"load_and_convert",
|
|
33
|
+
"auto_detect_inversion",
|
|
34
|
+
"invert_image",
|
|
35
|
+
"enhance_for_band_detection",
|
|
36
|
+
"rotate_image",
|
|
37
|
+
"crop_to_content",
|
|
38
|
+
]
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""BioPro SDK Core — Base classes for plugin development.
|
|
2
|
+
|
|
3
|
+
Provides:
|
|
4
|
+
- PluginSignals: Standard PyQt6 signals for plugin communication
|
|
5
|
+
- PluginState: Base class for serializable plugin state
|
|
6
|
+
- AnalysisBase: Abstract base for analysis logic
|
|
7
|
+
- AnalysisWorker: Background worker for thread execution
|
|
8
|
+
- PluginBase: Main plugin class to inherit from
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
from biopro.core.diagnostics import diagnostics
|
|
13
|
+
except ImportError:
|
|
14
|
+
class MockDiagnostics:
|
|
15
|
+
def report_error(self, message, exception=None, plugin_id=None, fatal=False):
|
|
16
|
+
import logging
|
|
17
|
+
logging.getLogger("biopro_sdk.diagnostics").error(f"[{plugin_id or 'System'}] {message}: {exception or ''}")
|
|
18
|
+
diagnostics = MockDiagnostics()
|
|
19
|
+
|
|
20
|
+
from .analysis import AnalysisBase, AnalysisWorker
|
|
21
|
+
from .base import PluginBase
|
|
22
|
+
from .interfaces import BioProPlugin
|
|
23
|
+
from .managed_task import FunctionalTask
|
|
24
|
+
from .preferences import PreferenceManagerProtocol
|
|
25
|
+
from .signals import PluginSignals
|
|
26
|
+
from .state import PluginState
|
|
27
|
+
|
|
28
|
+
__all__ = [
|
|
29
|
+
"PluginSignals",
|
|
30
|
+
"PluginState",
|
|
31
|
+
"AnalysisBase",
|
|
32
|
+
"AnalysisWorker",
|
|
33
|
+
"PluginBase",
|
|
34
|
+
"FunctionalTask",
|
|
35
|
+
"BioProPlugin",
|
|
36
|
+
"PreferenceManagerProtocol",
|
|
37
|
+
"diagnostics",
|
|
38
|
+
]
|