flowyml 1.7.1__py3-none-any.whl → 1.8.0__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.
Files changed (137) hide show
  1. flowyml/assets/base.py +15 -0
  2. flowyml/assets/dataset.py +570 -17
  3. flowyml/assets/metrics.py +5 -0
  4. flowyml/assets/model.py +1052 -15
  5. flowyml/cli/main.py +709 -0
  6. flowyml/cli/stack_cli.py +138 -25
  7. flowyml/core/__init__.py +17 -0
  8. flowyml/core/executor.py +231 -37
  9. flowyml/core/image_builder.py +129 -0
  10. flowyml/core/log_streamer.py +227 -0
  11. flowyml/core/orchestrator.py +59 -4
  12. flowyml/core/pipeline.py +65 -13
  13. flowyml/core/routing.py +558 -0
  14. flowyml/core/scheduler.py +88 -5
  15. flowyml/core/step.py +9 -1
  16. flowyml/core/step_grouping.py +49 -35
  17. flowyml/core/types.py +407 -0
  18. flowyml/integrations/keras.py +247 -82
  19. flowyml/monitoring/alerts.py +10 -0
  20. flowyml/monitoring/notifications.py +104 -25
  21. flowyml/monitoring/slack_blocks.py +323 -0
  22. flowyml/plugins/__init__.py +251 -0
  23. flowyml/plugins/alerters/__init__.py +1 -0
  24. flowyml/plugins/alerters/slack.py +168 -0
  25. flowyml/plugins/base.py +752 -0
  26. flowyml/plugins/config.py +478 -0
  27. flowyml/plugins/deployers/__init__.py +22 -0
  28. flowyml/plugins/deployers/gcp_cloud_run.py +200 -0
  29. flowyml/plugins/deployers/sagemaker.py +306 -0
  30. flowyml/plugins/deployers/vertex.py +290 -0
  31. flowyml/plugins/integration.py +369 -0
  32. flowyml/plugins/manager.py +510 -0
  33. flowyml/plugins/model_registries/__init__.py +22 -0
  34. flowyml/plugins/model_registries/mlflow.py +159 -0
  35. flowyml/plugins/model_registries/sagemaker.py +489 -0
  36. flowyml/plugins/model_registries/vertex.py +386 -0
  37. flowyml/plugins/orchestrators/__init__.py +13 -0
  38. flowyml/plugins/orchestrators/sagemaker.py +443 -0
  39. flowyml/plugins/orchestrators/vertex_ai.py +461 -0
  40. flowyml/plugins/registries/__init__.py +13 -0
  41. flowyml/plugins/registries/ecr.py +321 -0
  42. flowyml/plugins/registries/gcr.py +313 -0
  43. flowyml/plugins/registry.py +454 -0
  44. flowyml/plugins/stack.py +494 -0
  45. flowyml/plugins/stack_config.py +537 -0
  46. flowyml/plugins/stores/__init__.py +13 -0
  47. flowyml/plugins/stores/gcs.py +460 -0
  48. flowyml/plugins/stores/s3.py +453 -0
  49. flowyml/plugins/trackers/__init__.py +11 -0
  50. flowyml/plugins/trackers/mlflow.py +316 -0
  51. flowyml/plugins/validators/__init__.py +3 -0
  52. flowyml/plugins/validators/deepchecks.py +119 -0
  53. flowyml/registry/__init__.py +2 -1
  54. flowyml/registry/model_environment.py +109 -0
  55. flowyml/registry/model_registry.py +241 -96
  56. flowyml/serving/__init__.py +17 -0
  57. flowyml/serving/model_server.py +628 -0
  58. flowyml/stacks/__init__.py +60 -0
  59. flowyml/stacks/aws.py +93 -0
  60. flowyml/stacks/base.py +62 -0
  61. flowyml/stacks/components.py +12 -0
  62. flowyml/stacks/gcp.py +44 -9
  63. flowyml/stacks/plugins.py +115 -0
  64. flowyml/stacks/registry.py +2 -1
  65. flowyml/storage/sql.py +401 -12
  66. flowyml/tracking/experiment.py +8 -5
  67. flowyml/ui/backend/Dockerfile +87 -16
  68. flowyml/ui/backend/auth.py +12 -2
  69. flowyml/ui/backend/main.py +149 -5
  70. flowyml/ui/backend/routers/ai_context.py +226 -0
  71. flowyml/ui/backend/routers/assets.py +23 -4
  72. flowyml/ui/backend/routers/auth.py +96 -0
  73. flowyml/ui/backend/routers/deployments.py +660 -0
  74. flowyml/ui/backend/routers/model_explorer.py +597 -0
  75. flowyml/ui/backend/routers/plugins.py +103 -51
  76. flowyml/ui/backend/routers/projects.py +91 -8
  77. flowyml/ui/backend/routers/runs.py +132 -1
  78. flowyml/ui/backend/routers/schedules.py +54 -29
  79. flowyml/ui/backend/routers/templates.py +319 -0
  80. flowyml/ui/backend/routers/websocket.py +2 -2
  81. flowyml/ui/frontend/Dockerfile +55 -6
  82. flowyml/ui/frontend/dist/assets/index-B5AsPTSz.css +1 -0
  83. flowyml/ui/frontend/dist/assets/index-dFbZ8wD8.js +753 -0
  84. flowyml/ui/frontend/dist/index.html +2 -2
  85. flowyml/ui/frontend/dist/logo.png +0 -0
  86. flowyml/ui/frontend/nginx.conf +65 -4
  87. flowyml/ui/frontend/package-lock.json +1415 -74
  88. flowyml/ui/frontend/package.json +4 -0
  89. flowyml/ui/frontend/public/logo.png +0 -0
  90. flowyml/ui/frontend/src/App.jsx +10 -7
  91. flowyml/ui/frontend/src/app/assets/page.jsx +890 -321
  92. flowyml/ui/frontend/src/app/auth/Login.jsx +90 -0
  93. flowyml/ui/frontend/src/app/dashboard/page.jsx +8 -8
  94. flowyml/ui/frontend/src/app/deployments/page.jsx +786 -0
  95. flowyml/ui/frontend/src/app/model-explorer/page.jsx +1031 -0
  96. flowyml/ui/frontend/src/app/pipelines/page.jsx +12 -2
  97. flowyml/ui/frontend/src/app/projects/[projectId]/_components/ProjectExperimentsList.jsx +19 -6
  98. flowyml/ui/frontend/src/app/projects/[projectId]/_components/ProjectMetricsPanel.jsx +1 -1
  99. flowyml/ui/frontend/src/app/runs/[runId]/page.jsx +601 -101
  100. flowyml/ui/frontend/src/app/runs/page.jsx +8 -2
  101. flowyml/ui/frontend/src/app/settings/page.jsx +267 -253
  102. flowyml/ui/frontend/src/components/ArtifactViewer.jsx +62 -2
  103. flowyml/ui/frontend/src/components/AssetDetailsPanel.jsx +424 -29
  104. flowyml/ui/frontend/src/components/AssetTreeHierarchy.jsx +119 -11
  105. flowyml/ui/frontend/src/components/DatasetViewer.jsx +753 -0
  106. flowyml/ui/frontend/src/components/Layout.jsx +6 -0
  107. flowyml/ui/frontend/src/components/PipelineGraph.jsx +79 -29
  108. flowyml/ui/frontend/src/components/RunDetailsPanel.jsx +36 -6
  109. flowyml/ui/frontend/src/components/RunMetaPanel.jsx +113 -0
  110. flowyml/ui/frontend/src/components/TrainingHistoryChart.jsx +514 -0
  111. flowyml/ui/frontend/src/components/TrainingMetricsPanel.jsx +175 -0
  112. flowyml/ui/frontend/src/components/ai/AIAssistantButton.jsx +71 -0
  113. flowyml/ui/frontend/src/components/ai/AIAssistantPanel.jsx +420 -0
  114. flowyml/ui/frontend/src/components/header/Header.jsx +22 -0
  115. flowyml/ui/frontend/src/components/plugins/PluginManager.jsx +4 -4
  116. flowyml/ui/frontend/src/components/plugins/{ZenMLIntegration.jsx → StackImport.jsx} +38 -12
  117. flowyml/ui/frontend/src/components/sidebar/Sidebar.jsx +36 -13
  118. flowyml/ui/frontend/src/contexts/AIAssistantContext.jsx +245 -0
  119. flowyml/ui/frontend/src/contexts/AuthContext.jsx +108 -0
  120. flowyml/ui/frontend/src/hooks/useAIContext.js +156 -0
  121. flowyml/ui/frontend/src/hooks/useWebGPU.js +54 -0
  122. flowyml/ui/frontend/src/layouts/MainLayout.jsx +6 -0
  123. flowyml/ui/frontend/src/router/index.jsx +47 -20
  124. flowyml/ui/frontend/src/services/pluginService.js +3 -1
  125. flowyml/ui/server_manager.py +5 -5
  126. flowyml/ui/utils.py +157 -39
  127. flowyml/utils/config.py +37 -15
  128. flowyml/utils/model_introspection.py +123 -0
  129. flowyml/utils/observability.py +30 -0
  130. flowyml-1.8.0.dist-info/METADATA +174 -0
  131. {flowyml-1.7.1.dist-info → flowyml-1.8.0.dist-info}/RECORD +134 -73
  132. {flowyml-1.7.1.dist-info → flowyml-1.8.0.dist-info}/WHEEL +1 -1
  133. flowyml/ui/frontend/dist/assets/index-BqDQvp63.js +0 -630
  134. flowyml/ui/frontend/dist/assets/index-By4trVyv.css +0 -1
  135. flowyml-1.7.1.dist-info/METADATA +0 -477
  136. {flowyml-1.7.1.dist-info → flowyml-1.8.0.dist-info}/entry_points.txt +0 -0
  137. {flowyml-1.7.1.dist-info → flowyml-1.8.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,323 @@
1
+ """Slack Block Kit message builders for rich notifications.
2
+
3
+ This module provides utilities for building professional-looking Slack messages
4
+ using Block Kit components.
5
+ """
6
+
7
+ from datetime import datetime
8
+ from typing import Any
9
+
10
+
11
+ def _get_emoji(level: str) -> str:
12
+ """Get emoji for notification level."""
13
+ return {
14
+ "info": "ℹ️",
15
+ "warning": "⚠️",
16
+ "error": "❌",
17
+ "success": "✅",
18
+ "critical": "🚨",
19
+ }.get(level, "📢")
20
+
21
+
22
+ def _get_color(level: str) -> str:
23
+ """Get color for notification level."""
24
+ return {
25
+ "info": "#36a64f",
26
+ "warning": "#ff9900",
27
+ "error": "#ff0000",
28
+ "success": "#2eb886",
29
+ "critical": "#8b0000",
30
+ }.get(level, "#cccccc")
31
+
32
+
33
+ def build_header_block(text: str, emoji: str = "") -> dict:
34
+ """Build a header block."""
35
+ return {
36
+ "type": "header",
37
+ "text": {
38
+ "type": "plain_text",
39
+ "text": f"{emoji} {text}" if emoji else text,
40
+ "emoji": True,
41
+ },
42
+ }
43
+
44
+
45
+ def build_section_block(text: str, accessory: dict | None = None) -> dict:
46
+ """Build a section block with markdown text."""
47
+ block = {
48
+ "type": "section",
49
+ "text": {
50
+ "type": "mrkdwn",
51
+ "text": text,
52
+ },
53
+ }
54
+ if accessory:
55
+ block["accessory"] = accessory
56
+ return block
57
+
58
+
59
+ def build_context_block(elements: list[str]) -> dict:
60
+ """Build a context block with multiple text elements."""
61
+ return {
62
+ "type": "context",
63
+ "elements": [{"type": "mrkdwn", "text": el} for el in elements],
64
+ }
65
+
66
+
67
+ def build_divider() -> dict:
68
+ """Build a divider block."""
69
+ return {"type": "divider"}
70
+
71
+
72
+ def build_fields_section(fields: dict[str, Any]) -> dict:
73
+ """Build a section with multiple fields."""
74
+ return {
75
+ "type": "section",
76
+ "fields": [{"type": "mrkdwn", "text": f"*{key}*\n{value}"} for key, value in fields.items()],
77
+ }
78
+
79
+
80
+ def build_button_accessory(text: str, url: str, style: str = "primary") -> dict:
81
+ """Build a button accessory."""
82
+ return {
83
+ "type": "button",
84
+ "text": {"type": "plain_text", "text": text, "emoji": True},
85
+ "url": url,
86
+ "style": style,
87
+ }
88
+
89
+
90
+ def build_pipeline_success_message(
91
+ pipeline_name: str,
92
+ run_id: str,
93
+ duration: float,
94
+ metrics: dict[str, float] | None = None,
95
+ ui_url: str | None = None,
96
+ ) -> dict:
97
+ """Build a rich message for pipeline success."""
98
+ emoji = _get_emoji("success")
99
+
100
+ blocks = [
101
+ build_header_block("Pipeline Completed Successfully", emoji),
102
+ build_section_block(f"*{pipeline_name}* finished in `{duration:.2f}s`"),
103
+ build_divider(),
104
+ build_fields_section(
105
+ {
106
+ "Run ID": f"`{run_id[:12]}...`",
107
+ "Duration": f"{duration:.2f} seconds",
108
+ "Status": "✅ Success",
109
+ "Completed": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
110
+ },
111
+ ),
112
+ ]
113
+
114
+ if metrics:
115
+ metrics_text = "\n".join([f"• *{k}*: `{v:.4f}`" for k, v in metrics.items()])
116
+ blocks.append(build_section_block(f"*Metrics:*\n{metrics_text}"))
117
+
118
+ if ui_url:
119
+ blocks.append(
120
+ build_section_block(
121
+ "View run details in the FlowyML dashboard:",
122
+ accessory=build_button_accessory("View Run", f"{ui_url}/runs/{run_id}"),
123
+ ),
124
+ )
125
+
126
+ blocks.append(
127
+ build_context_block([f"FlowyML | {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"]),
128
+ )
129
+
130
+ return {
131
+ "attachments": [
132
+ {
133
+ "color": _get_color("success"),
134
+ "blocks": blocks,
135
+ },
136
+ ],
137
+ }
138
+
139
+
140
+ def build_pipeline_failure_message(
141
+ pipeline_name: str,
142
+ run_id: str,
143
+ error: str,
144
+ step_name: str | None = None,
145
+ ui_url: str | None = None,
146
+ ) -> dict:
147
+ """Build a rich message for pipeline failure."""
148
+ emoji = _get_emoji("error")
149
+
150
+ blocks = [
151
+ build_header_block("Pipeline Failed", emoji),
152
+ build_section_block(f"*{pipeline_name}* encountered an error"),
153
+ build_divider(),
154
+ build_fields_section(
155
+ {
156
+ "Run ID": f"`{run_id[:12]}...`",
157
+ "Status": "❌ Failed",
158
+ "Failed At": step_name or "Unknown step",
159
+ "Time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
160
+ },
161
+ ),
162
+ build_section_block(f"*Error:*\n```{error[:500]}```"),
163
+ ]
164
+
165
+ if ui_url:
166
+ blocks.append(
167
+ build_section_block(
168
+ "Investigate the failure in the FlowyML dashboard:",
169
+ accessory=build_button_accessory("View Run", f"{ui_url}/runs/{run_id}", style="danger"),
170
+ ),
171
+ )
172
+
173
+ blocks.append(
174
+ build_context_block([f"FlowyML | {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"]),
175
+ )
176
+
177
+ return {
178
+ "attachments": [
179
+ {
180
+ "color": _get_color("error"),
181
+ "blocks": blocks,
182
+ },
183
+ ],
184
+ }
185
+
186
+
187
+ def build_drift_warning_message(
188
+ feature: str,
189
+ psi: float,
190
+ threshold: float = 0.2,
191
+ model_name: str | None = None,
192
+ ui_url: str | None = None,
193
+ ) -> dict:
194
+ """Build a rich message for data drift detection."""
195
+ emoji = _get_emoji("warning")
196
+ severity = "High" if psi > 0.5 else "Medium" if psi > 0.25 else "Low"
197
+
198
+ blocks = [
199
+ build_header_block("Data Drift Detected", emoji),
200
+ build_section_block(
201
+ f"Drift detected in feature *{feature}*" + (f" for model *{model_name}*" if model_name else ""),
202
+ ),
203
+ build_divider(),
204
+ build_fields_section(
205
+ {
206
+ "Feature": feature,
207
+ "PSI Score": f"`{psi:.4f}`",
208
+ "Threshold": f"`{threshold:.2f}`",
209
+ "Severity": f"{'🔴' if severity == 'High' else '🟡' if severity == 'Medium' else '🟢'} {severity}",
210
+ },
211
+ ),
212
+ build_section_block(
213
+ "💡 *Recommended Actions:*\n"
214
+ "• Review recent data pipeline changes\n"
215
+ "• Check for upstream data quality issues\n"
216
+ "• Consider retraining the model if drift persists",
217
+ ),
218
+ ]
219
+
220
+ if ui_url:
221
+ blocks.append(
222
+ build_section_block(
223
+ "View drift analysis in the dashboard:",
224
+ accessory=build_button_accessory("View Analysis", f"{ui_url}/monitoring/drift"),
225
+ ),
226
+ )
227
+
228
+ blocks.append(
229
+ build_context_block([f"FlowyML Monitoring | {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"]),
230
+ )
231
+
232
+ return {
233
+ "attachments": [
234
+ {
235
+ "color": _get_color("warning"),
236
+ "blocks": blocks,
237
+ },
238
+ ],
239
+ }
240
+
241
+
242
+ def build_model_promoted_message(
243
+ model_name: str,
244
+ version: str,
245
+ from_stage: str,
246
+ to_stage: str,
247
+ author: str | None = None,
248
+ metrics: dict[str, float] | None = None,
249
+ ui_url: str | None = None,
250
+ ) -> dict:
251
+ """Build a rich message for model promotion."""
252
+ emoji = "🚀" if to_stage == "production" else "📦"
253
+
254
+ blocks = [
255
+ build_header_block(f"Model Promoted to {to_stage.title()}", emoji),
256
+ build_section_block(f"*{model_name}* version `{version}` has been promoted"),
257
+ build_divider(),
258
+ build_fields_section(
259
+ {
260
+ "Model": model_name,
261
+ "Version": f"`{version}`",
262
+ "Transition": f"{from_stage} → *{to_stage}*",
263
+ "Promoted By": author or "System",
264
+ },
265
+ ),
266
+ ]
267
+
268
+ if metrics:
269
+ metrics_text = " | ".join([f"*{k}*: `{v:.4f}`" for k, v in metrics.items()])
270
+ blocks.append(build_context_block([f"Metrics: {metrics_text}"]))
271
+
272
+ if ui_url:
273
+ blocks.append(
274
+ build_section_block(
275
+ "View model in registry:",
276
+ accessory=build_button_accessory("View Model", f"{ui_url}/models/{model_name}"),
277
+ ),
278
+ )
279
+
280
+ blocks.append(
281
+ build_context_block([f"FlowyML Registry | {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"]),
282
+ )
283
+
284
+ return {
285
+ "attachments": [
286
+ {
287
+ "color": _get_color("success") if to_stage == "production" else _get_color("info"),
288
+ "blocks": blocks,
289
+ },
290
+ ],
291
+ }
292
+
293
+
294
+ def build_simple_message(
295
+ title: str,
296
+ message: str,
297
+ level: str = "info",
298
+ metadata: dict[str, Any] | None = None,
299
+ ) -> dict:
300
+ """Build a simple notification message."""
301
+ emoji = _get_emoji(level)
302
+
303
+ blocks = [
304
+ build_header_block(title, emoji),
305
+ build_section_block(message),
306
+ ]
307
+
308
+ if metadata:
309
+ blocks.append(build_divider())
310
+ blocks.append(build_fields_section(metadata))
311
+
312
+ blocks.append(
313
+ build_context_block([f"FlowyML | {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"]),
314
+ )
315
+
316
+ return {
317
+ "attachments": [
318
+ {
319
+ "color": _get_color(level),
320
+ "blocks": blocks,
321
+ },
322
+ ],
323
+ }
@@ -0,0 +1,251 @@
1
+ """FlowyML Native Plugin System.
2
+
3
+ A powerful, extensible plugin system that allows you to easily
4
+ integrate with external tools without requiring any framework dependencies.
5
+
6
+ Quick Start:
7
+ # Install a plugin (just installs the underlying packages)
8
+ from flowyml.plugins import install, load, get_plugin
9
+
10
+ install("mlflow") # Installs mlflow package directly
11
+
12
+ # Load and use
13
+ tracker = get_plugin("mlflow", tracking_uri="http://localhost:5000")
14
+ tracker.start_run("my_experiment")
15
+ tracker.log_metrics({"accuracy": 0.95})
16
+ tracker.end_run()
17
+
18
+ Config-Based Usage (Recommended):
19
+ # flowyml.yaml
20
+ plugins:
21
+ experiment_tracker:
22
+ type: mlflow
23
+ tracking_uri: http://localhost:5000
24
+ artifact_store:
25
+ type: gcs
26
+ bucket: my-ml-artifacts
27
+
28
+ # In code - just use, no setup needed
29
+ from flowyml.plugins.stack import (
30
+ start_run, log_metrics, save_artifact, save_model
31
+ )
32
+
33
+ start_run("my_training")
34
+ log_metrics({"accuracy": 0.95})
35
+ save_model(model, "models/classifier")
36
+
37
+ CLI Usage:
38
+ # List available plugins
39
+ flowyml plugin list
40
+
41
+ # Install a plugin
42
+ flowyml plugin install mlflow
43
+
44
+ # Initialize config
45
+ flowyml stack init --tracker mlflow --store gcs
46
+
47
+ Extending FlowyML:
48
+ Community plugins can register via Python entry points:
49
+
50
+ # In pyproject.toml
51
+ [project.entry-points."flowyml.plugins"]
52
+ my_tracker = "my_package.plugins:MyTracker"
53
+ """
54
+
55
+ # Base classes for creating plugins
56
+ from flowyml.plugins.base import (
57
+ BasePlugin,
58
+ PluginType,
59
+ PluginMetadata,
60
+ # Core plugin types
61
+ ExperimentTracker,
62
+ ArtifactStorePlugin,
63
+ OrchestratorPlugin,
64
+ ContainerRegistryPlugin,
65
+ FeatureStorePlugin,
66
+ DataValidatorPlugin,
67
+ ModelRegistryPlugin,
68
+ ModelDeployerPlugin,
69
+ AlerterPlugin,
70
+ )
71
+
72
+ # Registry for discovering plugins
73
+ from flowyml.plugins.registry import (
74
+ PluginInfo,
75
+ PluginStatus,
76
+ PLUGIN_CATALOG,
77
+ get_plugin_info,
78
+ list_plugins,
79
+ list_plugin_names,
80
+ register_plugin,
81
+ unregister_plugin,
82
+ )
83
+
84
+ # Manager for installing and loading plugins
85
+ from flowyml.plugins.manager import (
86
+ PluginManager,
87
+ get_manager,
88
+ install,
89
+ load,
90
+ get_plugin,
91
+ list_available,
92
+ list_installed,
93
+ is_installed,
94
+ )
95
+
96
+ # Config-based plugin access
97
+ from flowyml.plugins.config import (
98
+ PluginConfig,
99
+ get_config,
100
+ reload_config,
101
+ get_tracker,
102
+ get_artifact_store,
103
+ get_orchestrator,
104
+ get_container_registry,
105
+ get_feature_store,
106
+ get_data_validator,
107
+ get_alerter,
108
+ generate_config_template,
109
+ )
110
+
111
+ # Multi-stack configuration
112
+ from flowyml.plugins.stack_config import (
113
+ StackManager,
114
+ StackConfig,
115
+ ArtifactRoutingRule,
116
+ ArtifactRoutingConfig,
117
+ get_stack_manager,
118
+ get_active_stack,
119
+ list_stacks,
120
+ set_active_stack,
121
+ use_stack,
122
+ use_stack_decorator,
123
+ get_routing_for_type,
124
+ )
125
+
126
+ # Unified stack interface (config-driven)
127
+ from flowyml.plugins.stack import (
128
+ # Experiment tracking
129
+ start_run,
130
+ end_run,
131
+ run,
132
+ log_params,
133
+ log_metrics,
134
+ log_artifact,
135
+ set_tag,
136
+ set_tags,
137
+ # Artifact storage
138
+ save_artifact,
139
+ load_artifact,
140
+ artifact_exists,
141
+ list_artifacts,
142
+ delete_artifact,
143
+ # Model management
144
+ save_model,
145
+ load_model,
146
+ # Container registry
147
+ push_image,
148
+ get_image_uri,
149
+ # Orchestration
150
+ run_pipeline,
151
+ # Alerts
152
+ send_alert,
153
+ # Stack info
154
+ show_stack,
155
+ validate_stack,
156
+ )
157
+
158
+ # Pipeline integration
159
+ from flowyml.plugins.integration import (
160
+ StackContext,
161
+ run_with_stack,
162
+ tracked,
163
+ PipelinePluginIntegration,
164
+ get_integration,
165
+ )
166
+
167
+ __all__ = [
168
+ # Base classes
169
+ "BasePlugin",
170
+ "PluginType",
171
+ "PluginMetadata",
172
+ "ExperimentTracker",
173
+ "ArtifactStorePlugin",
174
+ "OrchestratorPlugin",
175
+ "ContainerRegistryPlugin",
176
+ "FeatureStorePlugin",
177
+ "DataValidatorPlugin",
178
+ "ModelRegistryPlugin",
179
+ "ModelDeployerPlugin",
180
+ "AlerterPlugin",
181
+ # Registry
182
+ "PluginInfo",
183
+ "PluginStatus",
184
+ "PLUGIN_CATALOG",
185
+ "get_plugin_info",
186
+ "list_plugins",
187
+ "list_plugin_names",
188
+ "register_plugin",
189
+ "unregister_plugin",
190
+ # Manager
191
+ "PluginManager",
192
+ "get_manager",
193
+ "install",
194
+ "load",
195
+ "get_plugin",
196
+ "list_available",
197
+ "list_installed",
198
+ "is_installed",
199
+ # Config
200
+ "PluginConfig",
201
+ "get_config",
202
+ "reload_config",
203
+ "get_tracker",
204
+ "get_artifact_store",
205
+ "get_orchestrator",
206
+ "get_container_registry",
207
+ "get_feature_store",
208
+ "get_data_validator",
209
+ "get_alerter",
210
+ "generate_config_template",
211
+ # Stack (unified interface)
212
+ "start_run",
213
+ "end_run",
214
+ "run",
215
+ "log_params",
216
+ "log_metrics",
217
+ "log_artifact",
218
+ "set_tag",
219
+ "set_tags",
220
+ "save_artifact",
221
+ "load_artifact",
222
+ "artifact_exists",
223
+ "list_artifacts",
224
+ "delete_artifact",
225
+ "save_model",
226
+ "load_model",
227
+ "push_image",
228
+ "get_image_uri",
229
+ "run_pipeline",
230
+ "send_alert",
231
+ "show_stack",
232
+ "validate_stack",
233
+ # Integration
234
+ "StackContext",
235
+ "run_with_stack",
236
+ "tracked",
237
+ "PipelinePluginIntegration",
238
+ "get_integration",
239
+ # Multi-stack configuration
240
+ "StackManager",
241
+ "StackConfig",
242
+ "ArtifactRoutingRule",
243
+ "ArtifactRoutingConfig",
244
+ "get_stack_manager",
245
+ "get_active_stack",
246
+ "list_stacks",
247
+ "set_active_stack",
248
+ "use_stack",
249
+ "use_stack_decorator",
250
+ "get_routing_for_type",
251
+ ]
@@ -0,0 +1 @@
1
+ """Alerter plugins for FlowyML."""