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.
- flowyml/assets/base.py +15 -0
- flowyml/assets/dataset.py +570 -17
- flowyml/assets/metrics.py +5 -0
- flowyml/assets/model.py +1052 -15
- flowyml/cli/main.py +709 -0
- flowyml/cli/stack_cli.py +138 -25
- flowyml/core/__init__.py +17 -0
- flowyml/core/executor.py +231 -37
- flowyml/core/image_builder.py +129 -0
- flowyml/core/log_streamer.py +227 -0
- flowyml/core/orchestrator.py +59 -4
- flowyml/core/pipeline.py +65 -13
- flowyml/core/routing.py +558 -0
- flowyml/core/scheduler.py +88 -5
- flowyml/core/step.py +9 -1
- flowyml/core/step_grouping.py +49 -35
- flowyml/core/types.py +407 -0
- flowyml/integrations/keras.py +247 -82
- flowyml/monitoring/alerts.py +10 -0
- flowyml/monitoring/notifications.py +104 -25
- flowyml/monitoring/slack_blocks.py +323 -0
- flowyml/plugins/__init__.py +251 -0
- flowyml/plugins/alerters/__init__.py +1 -0
- flowyml/plugins/alerters/slack.py +168 -0
- flowyml/plugins/base.py +752 -0
- flowyml/plugins/config.py +478 -0
- flowyml/plugins/deployers/__init__.py +22 -0
- flowyml/plugins/deployers/gcp_cloud_run.py +200 -0
- flowyml/plugins/deployers/sagemaker.py +306 -0
- flowyml/plugins/deployers/vertex.py +290 -0
- flowyml/plugins/integration.py +369 -0
- flowyml/plugins/manager.py +510 -0
- flowyml/plugins/model_registries/__init__.py +22 -0
- flowyml/plugins/model_registries/mlflow.py +159 -0
- flowyml/plugins/model_registries/sagemaker.py +489 -0
- flowyml/plugins/model_registries/vertex.py +386 -0
- flowyml/plugins/orchestrators/__init__.py +13 -0
- flowyml/plugins/orchestrators/sagemaker.py +443 -0
- flowyml/plugins/orchestrators/vertex_ai.py +461 -0
- flowyml/plugins/registries/__init__.py +13 -0
- flowyml/plugins/registries/ecr.py +321 -0
- flowyml/plugins/registries/gcr.py +313 -0
- flowyml/plugins/registry.py +454 -0
- flowyml/plugins/stack.py +494 -0
- flowyml/plugins/stack_config.py +537 -0
- flowyml/plugins/stores/__init__.py +13 -0
- flowyml/plugins/stores/gcs.py +460 -0
- flowyml/plugins/stores/s3.py +453 -0
- flowyml/plugins/trackers/__init__.py +11 -0
- flowyml/plugins/trackers/mlflow.py +316 -0
- flowyml/plugins/validators/__init__.py +3 -0
- flowyml/plugins/validators/deepchecks.py +119 -0
- flowyml/registry/__init__.py +2 -1
- flowyml/registry/model_environment.py +109 -0
- flowyml/registry/model_registry.py +241 -96
- flowyml/serving/__init__.py +17 -0
- flowyml/serving/model_server.py +628 -0
- flowyml/stacks/__init__.py +60 -0
- flowyml/stacks/aws.py +93 -0
- flowyml/stacks/base.py +62 -0
- flowyml/stacks/components.py +12 -0
- flowyml/stacks/gcp.py +44 -9
- flowyml/stacks/plugins.py +115 -0
- flowyml/stacks/registry.py +2 -1
- flowyml/storage/sql.py +401 -12
- flowyml/tracking/experiment.py +8 -5
- flowyml/ui/backend/Dockerfile +87 -16
- flowyml/ui/backend/auth.py +12 -2
- flowyml/ui/backend/main.py +149 -5
- flowyml/ui/backend/routers/ai_context.py +226 -0
- flowyml/ui/backend/routers/assets.py +23 -4
- flowyml/ui/backend/routers/auth.py +96 -0
- flowyml/ui/backend/routers/deployments.py +660 -0
- flowyml/ui/backend/routers/model_explorer.py +597 -0
- flowyml/ui/backend/routers/plugins.py +103 -51
- flowyml/ui/backend/routers/projects.py +91 -8
- flowyml/ui/backend/routers/runs.py +132 -1
- flowyml/ui/backend/routers/schedules.py +54 -29
- flowyml/ui/backend/routers/templates.py +319 -0
- flowyml/ui/backend/routers/websocket.py +2 -2
- flowyml/ui/frontend/Dockerfile +55 -6
- flowyml/ui/frontend/dist/assets/index-B5AsPTSz.css +1 -0
- flowyml/ui/frontend/dist/assets/index-dFbZ8wD8.js +753 -0
- flowyml/ui/frontend/dist/index.html +2 -2
- flowyml/ui/frontend/dist/logo.png +0 -0
- flowyml/ui/frontend/nginx.conf +65 -4
- flowyml/ui/frontend/package-lock.json +1415 -74
- flowyml/ui/frontend/package.json +4 -0
- flowyml/ui/frontend/public/logo.png +0 -0
- flowyml/ui/frontend/src/App.jsx +10 -7
- flowyml/ui/frontend/src/app/assets/page.jsx +890 -321
- flowyml/ui/frontend/src/app/auth/Login.jsx +90 -0
- flowyml/ui/frontend/src/app/dashboard/page.jsx +8 -8
- flowyml/ui/frontend/src/app/deployments/page.jsx +786 -0
- flowyml/ui/frontend/src/app/model-explorer/page.jsx +1031 -0
- flowyml/ui/frontend/src/app/pipelines/page.jsx +12 -2
- flowyml/ui/frontend/src/app/projects/[projectId]/_components/ProjectExperimentsList.jsx +19 -6
- flowyml/ui/frontend/src/app/projects/[projectId]/_components/ProjectMetricsPanel.jsx +1 -1
- flowyml/ui/frontend/src/app/runs/[runId]/page.jsx +601 -101
- flowyml/ui/frontend/src/app/runs/page.jsx +8 -2
- flowyml/ui/frontend/src/app/settings/page.jsx +267 -253
- flowyml/ui/frontend/src/components/ArtifactViewer.jsx +62 -2
- flowyml/ui/frontend/src/components/AssetDetailsPanel.jsx +424 -29
- flowyml/ui/frontend/src/components/AssetTreeHierarchy.jsx +119 -11
- flowyml/ui/frontend/src/components/DatasetViewer.jsx +753 -0
- flowyml/ui/frontend/src/components/Layout.jsx +6 -0
- flowyml/ui/frontend/src/components/PipelineGraph.jsx +79 -29
- flowyml/ui/frontend/src/components/RunDetailsPanel.jsx +36 -6
- flowyml/ui/frontend/src/components/RunMetaPanel.jsx +113 -0
- flowyml/ui/frontend/src/components/TrainingHistoryChart.jsx +514 -0
- flowyml/ui/frontend/src/components/TrainingMetricsPanel.jsx +175 -0
- flowyml/ui/frontend/src/components/ai/AIAssistantButton.jsx +71 -0
- flowyml/ui/frontend/src/components/ai/AIAssistantPanel.jsx +420 -0
- flowyml/ui/frontend/src/components/header/Header.jsx +22 -0
- flowyml/ui/frontend/src/components/plugins/PluginManager.jsx +4 -4
- flowyml/ui/frontend/src/components/plugins/{ZenMLIntegration.jsx → StackImport.jsx} +38 -12
- flowyml/ui/frontend/src/components/sidebar/Sidebar.jsx +36 -13
- flowyml/ui/frontend/src/contexts/AIAssistantContext.jsx +245 -0
- flowyml/ui/frontend/src/contexts/AuthContext.jsx +108 -0
- flowyml/ui/frontend/src/hooks/useAIContext.js +156 -0
- flowyml/ui/frontend/src/hooks/useWebGPU.js +54 -0
- flowyml/ui/frontend/src/layouts/MainLayout.jsx +6 -0
- flowyml/ui/frontend/src/router/index.jsx +47 -20
- flowyml/ui/frontend/src/services/pluginService.js +3 -1
- flowyml/ui/server_manager.py +5 -5
- flowyml/ui/utils.py +157 -39
- flowyml/utils/config.py +37 -15
- flowyml/utils/model_introspection.py +123 -0
- flowyml/utils/observability.py +30 -0
- flowyml-1.8.0.dist-info/METADATA +174 -0
- {flowyml-1.7.1.dist-info → flowyml-1.8.0.dist-info}/RECORD +134 -73
- {flowyml-1.7.1.dist-info → flowyml-1.8.0.dist-info}/WHEEL +1 -1
- flowyml/ui/frontend/dist/assets/index-BqDQvp63.js +0 -630
- flowyml/ui/frontend/dist/assets/index-By4trVyv.css +0 -1
- flowyml-1.7.1.dist-info/METADATA +0 -477
- {flowyml-1.7.1.dist-info → flowyml-1.8.0.dist-info}/entry_points.txt +0 -0
- {flowyml-1.7.1.dist-info → flowyml-1.8.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,454 @@
|
|
|
1
|
+
"""FlowyML Plugin Registry - Plugin Catalog and Discovery.
|
|
2
|
+
|
|
3
|
+
This module defines the catalog of available plugins and provides
|
|
4
|
+
discovery mechanisms for finding and loading plugins.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
from flowyml.plugins.registry import PLUGIN_CATALOG, get_plugin_info
|
|
8
|
+
|
|
9
|
+
# Get info about a plugin
|
|
10
|
+
info = get_plugin_info("mlflow")
|
|
11
|
+
|
|
12
|
+
# List all available plugins
|
|
13
|
+
plugins = list_plugins()
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from dataclasses import dataclass, field
|
|
17
|
+
from enum import Enum
|
|
18
|
+
|
|
19
|
+
from flowyml.plugins.base import PluginType
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class PluginStatus(Enum):
|
|
23
|
+
"""Status of a plugin."""
|
|
24
|
+
|
|
25
|
+
AVAILABLE = "available" # Plugin is in catalog, packages not installed
|
|
26
|
+
INSTALLED = "installed" # Packages are installed
|
|
27
|
+
LOADED = "loaded" # Plugin class has been loaded
|
|
28
|
+
DEPRECATED = "deprecated" # Plugin is deprecated
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass
|
|
32
|
+
class PluginInfo:
|
|
33
|
+
"""Information about a plugin in the catalog."""
|
|
34
|
+
|
|
35
|
+
# Basic info
|
|
36
|
+
name: str
|
|
37
|
+
description: str
|
|
38
|
+
plugin_type: PluginType
|
|
39
|
+
|
|
40
|
+
# Package requirements
|
|
41
|
+
packages: list[str] = field(default_factory=list)
|
|
42
|
+
|
|
43
|
+
# Plugin class location
|
|
44
|
+
wrapper_path: str = "" # e.g., "flowyml.plugins.trackers.mlflow:MLflowTracker"
|
|
45
|
+
|
|
46
|
+
# Metadata
|
|
47
|
+
version: str = "1.0.0"
|
|
48
|
+
author: str = "FlowyML"
|
|
49
|
+
documentation_url: str = ""
|
|
50
|
+
tags: list[str] = field(default_factory=list)
|
|
51
|
+
|
|
52
|
+
# Status
|
|
53
|
+
status: PluginStatus = PluginStatus.AVAILABLE
|
|
54
|
+
|
|
55
|
+
# Optional extras
|
|
56
|
+
optional_packages: list[str] = field(default_factory=list)
|
|
57
|
+
|
|
58
|
+
def __post_init__(self):
|
|
59
|
+
"""Validate and normalize fields."""
|
|
60
|
+
if isinstance(self.plugin_type, str):
|
|
61
|
+
self.plugin_type = PluginType(self.plugin_type)
|
|
62
|
+
if isinstance(self.status, str):
|
|
63
|
+
self.status = PluginStatus(self.status)
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# ============================================================================
|
|
67
|
+
# OFFICIAL PLUGIN CATALOG
|
|
68
|
+
# ============================================================================
|
|
69
|
+
|
|
70
|
+
PLUGIN_CATALOG: dict[str, PluginInfo] = {
|
|
71
|
+
# -------------------------------------------------------------------------
|
|
72
|
+
# EXPERIMENT TRACKERS
|
|
73
|
+
# -------------------------------------------------------------------------
|
|
74
|
+
"mlflow": PluginInfo(
|
|
75
|
+
name="mlflow",
|
|
76
|
+
description="MLflow experiment tracking and model registry",
|
|
77
|
+
plugin_type=PluginType.EXPERIMENT_TRACKER,
|
|
78
|
+
packages=["mlflow>=2.0"],
|
|
79
|
+
wrapper_path="flowyml.plugins.trackers.mlflow:MLflowTracker",
|
|
80
|
+
documentation_url="https://mlflow.org/docs/latest/index.html",
|
|
81
|
+
tags=["experiment-tracking", "model-registry", "popular"],
|
|
82
|
+
),
|
|
83
|
+
"wandb": PluginInfo(
|
|
84
|
+
name="wandb",
|
|
85
|
+
description="Weights & Biases experiment tracking",
|
|
86
|
+
plugin_type=PluginType.EXPERIMENT_TRACKER,
|
|
87
|
+
packages=["wandb>=0.15"],
|
|
88
|
+
wrapper_path="flowyml.plugins.trackers.wandb:WandbTracker",
|
|
89
|
+
documentation_url="https://docs.wandb.ai/",
|
|
90
|
+
tags=["experiment-tracking", "visualization", "popular"],
|
|
91
|
+
),
|
|
92
|
+
"neptune": PluginInfo(
|
|
93
|
+
name="neptune",
|
|
94
|
+
description="Neptune.ai experiment tracking",
|
|
95
|
+
plugin_type=PluginType.EXPERIMENT_TRACKER,
|
|
96
|
+
packages=["neptune>=1.0"],
|
|
97
|
+
wrapper_path="flowyml.plugins.trackers.neptune:NeptuneTracker",
|
|
98
|
+
documentation_url="https://docs.neptune.ai/",
|
|
99
|
+
tags=["experiment-tracking", "visualization"],
|
|
100
|
+
),
|
|
101
|
+
"tensorboard": PluginInfo(
|
|
102
|
+
name="tensorboard",
|
|
103
|
+
description="TensorBoard visualization and logging",
|
|
104
|
+
plugin_type=PluginType.EXPERIMENT_TRACKER,
|
|
105
|
+
packages=["tensorboard>=2.10"],
|
|
106
|
+
wrapper_path="flowyml.plugins.trackers.tensorboard:TensorBoardTracker",
|
|
107
|
+
documentation_url="https://www.tensorflow.org/tensorboard",
|
|
108
|
+
tags=["experiment-tracking", "visualization", "tensorflow"],
|
|
109
|
+
),
|
|
110
|
+
# -------------------------------------------------------------------------
|
|
111
|
+
# ARTIFACT STORES - Cloud
|
|
112
|
+
# -------------------------------------------------------------------------
|
|
113
|
+
"s3": PluginInfo(
|
|
114
|
+
name="s3",
|
|
115
|
+
description="AWS S3 artifact storage",
|
|
116
|
+
plugin_type=PluginType.ARTIFACT_STORE,
|
|
117
|
+
packages=["boto3>=1.28", "s3fs>=2023.0"],
|
|
118
|
+
wrapper_path="flowyml.plugins.stores.s3:S3ArtifactStore",
|
|
119
|
+
documentation_url="https://docs.aws.amazon.com/s3/",
|
|
120
|
+
tags=["artifact-store", "aws", "cloud", "popular"],
|
|
121
|
+
),
|
|
122
|
+
"gcs": PluginInfo(
|
|
123
|
+
name="gcs",
|
|
124
|
+
description="Google Cloud Storage artifact storage",
|
|
125
|
+
plugin_type=PluginType.ARTIFACT_STORE,
|
|
126
|
+
packages=["google-cloud-storage>=2.0", "gcsfs>=2023.0"],
|
|
127
|
+
wrapper_path="flowyml.plugins.stores.gcs:GCSArtifactStore",
|
|
128
|
+
documentation_url="https://cloud.google.com/storage/docs",
|
|
129
|
+
tags=["artifact-store", "gcp", "cloud", "popular"],
|
|
130
|
+
),
|
|
131
|
+
"azure_blob": PluginInfo(
|
|
132
|
+
name="azure_blob",
|
|
133
|
+
description="Azure Blob Storage artifact storage",
|
|
134
|
+
plugin_type=PluginType.ARTIFACT_STORE,
|
|
135
|
+
packages=["azure-storage-blob>=12.0", "adlfs>=2023.0"],
|
|
136
|
+
wrapper_path="flowyml.plugins.stores.azure:AzureBlobArtifactStore",
|
|
137
|
+
documentation_url="https://docs.microsoft.com/azure/storage/blobs/",
|
|
138
|
+
tags=["artifact-store", "azure", "cloud"],
|
|
139
|
+
),
|
|
140
|
+
# -------------------------------------------------------------------------
|
|
141
|
+
# ORCHESTRATORS
|
|
142
|
+
# -------------------------------------------------------------------------
|
|
143
|
+
"kubernetes": PluginInfo(
|
|
144
|
+
name="kubernetes",
|
|
145
|
+
description="Kubernetes orchestration for pipeline execution",
|
|
146
|
+
plugin_type=PluginType.ORCHESTRATOR,
|
|
147
|
+
packages=["kubernetes>=25.0"],
|
|
148
|
+
wrapper_path="flowyml.plugins.orchestrators.kubernetes:KubernetesOrchestrator",
|
|
149
|
+
documentation_url="https://kubernetes.io/docs/",
|
|
150
|
+
tags=["orchestrator", "kubernetes", "cloud", "popular"],
|
|
151
|
+
),
|
|
152
|
+
"airflow": PluginInfo(
|
|
153
|
+
name="airflow",
|
|
154
|
+
description="Apache Airflow DAG-based orchestration",
|
|
155
|
+
plugin_type=PluginType.ORCHESTRATOR,
|
|
156
|
+
packages=["apache-airflow>=2.5"],
|
|
157
|
+
wrapper_path="flowyml.plugins.orchestrators.airflow:AirflowOrchestrator",
|
|
158
|
+
documentation_url="https://airflow.apache.org/docs/",
|
|
159
|
+
tags=["orchestrator", "airflow", "dag"],
|
|
160
|
+
),
|
|
161
|
+
"kubeflow": PluginInfo(
|
|
162
|
+
name="kubeflow",
|
|
163
|
+
description="Kubeflow Pipelines orchestration",
|
|
164
|
+
plugin_type=PluginType.ORCHESTRATOR,
|
|
165
|
+
packages=["kfp>=2.0"],
|
|
166
|
+
wrapper_path="flowyml.plugins.orchestrators.kubeflow:KubeflowOrchestrator",
|
|
167
|
+
documentation_url="https://www.kubeflow.org/docs/",
|
|
168
|
+
tags=["orchestrator", "kubeflow", "kubernetes"],
|
|
169
|
+
),
|
|
170
|
+
"ray": PluginInfo(
|
|
171
|
+
name="ray",
|
|
172
|
+
description="Ray distributed computing orchestration",
|
|
173
|
+
plugin_type=PluginType.ORCHESTRATOR,
|
|
174
|
+
packages=["ray>=2.0"],
|
|
175
|
+
wrapper_path="flowyml.plugins.orchestrators.ray:RayOrchestrator",
|
|
176
|
+
documentation_url="https://docs.ray.io/",
|
|
177
|
+
tags=["orchestrator", "ray", "distributed"],
|
|
178
|
+
),
|
|
179
|
+
"vertex_ai": PluginInfo(
|
|
180
|
+
name="vertex_ai",
|
|
181
|
+
description="Google Cloud Vertex AI Pipelines orchestration",
|
|
182
|
+
plugin_type=PluginType.ORCHESTRATOR,
|
|
183
|
+
packages=["google-cloud-aiplatform>=1.25", "kfp>=2.0"],
|
|
184
|
+
wrapper_path="flowyml.plugins.orchestrators.vertex_ai:VertexAIOrchestrator",
|
|
185
|
+
documentation_url="https://cloud.google.com/vertex-ai/docs/pipelines",
|
|
186
|
+
tags=["orchestrator", "gcp", "cloud", "vertex-ai"],
|
|
187
|
+
),
|
|
188
|
+
"sagemaker": PluginInfo(
|
|
189
|
+
name="sagemaker",
|
|
190
|
+
description="AWS SageMaker Pipelines orchestration",
|
|
191
|
+
plugin_type=PluginType.ORCHESTRATOR,
|
|
192
|
+
packages=["sagemaker>=2.100"],
|
|
193
|
+
wrapper_path="flowyml.plugins.orchestrators.sagemaker:SageMakerOrchestrator",
|
|
194
|
+
documentation_url="https://docs.aws.amazon.com/sagemaker/latest/dg/pipelines.html",
|
|
195
|
+
tags=["orchestrator", "aws", "cloud", "sagemaker"],
|
|
196
|
+
),
|
|
197
|
+
# -------------------------------------------------------------------------
|
|
198
|
+
# CONTAINER REGISTRIES
|
|
199
|
+
# -------------------------------------------------------------------------
|
|
200
|
+
"docker": PluginInfo(
|
|
201
|
+
name="docker",
|
|
202
|
+
description="Local Docker registry support",
|
|
203
|
+
plugin_type=PluginType.CONTAINER_REGISTRY,
|
|
204
|
+
packages=["docker>=6.0"],
|
|
205
|
+
wrapper_path="flowyml.plugins.registries.docker:DockerRegistry",
|
|
206
|
+
documentation_url="https://docs.docker.com/registry/",
|
|
207
|
+
tags=["container-registry", "docker", "local"],
|
|
208
|
+
),
|
|
209
|
+
"ecr": PluginInfo(
|
|
210
|
+
name="ecr",
|
|
211
|
+
description="AWS Elastic Container Registry",
|
|
212
|
+
plugin_type=PluginType.CONTAINER_REGISTRY,
|
|
213
|
+
packages=["boto3>=1.28"],
|
|
214
|
+
wrapper_path="flowyml.plugins.registries.ecr:ECRRegistry",
|
|
215
|
+
documentation_url="https://docs.aws.amazon.com/ecr/",
|
|
216
|
+
tags=["container-registry", "aws", "cloud"],
|
|
217
|
+
),
|
|
218
|
+
"gcr": PluginInfo(
|
|
219
|
+
name="gcr",
|
|
220
|
+
description="Google Container Registry / Artifact Registry",
|
|
221
|
+
plugin_type=PluginType.CONTAINER_REGISTRY,
|
|
222
|
+
packages=["google-cloud-artifact-registry>=1.0"],
|
|
223
|
+
wrapper_path="flowyml.plugins.registries.gcr:GCRRegistry",
|
|
224
|
+
documentation_url="https://cloud.google.com/artifact-registry/docs",
|
|
225
|
+
tags=["container-registry", "gcp", "cloud"],
|
|
226
|
+
),
|
|
227
|
+
"acr": PluginInfo(
|
|
228
|
+
name="acr",
|
|
229
|
+
description="Azure Container Registry",
|
|
230
|
+
plugin_type=PluginType.CONTAINER_REGISTRY,
|
|
231
|
+
packages=["azure-mgmt-containerregistry>=10.0"],
|
|
232
|
+
wrapper_path="flowyml.plugins.registries.acr:ACRRegistry",
|
|
233
|
+
documentation_url="https://docs.microsoft.com/azure/container-registry/",
|
|
234
|
+
tags=["container-registry", "azure", "cloud"],
|
|
235
|
+
),
|
|
236
|
+
# -------------------------------------------------------------------------
|
|
237
|
+
# FEATURE STORES
|
|
238
|
+
# -------------------------------------------------------------------------
|
|
239
|
+
"feast": PluginInfo(
|
|
240
|
+
name="feast",
|
|
241
|
+
description="Feast feature store",
|
|
242
|
+
plugin_type=PluginType.FEATURE_STORE,
|
|
243
|
+
packages=["feast>=0.30"],
|
|
244
|
+
wrapper_path="flowyml.plugins.stores.feast:FeastFeatureStore",
|
|
245
|
+
documentation_url="https://docs.feast.dev/",
|
|
246
|
+
tags=["feature-store", "ml-features", "popular"],
|
|
247
|
+
),
|
|
248
|
+
# -------------------------------------------------------------------------
|
|
249
|
+
# DATA VALIDATORS
|
|
250
|
+
# -------------------------------------------------------------------------
|
|
251
|
+
"great_expectations": PluginInfo(
|
|
252
|
+
name="great_expectations",
|
|
253
|
+
description="Great Expectations data validation",
|
|
254
|
+
plugin_type=PluginType.DATA_VALIDATOR,
|
|
255
|
+
packages=["great_expectations>=0.17"],
|
|
256
|
+
wrapper_path="flowyml.plugins.validators.great_expectations:GEValidator",
|
|
257
|
+
documentation_url="https://docs.greatexpectations.io/",
|
|
258
|
+
tags=["data-validation", "testing", "popular"],
|
|
259
|
+
),
|
|
260
|
+
"pandera": PluginInfo(
|
|
261
|
+
name="pandera",
|
|
262
|
+
description="Pandera DataFrame validation",
|
|
263
|
+
plugin_type=PluginType.DATA_VALIDATOR,
|
|
264
|
+
packages=["pandera>=0.15"],
|
|
265
|
+
wrapper_path="flowyml.plugins.validators.pandera:PanderaValidator",
|
|
266
|
+
documentation_url="https://pandera.readthedocs.io/",
|
|
267
|
+
tags=["data-validation", "pandas", "schema"],
|
|
268
|
+
),
|
|
269
|
+
"deepchecks": PluginInfo(
|
|
270
|
+
name="deepchecks",
|
|
271
|
+
description="Deepchecks Data Validator",
|
|
272
|
+
plugin_type=PluginType.DATA_VALIDATOR,
|
|
273
|
+
packages=["deepchecks>=0.17.0"],
|
|
274
|
+
wrapper_path="flowyml.plugins.validators.deepchecks:DeepchecksValidator",
|
|
275
|
+
documentation_url="https://docs.deepchecks.com/stable/general/usage/tabular/index.html",
|
|
276
|
+
tags=["data-validation", "drift", "integrity"],
|
|
277
|
+
),
|
|
278
|
+
# -------------------------------------------------------------------------
|
|
279
|
+
# ALERTERS
|
|
280
|
+
# -------------------------------------------------------------------------
|
|
281
|
+
"slack": PluginInfo(
|
|
282
|
+
name="slack",
|
|
283
|
+
description="Slack notifications",
|
|
284
|
+
plugin_type=PluginType.ALERTER,
|
|
285
|
+
packages=["slack-sdk>=3.0"],
|
|
286
|
+
wrapper_path="flowyml.plugins.alerters.slack:SlackAlerter",
|
|
287
|
+
documentation_url="https://api.slack.com/",
|
|
288
|
+
tags=["alerter", "notifications", "popular"],
|
|
289
|
+
),
|
|
290
|
+
"discord": PluginInfo(
|
|
291
|
+
name="discord",
|
|
292
|
+
description="Discord webhook notifications",
|
|
293
|
+
plugin_type=PluginType.ALERTER,
|
|
294
|
+
packages=["discord-webhook>=1.0"],
|
|
295
|
+
wrapper_path="flowyml.plugins.alerters.discord:DiscordAlerter",
|
|
296
|
+
documentation_url="https://discord.com/developers/docs/resources/webhook",
|
|
297
|
+
tags=["alerter", "notifications"],
|
|
298
|
+
),
|
|
299
|
+
"pagerduty": PluginInfo(
|
|
300
|
+
name="pagerduty",
|
|
301
|
+
description="PagerDuty incident management",
|
|
302
|
+
plugin_type=PluginType.ALERTER,
|
|
303
|
+
packages=["pdpyras>=4.0"],
|
|
304
|
+
wrapper_path="flowyml.plugins.alerters.pagerduty:PagerDutyAlerter",
|
|
305
|
+
documentation_url="https://developer.pagerduty.com/",
|
|
306
|
+
tags=["alerter", "incident-management", "enterprise"],
|
|
307
|
+
),
|
|
308
|
+
# -------------------------------------------------------------------------
|
|
309
|
+
# MODEL REGISTRIES
|
|
310
|
+
# -------------------------------------------------------------------------
|
|
311
|
+
"vertex_model_registry": PluginInfo(
|
|
312
|
+
name="vertex_model_registry",
|
|
313
|
+
description="Google Cloud Vertex AI Model Registry",
|
|
314
|
+
plugin_type=PluginType.CUSTOM, # MODEL_REGISTRY type
|
|
315
|
+
packages=["google-cloud-aiplatform>=1.25"],
|
|
316
|
+
wrapper_path="flowyml.plugins.model_registries.vertex:VertexModelRegistry",
|
|
317
|
+
documentation_url="https://cloud.google.com/vertex-ai/docs/model-registry",
|
|
318
|
+
tags=["model-registry", "gcp", "cloud", "vertex-ai"],
|
|
319
|
+
),
|
|
320
|
+
"sagemaker_model_registry": PluginInfo(
|
|
321
|
+
name="sagemaker_model_registry",
|
|
322
|
+
description="AWS SageMaker Model Registry",
|
|
323
|
+
plugin_type=PluginType.CUSTOM, # MODEL_REGISTRY type
|
|
324
|
+
packages=["boto3>=1.28", "sagemaker>=2.100"],
|
|
325
|
+
wrapper_path="flowyml.plugins.model_registries.sagemaker:SageMakerModelRegistry",
|
|
326
|
+
documentation_url="https://docs.aws.amazon.com/sagemaker/latest/dg/model-registry.html",
|
|
327
|
+
tags=["model-registry", "aws", "cloud", "sagemaker"],
|
|
328
|
+
),
|
|
329
|
+
# -------------------------------------------------------------------------
|
|
330
|
+
# MODEL DEPLOYERS
|
|
331
|
+
# -------------------------------------------------------------------------
|
|
332
|
+
"vertex_endpoint": PluginInfo(
|
|
333
|
+
name="vertex_endpoint",
|
|
334
|
+
description="Google Cloud Vertex AI Endpoint Deployer",
|
|
335
|
+
plugin_type=PluginType.CUSTOM, # MODEL_DEPLOYER type
|
|
336
|
+
packages=["google-cloud-aiplatform>=1.25"],
|
|
337
|
+
wrapper_path="flowyml.plugins.deployers.vertex:VertexEndpointDeployer",
|
|
338
|
+
documentation_url="https://cloud.google.com/vertex-ai/docs/predictions",
|
|
339
|
+
tags=["model-deployer", "gcp", "cloud", "vertex-ai", "inference"],
|
|
340
|
+
),
|
|
341
|
+
"sagemaker_endpoint": PluginInfo(
|
|
342
|
+
name="sagemaker_endpoint",
|
|
343
|
+
description="AWS SageMaker Endpoint Deployer",
|
|
344
|
+
plugin_type=PluginType.CUSTOM, # MODEL_DEPLOYER type
|
|
345
|
+
packages=["boto3>=1.28"],
|
|
346
|
+
wrapper_path="flowyml.plugins.deployers.sagemaker:SageMakerEndpointDeployer",
|
|
347
|
+
documentation_url="https://docs.aws.amazon.com/sagemaker/latest/dg/deploy-model.html",
|
|
348
|
+
tags=["model-deployer", "aws", "cloud", "sagemaker", "inference"],
|
|
349
|
+
),
|
|
350
|
+
"gcp_cloud_run": PluginInfo(
|
|
351
|
+
name="gcp_cloud_run",
|
|
352
|
+
description="Google Cloud Run Deployer",
|
|
353
|
+
plugin_type=PluginType.CUSTOM, # MODEL_DEPLOYER type
|
|
354
|
+
packages=["google-cloud-run>=0.10.0"],
|
|
355
|
+
wrapper_path="flowyml.plugins.deployers.gcp_cloud_run:GCPCloudRunDeployer",
|
|
356
|
+
documentation_url="https://cloud.google.com/run/docs",
|
|
357
|
+
tags=["model-deployer", "gcp", "serverless", "container"],
|
|
358
|
+
),
|
|
359
|
+
"mlflow_registry": PluginInfo(
|
|
360
|
+
name="mlflow_registry",
|
|
361
|
+
description="MLflow Model Registry",
|
|
362
|
+
plugin_type=PluginType.CUSTOM, # MODEL_REGISTRY type
|
|
363
|
+
packages=["mlflow>=2.0"],
|
|
364
|
+
wrapper_path="flowyml.plugins.model_registries.mlflow:MLflowModelRegistry",
|
|
365
|
+
documentation_url="https://mlflow.org/docs/latest/model-registry.html",
|
|
366
|
+
tags=["model-registry", "mlflow", "versioning"],
|
|
367
|
+
),
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
# ============================================================================
|
|
372
|
+
# REGISTRY FUNCTIONS
|
|
373
|
+
# ============================================================================
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
def get_plugin_info(name: str) -> PluginInfo | None:
|
|
377
|
+
"""Get information about a plugin by name.
|
|
378
|
+
|
|
379
|
+
Args:
|
|
380
|
+
name: Plugin name.
|
|
381
|
+
|
|
382
|
+
Returns:
|
|
383
|
+
PluginInfo if found, None otherwise.
|
|
384
|
+
"""
|
|
385
|
+
return PLUGIN_CATALOG.get(name)
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
def list_plugins(
|
|
389
|
+
plugin_type: PluginType = None,
|
|
390
|
+
tag: str = None,
|
|
391
|
+
status: PluginStatus = None,
|
|
392
|
+
) -> list[PluginInfo]:
|
|
393
|
+
"""List plugins with optional filtering.
|
|
394
|
+
|
|
395
|
+
Args:
|
|
396
|
+
plugin_type: Filter by plugin type.
|
|
397
|
+
tag: Filter by tag.
|
|
398
|
+
status: Filter by status.
|
|
399
|
+
|
|
400
|
+
Returns:
|
|
401
|
+
List of matching PluginInfo objects.
|
|
402
|
+
"""
|
|
403
|
+
results = list(PLUGIN_CATALOG.values())
|
|
404
|
+
|
|
405
|
+
if plugin_type:
|
|
406
|
+
results = [p for p in results if p.plugin_type == plugin_type]
|
|
407
|
+
|
|
408
|
+
if tag:
|
|
409
|
+
results = [p for p in results if tag in p.tags]
|
|
410
|
+
|
|
411
|
+
if status:
|
|
412
|
+
results = [p for p in results if p.status == status]
|
|
413
|
+
|
|
414
|
+
return results
|
|
415
|
+
|
|
416
|
+
|
|
417
|
+
def list_plugin_names(plugin_type: PluginType = None) -> list[str]:
|
|
418
|
+
"""List plugin names with optional type filtering.
|
|
419
|
+
|
|
420
|
+
Args:
|
|
421
|
+
plugin_type: Optional filter by plugin type.
|
|
422
|
+
|
|
423
|
+
Returns:
|
|
424
|
+
List of plugin names.
|
|
425
|
+
"""
|
|
426
|
+
if plugin_type:
|
|
427
|
+
return [name for name, info in PLUGIN_CATALOG.items() if info.plugin_type == plugin_type]
|
|
428
|
+
return list(PLUGIN_CATALOG.keys())
|
|
429
|
+
|
|
430
|
+
|
|
431
|
+
def register_plugin(info: PluginInfo) -> None:
|
|
432
|
+
"""Register a new plugin in the catalog.
|
|
433
|
+
|
|
434
|
+
This allows community plugins to register themselves.
|
|
435
|
+
|
|
436
|
+
Args:
|
|
437
|
+
info: PluginInfo for the new plugin.
|
|
438
|
+
"""
|
|
439
|
+
PLUGIN_CATALOG[info.name] = info
|
|
440
|
+
|
|
441
|
+
|
|
442
|
+
def unregister_plugin(name: str) -> bool:
|
|
443
|
+
"""Unregister a plugin from the catalog.
|
|
444
|
+
|
|
445
|
+
Args:
|
|
446
|
+
name: Plugin name to remove.
|
|
447
|
+
|
|
448
|
+
Returns:
|
|
449
|
+
True if plugin was removed.
|
|
450
|
+
"""
|
|
451
|
+
if name in PLUGIN_CATALOG:
|
|
452
|
+
del PLUGIN_CATALOG[name]
|
|
453
|
+
return True
|
|
454
|
+
return False
|