aphelion-plugin-sdk 0.1.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.
Files changed (44) hide show
  1. aphelion_plugin_sdk-0.1.0/PKG-INFO +114 -0
  2. aphelion_plugin_sdk-0.1.0/README.md +97 -0
  3. aphelion_plugin_sdk-0.1.0/aphelion_plugin_sdk.egg-info/PKG-INFO +114 -0
  4. aphelion_plugin_sdk-0.1.0/aphelion_plugin_sdk.egg-info/SOURCES.txt +42 -0
  5. aphelion_plugin_sdk-0.1.0/aphelion_plugin_sdk.egg-info/dependency_links.txt +1 -0
  6. aphelion_plugin_sdk-0.1.0/aphelion_plugin_sdk.egg-info/entry_points.txt +2 -0
  7. aphelion_plugin_sdk-0.1.0/aphelion_plugin_sdk.egg-info/requires.txt +6 -0
  8. aphelion_plugin_sdk-0.1.0/aphelion_plugin_sdk.egg-info/top_level.txt +1 -0
  9. aphelion_plugin_sdk-0.1.0/aphelion_sdk/__init__.py +151 -0
  10. aphelion_plugin_sdk-0.1.0/aphelion_sdk/__main__.py +10 -0
  11. aphelion_plugin_sdk-0.1.0/aphelion_sdk/audio/__init__.py +9 -0
  12. aphelion_plugin_sdk-0.1.0/aphelion_sdk/cli/__init__.py +7 -0
  13. aphelion_plugin_sdk-0.1.0/aphelion_sdk/cli/main.py +203 -0
  14. aphelion_plugin_sdk-0.1.0/aphelion_sdk/host/__init__.py +16 -0
  15. aphelion_plugin_sdk-0.1.0/aphelion_sdk/host/constants.py +17 -0
  16. aphelion_plugin_sdk-0.1.0/aphelion_sdk/host/errors.py +20 -0
  17. aphelion_plugin_sdk-0.1.0/aphelion_sdk/host/install.py +55 -0
  18. aphelion_plugin_sdk-0.1.0/aphelion_sdk/host/locate.py +81 -0
  19. aphelion_plugin_sdk-0.1.0/aphelion_sdk/host/models.py +33 -0
  20. aphelion_plugin_sdk-0.1.0/aphelion_sdk/host/validate.py +75 -0
  21. aphelion_plugin_sdk-0.1.0/aphelion_sdk/host/windows.py +80 -0
  22. aphelion_plugin_sdk-0.1.0/aphelion_sdk/packaging/__init__.py +19 -0
  23. aphelion_plugin_sdk-0.1.0/aphelion_sdk/packaging/builder.py +222 -0
  24. aphelion_plugin_sdk-0.1.0/aphelion_sdk/packaging/discovery.py +250 -0
  25. aphelion_plugin_sdk-0.1.0/aphelion_sdk/packaging/errors.py +20 -0
  26. aphelion_plugin_sdk-0.1.0/aphelion_sdk/packaging/names.py +174 -0
  27. aphelion_plugin_sdk-0.1.0/aphelion_sdk/packaging/project.py +241 -0
  28. aphelion_plugin_sdk-0.1.0/aphelion_sdk/plugin.py +51 -0
  29. aphelion_plugin_sdk-0.1.0/aphelion_sdk/properties.py +179 -0
  30. aphelion_plugin_sdk-0.1.0/aphelion_sdk/py.typed +0 -0
  31. aphelion_plugin_sdk-0.1.0/aphelion_sdk/registration.py +85 -0
  32. aphelion_plugin_sdk-0.1.0/aphelion_sdk/types.py +19 -0
  33. aphelion_plugin_sdk-0.1.0/aphelion_sdk/version.py +6 -0
  34. aphelion_plugin_sdk-0.1.0/aphelion_sdk/video/__init__.py +7 -0
  35. aphelion_plugin_sdk-0.1.0/aphelion_sdk/video/effect.py +93 -0
  36. aphelion_plugin_sdk-0.1.0/aphelion_sdk/widgets/__init__.py +23 -0
  37. aphelion_plugin_sdk-0.1.0/aphelion_sdk/widgets/base.py +76 -0
  38. aphelion_plugin_sdk-0.1.0/aphelion_sdk/widgets/dialog.py +45 -0
  39. aphelion_plugin_sdk-0.1.0/aphelion_sdk/widgets/host.py +105 -0
  40. aphelion_plugin_sdk-0.1.0/aphelion_sdk/widgets/kinds.py +14 -0
  41. aphelion_plugin_sdk-0.1.0/aphelion_sdk/widgets/panel.py +35 -0
  42. aphelion_plugin_sdk-0.1.0/aphelion_sdk/widgets/qt.py +35 -0
  43. aphelion_plugin_sdk-0.1.0/pyproject.toml +49 -0
  44. aphelion_plugin_sdk-0.1.0/setup.cfg +4 -0
