flowyml 1.7.2__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 (126) hide show
  1. flowyml/assets/base.py +15 -0
  2. flowyml/assets/metrics.py +5 -0
  3. flowyml/cli/main.py +709 -0
  4. flowyml/cli/stack_cli.py +138 -25
  5. flowyml/core/__init__.py +17 -0
  6. flowyml/core/executor.py +161 -26
  7. flowyml/core/image_builder.py +129 -0
  8. flowyml/core/log_streamer.py +227 -0
  9. flowyml/core/orchestrator.py +22 -2
  10. flowyml/core/pipeline.py +34 -10
  11. flowyml/core/routing.py +558 -0
  12. flowyml/core/step.py +9 -1
  13. flowyml/core/step_grouping.py +49 -35
  14. flowyml/core/types.py +407 -0
  15. flowyml/monitoring/alerts.py +10 -0
  16. flowyml/monitoring/notifications.py +104 -25
  17. flowyml/monitoring/slack_blocks.py +323 -0
  18. flowyml/plugins/__init__.py +251 -0
  19. flowyml/plugins/alerters/__init__.py +1 -0
  20. flowyml/plugins/alerters/slack.py +168 -0
  21. flowyml/plugins/base.py +752 -0
  22. flowyml/plugins/config.py +478 -0
  23. flowyml/plugins/deployers/__init__.py +22 -0
  24. flowyml/plugins/deployers/gcp_cloud_run.py +200 -0
  25. flowyml/plugins/deployers/sagemaker.py +306 -0
  26. flowyml/plugins/deployers/vertex.py +290 -0
  27. flowyml/plugins/integration.py +369 -0
  28. flowyml/plugins/manager.py +510 -0
  29. flowyml/plugins/model_registries/__init__.py +22 -0
  30. flowyml/plugins/model_registries/mlflow.py +159 -0
  31. flowyml/plugins/model_registries/sagemaker.py +489 -0
  32. flowyml/plugins/model_registries/vertex.py +386 -0
  33. flowyml/plugins/orchestrators/__init__.py +13 -0
  34. flowyml/plugins/orchestrators/sagemaker.py +443 -0
  35. flowyml/plugins/orchestrators/vertex_ai.py +461 -0
  36. flowyml/plugins/registries/__init__.py +13 -0
  37. flowyml/plugins/registries/ecr.py +321 -0
  38. flowyml/plugins/registries/gcr.py +313 -0
  39. flowyml/plugins/registry.py +454 -0
  40. flowyml/plugins/stack.py +494 -0
  41. flowyml/plugins/stack_config.py +537 -0
  42. flowyml/plugins/stores/__init__.py +13 -0
  43. flowyml/plugins/stores/gcs.py +460 -0
  44. flowyml/plugins/stores/s3.py +453 -0
  45. flowyml/plugins/trackers/__init__.py +11 -0
  46. flowyml/plugins/trackers/mlflow.py +316 -0
  47. flowyml/plugins/validators/__init__.py +3 -0
  48. flowyml/plugins/validators/deepchecks.py +119 -0
  49. flowyml/registry/__init__.py +2 -1
  50. flowyml/registry/model_environment.py +109 -0
  51. flowyml/registry/model_registry.py +241 -96
  52. flowyml/serving/__init__.py +17 -0
  53. flowyml/serving/model_server.py +628 -0
  54. flowyml/stacks/__init__.py +60 -0
  55. flowyml/stacks/aws.py +93 -0
  56. flowyml/stacks/base.py +62 -0
  57. flowyml/stacks/components.py +12 -0
  58. flowyml/stacks/gcp.py +44 -9
  59. flowyml/stacks/plugins.py +115 -0
  60. flowyml/stacks/registry.py +2 -1
  61. flowyml/storage/sql.py +401 -12
  62. flowyml/tracking/experiment.py +8 -5
  63. flowyml/ui/backend/Dockerfile +87 -16
  64. flowyml/ui/backend/auth.py +12 -2
  65. flowyml/ui/backend/main.py +149 -5
  66. flowyml/ui/backend/routers/ai_context.py +226 -0
  67. flowyml/ui/backend/routers/assets.py +23 -4
  68. flowyml/ui/backend/routers/auth.py +96 -0
  69. flowyml/ui/backend/routers/deployments.py +660 -0
  70. flowyml/ui/backend/routers/model_explorer.py +597 -0
  71. flowyml/ui/backend/routers/plugins.py +103 -51
  72. flowyml/ui/backend/routers/projects.py +91 -8
  73. flowyml/ui/backend/routers/runs.py +20 -1
  74. flowyml/ui/backend/routers/schedules.py +22 -17
  75. flowyml/ui/backend/routers/templates.py +319 -0
  76. flowyml/ui/backend/routers/websocket.py +2 -2
  77. flowyml/ui/frontend/Dockerfile +55 -6
  78. flowyml/ui/frontend/dist/assets/index-B5AsPTSz.css +1 -0
  79. flowyml/ui/frontend/dist/assets/index-dFbZ8wD8.js +753 -0
  80. flowyml/ui/frontend/dist/index.html +2 -2
  81. flowyml/ui/frontend/dist/logo.png +0 -0
  82. flowyml/ui/frontend/nginx.conf +65 -4
  83. flowyml/ui/frontend/package-lock.json +1404 -74
  84. flowyml/ui/frontend/package.json +3 -0
  85. flowyml/ui/frontend/public/logo.png +0 -0
  86. flowyml/ui/frontend/src/App.jsx +10 -7
  87. flowyml/ui/frontend/src/app/auth/Login.jsx +90 -0
  88. flowyml/ui/frontend/src/app/dashboard/page.jsx +8 -8
  89. flowyml/ui/frontend/src/app/deployments/page.jsx +786 -0
  90. flowyml/ui/frontend/src/app/model-explorer/page.jsx +1031 -0
  91. flowyml/ui/frontend/src/app/pipelines/page.jsx +12 -2
  92. flowyml/ui/frontend/src/app/projects/[projectId]/_components/ProjectExperimentsList.jsx +19 -6
  93. flowyml/ui/frontend/src/app/runs/[runId]/page.jsx +36 -24
  94. flowyml/ui/frontend/src/app/runs/page.jsx +8 -2
  95. flowyml/ui/frontend/src/app/settings/page.jsx +267 -253
  96. flowyml/ui/frontend/src/components/AssetDetailsPanel.jsx +29 -7
  97. flowyml/ui/frontend/src/components/Layout.jsx +6 -0
  98. flowyml/ui/frontend/src/components/PipelineGraph.jsx +79 -29
  99. flowyml/ui/frontend/src/components/RunDetailsPanel.jsx +36 -6
  100. flowyml/ui/frontend/src/components/RunMetaPanel.jsx +113 -0
  101. flowyml/ui/frontend/src/components/ai/AIAssistantButton.jsx +71 -0
  102. flowyml/ui/frontend/src/components/ai/AIAssistantPanel.jsx +420 -0
  103. flowyml/ui/frontend/src/components/header/Header.jsx +22 -0
  104. flowyml/ui/frontend/src/components/plugins/PluginManager.jsx +4 -4
  105. flowyml/ui/frontend/src/components/plugins/{ZenMLIntegration.jsx → StackImport.jsx} +38 -12
  106. flowyml/ui/frontend/src/components/sidebar/Sidebar.jsx +36 -13
  107. flowyml/ui/frontend/src/contexts/AIAssistantContext.jsx +245 -0
  108. flowyml/ui/frontend/src/contexts/AuthContext.jsx +108 -0
  109. flowyml/ui/frontend/src/hooks/useAIContext.js +156 -0
  110. flowyml/ui/frontend/src/hooks/useWebGPU.js +54 -0
  111. flowyml/ui/frontend/src/layouts/MainLayout.jsx +6 -0
  112. flowyml/ui/frontend/src/router/index.jsx +47 -20
  113. flowyml/ui/frontend/src/services/pluginService.js +3 -1
  114. flowyml/ui/server_manager.py +5 -5
  115. flowyml/ui/utils.py +157 -39
  116. flowyml/utils/config.py +37 -15
  117. flowyml/utils/model_introspection.py +123 -0
  118. flowyml/utils/observability.py +30 -0
  119. flowyml-1.8.0.dist-info/METADATA +174 -0
  120. {flowyml-1.7.2.dist-info → flowyml-1.8.0.dist-info}/RECORD +123 -65
  121. {flowyml-1.7.2.dist-info → flowyml-1.8.0.dist-info}/WHEEL +1 -1
  122. flowyml/ui/frontend/dist/assets/index-B40RsQDq.css +0 -1
  123. flowyml/ui/frontend/dist/assets/index-CjI0zKCn.js +0 -685
  124. flowyml-1.7.2.dist-info/METADATA +0 -477
  125. {flowyml-1.7.2.dist-info → flowyml-1.8.0.dist-info}/entry_points.txt +0 -0
  126. {flowyml-1.7.2.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