@@ -0,0 +1,114 @@
1
+ Metadata-Version: 2.4
2
+ Name: aphelion-plugin-sdk
3
+ Version: 0.1.0
4
+ Summary: Public SDK for Aphelion plugins (video now; audio later).
5
+ Author: youthx
6
+ License-Expression: LicenseRef-Proprietary
7
+ Project-URL: Homepage, https://github.com/aphelion-engine/aphelion-sdk
8
+ Project-URL: Repository, https://github.com/aphelion-engine/aphelion-sdk
9
+ Keywords: aphelion,plugin,sdk,video,audio
10
+ Requires-Python: >=3.11
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: numpy>=1.26.0
13
+ Provides-Extra: dev
14
+ Requires-Dist: build>=1.2.0; extra == "dev"
15
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
16
+ Requires-Dist: mypy>=1.8.0; extra == "dev"
17
+
18
+ # Aphelion Plugin SDK
19
+
20
+ Public API for plugins that run **inside Aphelion Editor**. This package sits beside `aphelion-editor`, not inside it.
21
+
22
+ Import **`aphelion_sdk` only**. Never import `core`, `effects`, `render`, or `ui`.
23
+
24
+ Video effects are available now (`VideoEffectPlugin`). Audio bases will land under `aphelion_sdk.audio` later.
25
+
26
+ Version **0.1.0**. Python **3.11+**. Install with **`pip install aphelion-plugin-sdk`**. Import **`aphelion_sdk`**.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ pip install aphelion-plugin-sdk
32
+ ```
33
+
34
+ From the `aphelion-engine` root, with a venv active:
35
+
36
+ ```bash
37
+ pip install -e ./aphelion-editor
38
+ pip install -e ./aphelion-sdk
39
+ ```
40
+
41
+ Installing the editor already depends on this package (`aphelion-plugin-sdk @ file:../aphelion-sdk`).
42
+
43
+ ```bash
44
+ aphelion-sdk --version
45
+ python -m aphelion_sdk --help
46
+ ```
47
+
48
+ ## Quick start
49
+
50
+ ```python
51
+ import aphelion_sdk
52
+
53
+
54
+ @aphelion_sdk.register_plugin
55
+ class GrayscaleEffect(aphelion_sdk.VideoEffectPlugin):
56
+ plugin_name = "Grayscale"
57
+ plugin_category = "Plugins"
58
+ plugin_description = "Blend a frame toward grayscale."
59
+ plugin_color = (140, 140, 140)
60
+
61
+ def setup_effect_properties(self) -> None:
62
+ self.set_property(
63
+ "amount",
64
+ aphelion_sdk.slider_property(
65
+ 100, 0, 100,
66
+ label="Amount",
67
+ suffix="%",
68
+ ),
69
+ )
70
+
71
+ def process_frame(
72
+ self,
73
+ frame: aphelion_sdk.Frame,
74
+ _frame_num: int,
75
+ ) -> aphelion_sdk.Frame:
76
+ amount = self.float_value("amount", 100.0) / 100.0
77
+ luma = (
78
+ frame[..., 0] * 0.2126
79
+ + frame[..., 1] * 0.7152
80
+ + frame[..., 2] * 0.0722
81
+ )
82
+ gray = luma[..., None].repeat(3, axis=2)
83
+ return frame * (1.0 - amount) + gray * amount
84
+ ```
85
+
86
+ Drop the file in the editor's `plugins/` or `userdata/plugins/`, or pack a wheel (below). Time-independent effects should name the unused argument `_frame_num`.
87
+
88
+ Examples:
89
+
90
+ - [`examples/grayscale_effect.py`](examples/grayscale_effect.py)
91
+ - [`examples/effect_with_widget.py`](examples/effect_with_widget.py) — dialog + panel via `widgets = (...)`
92
+
93
+ ## Documentation
94
+
95
+ | Guide | Contents |
96
+ |---|---|
97
+ | [Authoring](docs/authoring.md) | Effect class, properties, discovery rules |
98
+ | [Widgets](docs/widgets.md) | Panels, dialogs, primitives, PyQt6 |
99
+ | [API reference](docs/api.md) | Public symbols |
100
+ | [Packaging](docs/packaging.md) | `aphelion-sdk build`, entry points, drop-in install |
101
+ | [Editor plugins](../aphelion-editor/docs/plugins.md) | How the host loads and reloads plugins |
102
+
103
+ ## Package a plugin
104
+
105
+ ```bash
106
+ aphelion-sdk build examples/grayscale_effect.py -o dist
107
+ pip install dist/aphelion_plugin_grayscale-*.whl
108
+ ```
109
+
110
+ Entry point group: `aphelion.plugins`. Widgets are declared on the plugin (`widgets = (MyDialog, MyPanel)`); they are not registered on their own.
111
+
112
+ ## License
113
+
114
+ Proprietary (`LicenseRef-Proprietary` in `pyproject.toml`).
@@ -0,0 +1,97 @@
1
+ # Aphelion Plugin SDK
2
+
3
+ Public API for plugins that run **inside Aphelion Editor**. This package sits beside `aphelion-editor`, not inside it.
4
+
5
+ Import **`aphelion_sdk` only**. Never import `core`, `effects`, `render`, or `ui`.
6
+
7
+ Video effects are available now (`VideoEffectPlugin`). Audio bases will land under `aphelion_sdk.audio` later.
8
+
9
+ Version **0.1.0**. Python **3.11+**. Install with **`pip install aphelion-plugin-sdk`**. Import **`aphelion_sdk`**.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ pip install aphelion-plugin-sdk
15
+ ```
16
+
17
+ From the `aphelion-engine` root, with a venv active:
18
+
19
+ ```bash
20
+ pip install -e ./aphelion-editor
21
+ pip install -e ./aphelion-sdk
22
+ ```
23
+
24
+ Installing the editor already depends on this package (`aphelion-plugin-sdk @ file:../aphelion-sdk`).
25
+
26
+ ```bash
27
+ aphelion-sdk --version
28
+ python -m aphelion_sdk --help
29
+ ```
30
+
31
+ ## Quick start
32
+
33
+ ```python
34
+ import aphelion_sdk
35
+
36
+
37
+ @aphelion_sdk.register_plugin
38
+ class GrayscaleEffect(aphelion_sdk.VideoEffectPlugin):
39
+ plugin_name = "Grayscale"
40
+ plugin_category = "Plugins"
41
+ plugin_description = "Blend a frame toward grayscale."
42
+ plugin_color = (140, 140, 140)
43
+
44
+ def setup_effect_properties(self) -> None:
45
+ self.set_property(
46
+ "amount",
47
+ aphelion_sdk.slider_property(
48
+ 100, 0, 100,
49
+ label="Amount",
50
+ suffix="%",
51
+ ),
52
+ )
53
+
54
+ def process_frame(
55
+ self,
56
+ frame: aphelion_sdk.Frame,
57
+ _frame_num: int,
58
+ ) -> aphelion_sdk.Frame:
59
+ amount = self.float_value("amount", 100.0) / 100.0
60
+ luma = (
61
+ frame[..., 0] * 0.2126
62
+ + frame[..., 1] * 0.7152
63
+ + frame[..., 2] * 0.0722
64
+ )
65
+ gray = luma[..., None].repeat(3, axis=2)
66
+ return frame * (1.0 - amount) + gray * amount
67
+ ```
68
+
69
+ Drop the file in the editor's `plugins/` or `userdata/plugins/`, or pack a wheel (below). Time-independent effects should name the unused argument `_frame_num`.
70
+
71
+ Examples:
72
+
73
+ - [`examples/grayscale_effect.py`](examples/grayscale_effect.py)
74
+ - [`examples/effect_with_widget.py`](examples/effect_with_widget.py) — dialog + panel via `widgets = (...)`
75
+
76
+ ## Documentation
77
+
78
+ | Guide | Contents |
79
+ |---|---|
80
+ | [Authoring](docs/authoring.md) | Effect class, properties, discovery rules |
81
+ | [Widgets](docs/widgets.md) | Panels, dialogs, primitives, PyQt6 |
82
+ | [API reference](docs/api.md) | Public symbols |
83
+ | [Packaging](docs/packaging.md) | `aphelion-sdk build`, entry points, drop-in install |
84
+ | [Editor plugins](../aphelion-editor/docs/plugins.md) | How the host loads and reloads plugins |
85
+
86
+ ## Package a plugin
87
+
88
+ ```bash
89
+ aphelion-sdk build examples/grayscale_effect.py -o dist
90
+ pip install dist/aphelion_plugin_grayscale-*.whl
91
+ ```
92
+
93
+ Entry point group: `aphelion.plugins`. Widgets are declared on the plugin (`widgets = (MyDialog, MyPanel)`); they are not registered on their own.
94
+
95
+ ## License
96
+
97
+ Proprietary (`LicenseRef-Proprietary` in `pyproject.toml`).
@@ -0,0 +1,114 @@
1
+ Metadata-Version: 2.4
2
+ Name: aphelion-plugin-sdk
3
+ Version: 0.1.0
4
+ Summary: Public SDK for Aphelion plugins (video now; audio later).
5
+ Author: youthx
6
+ License-Expression: LicenseRef-Proprietary
7
+ Project-URL: Homepage, https://github.com/aphelion-engine/aphelion-sdk
8
+ Project-URL: Repository, https://github.com/aphelion-engine/aphelion-sdk
9
+ Keywords: aphelion,plugin,sdk,video,audio
10
+ Requires-Python: >=3.11
11
+ Description-Content-Type: text/markdown
12
+ Requires-Dist: numpy>=1.26.0
13
+ Provides-Extra: dev
14
+ Requires-Dist: build>=1.2.0; extra == "dev"
15
+ Requires-Dist: pytest>=8.0.0; extra == "dev"
16
+ Requires-Dist: mypy>=1.8.0; extra == "dev"
17
+
18
+ # Aphelion Plugin SDK
19
+
20
+ Public API for plugins that run **inside Aphelion Editor**. This package sits beside `aphelion-editor`, not inside it.
21
+
22
+ Import **`aphelion_sdk` only**. Never import `core`, `effects`, `render`, or `ui`.
23
+
24
+ Video effects are available now (`VideoEffectPlugin`). Audio bases will land under `aphelion_sdk.audio` later.
25
+
26
+ Version **0.1.0**. Python **3.11+**. Install with **`pip install aphelion-plugin-sdk`**. Import **`aphelion_sdk`**.
27
+
28
+ ## Install
29
+
30
+ ```bash
31
+ pip install aphelion-plugin-sdk
32
+ ```
33
+
34
+ From the `aphelion-engine` root, with a venv active:
35
+
36
+ ```bash
37
+ pip install -e ./aphelion-editor
38
+ pip install -e ./aphelion-sdk
39
+ ```
40
+
41
+ Installing the editor already depends on this package (`aphelion-plugin-sdk @ file:../aphelion-sdk`).
42
+
43
+ ```bash
44
+ aphelion-sdk --version
45
+ python -m aphelion_sdk --help
46
+ ```
47
+
48
+ ## Quick start
49
+
50
+ ```python
51
+ import aphelion_sdk
52
+
53
+
54
+ @aphelion_sdk.register_plugin
55
+ class GrayscaleEffect(aphelion_sdk.VideoEffectPlugin):
56
+ plugin_name = "Grayscale"
57
+ plugin_category = "Plugins"
58
+ plugin_description = "Blend a frame toward grayscale."
59
+ plugin_color = (140, 140, 140)
60
+
61
+ def setup_effect_properties(self) -> None:
62
+ self.set_property(
63
+ "amount",
64
+ aphelion_sdk.slider_property(
65
+ 100, 0, 100,
66
+ label="Amount",
67
+ suffix="%",
68
+ ),
69
+ )
70
+
71
+ def process_frame(
72
+ self,
73
+ frame: aphelion_sdk.Frame,
74
+ _frame_num: int,
75
+ ) -> aphelion_sdk.Frame:
76
+ amount = self.float_value("amount", 100.0) / 100.0
77
+ luma = (
78
+ frame[..., 0] * 0.2126
79
+ + frame[..., 1] * 0.7152
80
+ + frame[..., 2] * 0.0722
81
+ )
82
+ gray = luma[..., None].repeat(3, axis=2)
83
+ return frame * (1.0 - amount) + gray * amount
84
+ ```
85
+
86
+ Drop the file in the editor's `plugins/` or `userdata/plugins/`, or pack a wheel (below). Time-independent effects should name the unused argument `_frame_num`.
87
+
88
+ Examples:
89
+
90
+ - [`examples/grayscale_effect.py`](examples/grayscale_effect.py)
91
+ - [`examples/effect_with_widget.py`](examples/effect_with_widget.py) — dialog + panel via `widgets = (...)`
92
+
93
+ ## Documentation
94
+
95
+ | Guide | Contents |
96
+ |---|---|
97
+ | [Authoring](docs/authoring.md) | Effect class, properties, discovery rules |
98
+ | [Widgets](docs/widgets.md) | Panels, dialogs, primitives, PyQt6 |
99
+ | [API reference](docs/api.md) | Public symbols |
100
+ | [Packaging](docs/packaging.md) | `aphelion-sdk build`, entry points, drop-in install |
101
+ | [Editor plugins](../aphelion-editor/docs/plugins.md) | How the host loads and reloads plugins |
102
+
103
+ ## Package a plugin
104
+
105
+ ```bash
106
+ aphelion-sdk build examples/grayscale_effect.py -o dist
107
+ pip install dist/aphelion_plugin_grayscale-*.whl
108
+ ```
109
+
110
+ Entry point group: `aphelion.plugins`. Widgets are declared on the plugin (`widgets = (MyDialog, MyPanel)`); they are not registered on their own.
111
+
112
+ ## License
113
+
114
+ Proprietary (`LicenseRef-Proprietary` in `pyproject.toml`).
@@ -0,0 +1,42 @@
1
+ README.md
2
+ pyproject.toml
3
+ aphelion_plugin_sdk.egg-info/PKG-INFO
4
+ aphelion_plugin_sdk.egg-info/SOURCES.txt
5
+ aphelion_plugin_sdk.egg-info/dependency_links.txt
6
+ aphelion_plugin_sdk.egg-info/entry_points.txt
7
+ aphelion_plugin_sdk.egg-info/requires.txt
8
+ aphelion_plugin_sdk.egg-info/top_level.txt
9
+ aphelion_sdk/__init__.py
10
+ aphelion_sdk/__main__.py
11
+ aphelion_sdk/plugin.py
12
+ aphelion_sdk/properties.py
13
+ aphelion_sdk/py.typed
14
+ aphelion_sdk/registration.py
15
+ aphelion_sdk/types.py
16
+ aphelion_sdk/version.py
17
+ aphelion_sdk/audio/__init__.py
18
+ aphelion_sdk/cli/__init__.py
19
+ aphelion_sdk/cli/main.py
20
+ aphelion_sdk/host/__init__.py
21
+ aphelion_sdk/host/constants.py
22
+ aphelion_sdk/host/errors.py
23
+ aphelion_sdk/host/install.py
24
+ aphelion_sdk/host/locate.py
25
+ aphelion_sdk/host/models.py
26
+ aphelion_sdk/host/validate.py
27
+ aphelion_sdk/host/windows.py
28
+ aphelion_sdk/packaging/__init__.py
29
+ aphelion_sdk/packaging/builder.py
30
+ aphelion_sdk/packaging/discovery.py
31
+ aphelion_sdk/packaging/errors.py
32
+ aphelion_sdk/packaging/names.py
33
+ aphelion_sdk/packaging/project.py
34
+ aphelion_sdk/video/__init__.py
35
+ aphelion_sdk/video/effect.py
36
+ aphelion_sdk/widgets/__init__.py
37
+ aphelion_sdk/widgets/base.py
38
+ aphelion_sdk/widgets/dialog.py
39
+ aphelion_sdk/widgets/host.py
40
+ aphelion_sdk/widgets/kinds.py
41
+ aphelion_sdk/widgets/panel.py
42
+ aphelion_sdk/widgets/qt.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ aphelion-sdk = aphelion_sdk.cli.main:main
@@ -0,0 +1,6 @@
1
+ numpy>=1.26.0
2
+
3
+ [dev]
4
+ build>=1.2.0
5
+ pytest>=8.0.0
6
+ mypy>=1.8.0
@@ -0,0 +1,151 @@
1
+ """Aphelion Plugin SDK.
2
+
3
+ Public, stable surface for custom Aphelion plugins. Authors should
4
+ ``import aphelion_sdk`` and must never import editor internals
5
+ (``core``, ``effects``, ``render``, ``ui``).
6
+
7
+ Video effects subclass ``VideoEffectPlugin``. Attach UI with
8
+ ``widgets = (MyDialog, MyPanel)``. Simple widgets use host primitives;
9
+ advanced widgets may import PyQt6 and return a ``QWidget`` from
10
+ ``build_qt_widget`` or ``embed_native``.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from importlib import import_module
16
+ from typing import TYPE_CHECKING, Final
17
+
18
+ if TYPE_CHECKING:
19
+ from aphelion_sdk.plugin import Plugin
20
+ from aphelion_sdk.properties import (
21
+ PluginProperty,
22
+ choice_property,
23
+ color_property,
24
+ custom_property,
25
+ number_property,
26
+ slider_property,
27
+ text_property,
28
+ toggle_property,
29
+ )
30
+ from aphelion_sdk.registration import (
31
+ clear_registered_plugins,
32
+ discover_installed_plugins,
33
+ get_registered_plugins,
34
+ register_plugin,
35
+ )
36
+ from aphelion_sdk.types import ColorRgb, Frame
37
+ from aphelion_sdk.version import __version__
38
+ from aphelion_sdk.video import VideoEffectPlugin
39
+ from aphelion_sdk.widgets import (
40
+ DialogWidget,
41
+ PanelWidget,
42
+ PluginWidget,
43
+ WidgetContext,
44
+ WidgetHost,
45
+ WidgetView,
46
+ coerce_qt_parent,
47
+ is_qt_widget,
48
+ )
49
+
50
+ __all__ = [
51
+ "ColorRgb",
52
+ "DialogWidget",
53
+ "Frame",
54
+ "PanelWidget",
55
+ "Plugin",
56
+ "PluginProperty",
57
+ "PluginWidget",
58
+ "VideoEffectPlugin",
59
+ "WidgetContext",
60
+ "WidgetHost",
61
+ "WidgetView",
62
+ "__version__",
63
+ "choice_property",
64
+ "clear_registered_plugins",
65
+ "coerce_qt_parent",
66
+ "color_property",
67
+ "custom_property",
68
+ "discover_editors",
69
+ "discover_installed_plugins",
70
+ "get_registered_plugins",
71
+ "install_plugins_into_editor",
72
+ "locate_editor",
73
+ "is_qt_widget",
74
+ "number_property",
75
+ "register_plugin",
76
+ "slider_property",
77
+ "text_property",
78
+ "toggle_property",
79
+ ]
80
+
81
+ _EXPORT_MAP: Final[dict[str, tuple[str, str]]] = {
82
+ "ColorRgb": ("aphelion_sdk.types", "ColorRgb"),
83
+ "DialogWidget": ("aphelion_sdk.widgets.dialog", "DialogWidget"),
84
+ "Frame": ("aphelion_sdk.types", "Frame"),
85
+ "PanelWidget": ("aphelion_sdk.widgets.panel", "PanelWidget"),
86
+ "Plugin": ("aphelion_sdk.plugin", "Plugin"),
87
+ "PluginProperty": ("aphelion_sdk.properties", "PluginProperty"),
88
+ "PluginWidget": ("aphelion_sdk.widgets.base", "PluginWidget"),
89
+ "VideoEffectPlugin": ("aphelion_sdk.video", "VideoEffectPlugin"),
90
+ "WidgetContext": ("aphelion_sdk.widgets.host", "WidgetContext"),
91
+ "WidgetHost": ("aphelion_sdk.widgets.host", "WidgetHost"),
92
+ "WidgetView": ("aphelion_sdk.widgets.host", "WidgetView"),
93
+ "__version__": ("aphelion_sdk.version", "__version__"),
94
+ "choice_property": ("aphelion_sdk.properties", "choice_property"),
95
+ "clear_registered_plugins": (
96
+ "aphelion_sdk.registration",
97
+ "clear_registered_plugins",
98
+ ),
99
+ "coerce_qt_parent": ("aphelion_sdk.widgets.qt", "coerce_qt_parent"),
100
+ "color_property": ("aphelion_sdk.properties", "color_property"),
101
+ "custom_property": ("aphelion_sdk.properties", "custom_property"),
102
+ "discover_editors": ("aphelion_sdk.host.locate", "discover_editors"),
103
+ "discover_installed_plugins": (
104
+ "aphelion_sdk.registration",
105
+ "discover_installed_plugins",
106
+ ),
107
+ "install_plugins_into_editor": (
108
+ "aphelion_sdk.host.install",
109
+ "install_plugins_into_editor",
110
+ ),
111
+ "locate_editor": ("aphelion_sdk.host.locate", "locate_editor"),
112
+ "get_registered_plugins": (
113
+ "aphelion_sdk.registration",
114
+ "get_registered_plugins",
115
+ ),
116
+ "is_qt_widget": ("aphelion_sdk.widgets.qt", "is_qt_widget"),
117
+ "number_property": ("aphelion_sdk.properties", "number_property"),
118
+ "register_plugin": ("aphelion_sdk.registration", "register_plugin"),
119
+ "slider_property": ("aphelion_sdk.properties", "slider_property"),
120
+ "text_property": ("aphelion_sdk.properties", "text_property"),
121
+ "toggle_property": ("aphelion_sdk.properties", "toggle_property"),
122
+ }
123
+
124
+
125
+ def __getattr__(name: str) -> object:
126
+ """Resolve a public SDK symbol on first access.
127
+
128
+ Parameters:
129
+ name: Attribute requested on ``aphelion_sdk``.
130
+
131
+ Returns:
132
+ The exported object bound to ``name``.
133
+
134
+ Exceptions:
135
+ AttributeError: If ``name`` is not part of the public surface.
136
+
137
+ Side effects:
138
+ Imports the implementing submodule and caches the attribute.
139
+ """
140
+ location: tuple[str, str] | None = _EXPORT_MAP.get(name)
141
+ if location is None:
142
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
143
+ module_name, attr_name = location
144
+ value: object = getattr(import_module(module_name), attr_name)
145
+ globals()[name] = value
146
+ return value
147
+
148
+
149
+ def __dir__() -> list[str]:
150
+ """Return module attributes including lazy public exports."""
151
+ return sorted(set(globals()) | set(_EXPORT_MAP))
@@ -0,0 +1,10 @@
1
+ """Allow ``python -m aphelion_sdk`` to invoke the packaging CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import sys
6
+
7
+ from aphelion_sdk.cli.main import main
8
+
9
+ if __name__ == "__main__":
10
+ sys.exit(main())
@@ -0,0 +1,9 @@
1
+ """Audio plugin bases.
2
+
3
+ Not implemented in this release. Video effects use
4
+ ``aphelion_sdk.VideoEffectPlugin``.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ __all__: list[str] = []
@@ -0,0 +1,7 @@
1
+ """Command-line interface for the Aphelion Plugin SDK."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from aphelion_sdk.cli.main import main
6
+
7
+ __all__ = ["main"]