zenml-nightly 0.68.0.dev20241027__py3-none-any.whl → 0.68.1.dev20241101__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 (125) hide show
  1. README.md +17 -11
  2. RELEASE_NOTES.md +9 -0
  3. zenml/VERSION +1 -1
  4. zenml/__init__.py +1 -1
  5. zenml/analytics/context.py +16 -1
  6. zenml/analytics/utils.py +18 -7
  7. zenml/artifacts/utils.py +40 -216
  8. zenml/cli/__init__.py +63 -90
  9. zenml/cli/base.py +3 -3
  10. zenml/cli/login.py +951 -0
  11. zenml/cli/server.py +462 -353
  12. zenml/cli/service_accounts.py +4 -4
  13. zenml/cli/stack.py +77 -2
  14. zenml/cli/stack_components.py +5 -16
  15. zenml/cli/user_management.py +0 -12
  16. zenml/cli/utils.py +24 -77
  17. zenml/client.py +46 -14
  18. zenml/config/compiler.py +1 -0
  19. zenml/config/global_config.py +9 -0
  20. zenml/config/pipeline_configurations.py +2 -1
  21. zenml/config/pipeline_run_configuration.py +2 -1
  22. zenml/constants.py +3 -9
  23. zenml/enums.py +1 -1
  24. zenml/exceptions.py +11 -0
  25. zenml/integrations/github/code_repositories/github_code_repository.py +1 -1
  26. zenml/login/__init__.py +16 -0
  27. zenml/login/credentials.py +346 -0
  28. zenml/login/credentials_store.py +603 -0
  29. zenml/login/pro/__init__.py +16 -0
  30. zenml/login/pro/client.py +496 -0
  31. zenml/login/pro/constants.py +34 -0
  32. zenml/login/pro/models.py +25 -0
  33. zenml/login/pro/organization/__init__.py +14 -0
  34. zenml/login/pro/organization/client.py +79 -0
  35. zenml/login/pro/organization/models.py +32 -0
  36. zenml/login/pro/tenant/__init__.py +14 -0
  37. zenml/login/pro/tenant/client.py +92 -0
  38. zenml/login/pro/tenant/models.py +174 -0
  39. zenml/login/pro/utils.py +121 -0
  40. zenml/{cli → login}/web_login.py +64 -28
  41. zenml/materializers/base_materializer.py +43 -9
  42. zenml/materializers/built_in_materializer.py +1 -1
  43. zenml/metadata/metadata_types.py +49 -0
  44. zenml/model/model.py +0 -38
  45. zenml/models/__init__.py +3 -0
  46. zenml/models/v2/base/base.py +12 -8
  47. zenml/models/v2/base/filter.py +9 -0
  48. zenml/models/v2/core/artifact_version.py +49 -10
  49. zenml/models/v2/core/component.py +54 -19
  50. zenml/models/v2/core/flavor.py +13 -13
  51. zenml/models/v2/core/model.py +3 -1
  52. zenml/models/v2/core/model_version.py +3 -5
  53. zenml/models/v2/core/model_version_artifact.py +3 -1
  54. zenml/models/v2/core/model_version_pipeline_run.py +3 -1
  55. zenml/models/v2/core/pipeline.py +3 -1
  56. zenml/models/v2/core/pipeline_run.py +23 -1
  57. zenml/models/v2/core/run_template.py +3 -1
  58. zenml/models/v2/core/stack.py +7 -3
  59. zenml/models/v2/core/step_run.py +43 -2
  60. zenml/models/v2/misc/auth_models.py +11 -2
  61. zenml/models/v2/misc/server_models.py +2 -0
  62. zenml/orchestrators/base_orchestrator.py +8 -4
  63. zenml/orchestrators/step_launcher.py +1 -0
  64. zenml/orchestrators/step_run_utils.py +10 -2
  65. zenml/orchestrators/step_runner.py +67 -55
  66. zenml/orchestrators/utils.py +45 -22
  67. zenml/pipelines/pipeline_decorator.py +5 -0
  68. zenml/pipelines/pipeline_definition.py +206 -160
  69. zenml/pipelines/run_utils.py +11 -10
  70. zenml/services/local/local_daemon_entrypoint.py +4 -4
  71. zenml/services/service.py +2 -2
  72. zenml/stack/stack.py +2 -6
  73. zenml/stack/stack_component.py +2 -7
  74. zenml/stack/utils.py +26 -14
  75. zenml/steps/base_step.py +8 -2
  76. zenml/steps/step_context.py +0 -3
  77. zenml/steps/step_invocation.py +14 -5
  78. zenml/steps/utils.py +1 -0
  79. zenml/utils/materializer_utils.py +1 -1
  80. zenml/utils/requirements_utils.py +71 -0
  81. zenml/utils/singleton.py +15 -3
  82. zenml/utils/source_utils.py +39 -2
  83. zenml/utils/visualization_utils.py +1 -1
  84. zenml/zen_server/auth.py +44 -39
  85. zenml/zen_server/deploy/__init__.py +7 -7
  86. zenml/zen_server/deploy/base_provider.py +46 -73
  87. zenml/zen_server/deploy/{local → daemon}/__init__.py +3 -3
  88. zenml/zen_server/deploy/{local/local_provider.py → daemon/daemon_provider.py} +44 -63
  89. zenml/zen_server/deploy/{local/local_zen_server.py → daemon/daemon_zen_server.py} +50 -22
  90. zenml/zen_server/deploy/deployer.py +90 -171
  91. zenml/zen_server/deploy/deployment.py +20 -12
  92. zenml/zen_server/deploy/docker/docker_provider.py +9 -28
  93. zenml/zen_server/deploy/docker/docker_zen_server.py +19 -3
  94. zenml/zen_server/deploy/helm/Chart.yaml +1 -1
  95. zenml/zen_server/deploy/helm/README.md +2 -2
  96. zenml/zen_server/exceptions.py +11 -0
  97. zenml/zen_server/jwt.py +9 -9
  98. zenml/zen_server/routers/auth_endpoints.py +30 -8
  99. zenml/zen_server/routers/stack_components_endpoints.py +1 -1
  100. zenml/zen_server/routers/workspaces_endpoints.py +1 -1
  101. zenml/zen_server/template_execution/runner_entrypoint_configuration.py +7 -4
  102. zenml/zen_server/template_execution/utils.py +6 -61
  103. zenml/zen_server/utils.py +64 -36
  104. zenml/zen_stores/base_zen_store.py +4 -49
  105. zenml/zen_stores/migrations/versions/0.68.1_release.py +23 -0
  106. zenml/zen_stores/migrations/versions/c22561cbb3a9_add_artifact_unique_constraints.py +86 -0
  107. zenml/zen_stores/rest_zen_store.py +325 -147
  108. zenml/zen_stores/schemas/api_key_schemas.py +9 -4
  109. zenml/zen_stores/schemas/artifact_schemas.py +21 -2
  110. zenml/zen_stores/schemas/artifact_visualization_schemas.py +1 -1
  111. zenml/zen_stores/schemas/component_schemas.py +49 -6
  112. zenml/zen_stores/schemas/device_schemas.py +9 -4
  113. zenml/zen_stores/schemas/flavor_schemas.py +1 -1
  114. zenml/zen_stores/schemas/model_schemas.py +1 -1
  115. zenml/zen_stores/schemas/service_schemas.py +1 -1
  116. zenml/zen_stores/schemas/step_run_schemas.py +1 -1
  117. zenml/zen_stores/schemas/trigger_schemas.py +1 -1
  118. zenml/zen_stores/sql_zen_store.py +393 -140
  119. zenml/zen_stores/template_utils.py +3 -1
  120. {zenml_nightly-0.68.0.dev20241027.dist-info → zenml_nightly-0.68.1.dev20241101.dist-info}/METADATA +18 -12
  121. {zenml_nightly-0.68.0.dev20241027.dist-info → zenml_nightly-0.68.1.dev20241101.dist-info}/RECORD +124 -107
  122. zenml/api.py +0 -60
  123. {zenml_nightly-0.68.0.dev20241027.dist-info → zenml_nightly-0.68.1.dev20241101.dist-info}/LICENSE +0 -0
  124. {zenml_nightly-0.68.0.dev20241027.dist-info → zenml_nightly-0.68.1.dev20241101.dist-info}/WHEEL +0 -0
  125. {zenml_nightly-0.68.0.dev20241027.dist-info → zenml_nightly-0.68.1.dev20241101.dist-info}/entry_points.txt +0 -0
@@ -20,6 +20,7 @@ import math
20
20
  import os
21
21
  import re
22
22
  import sys
23
+ import time
23
24
  from datetime import datetime, timezone
24
25
  from functools import lru_cache
25
26
  from pathlib import Path
@@ -93,9 +94,9 @@ from zenml.constants import (
93
94
  ENV_ZENML_DEFAULT_USER_NAME,
94
95
  ENV_ZENML_DEFAULT_USER_PASSWORD,
95
96
  ENV_ZENML_DISABLE_DATABASE_MIGRATION,
96
- ENV_ZENML_LOCAL_SERVER,
97
97
  ENV_ZENML_SERVER,
98
98
  FINISHED_ONBOARDING_SURVEY_KEY,
99
+ MAX_RETRIES_FOR_VERSIONED_ENTITY_CREATION,
99
100
  SORT_PIPELINES_BY_LATEST_RUN_KEY,
100
101
  SQL_STORE_BACKUP_DIRECTORY_NAME,
101
102
  TEXT_FIELD_MAX_LENGTH,
@@ -108,6 +109,7 @@ from zenml.enums import (
108
109
  DatabaseBackupStrategy,
109
110
  ExecutionStatus,
110
111
  LoggingLevels,
112
+ MetadataResourceTypes,
111
113
  ModelStages,
112
114
  OnboardingStep,
113
115
  SecretScope,
@@ -134,6 +136,7 @@ from zenml.exceptions import (
134
136
  )
135
137
  from zenml.io import fileio
136
138
  from zenml.logger import get_console_handler, get_logger, get_logging_level
139
+ from zenml.metadata.metadata_types import get_metadata_type
137
140
  from zenml.models import (
138
141
  ActionFilter,
139
142
  ActionRequest,
@@ -1585,10 +1588,10 @@ class SqlZenStore(BaseZenStore):
1585
1588
  # Fetch the deployment ID from the database and use it to replace
1586
1589
  # the one fetched from the global configuration
1587
1590
  model.id = settings.server_id
1591
+ model.name = settings.server_name
1588
1592
  model.active = settings.active
1589
1593
  model.last_user_activity = settings.last_user_activity
1590
- if not handle_bool_env_var(ENV_ZENML_LOCAL_SERVER):
1591
- model.analytics_enabled = settings.enable_analytics
1594
+ model.analytics_enabled = settings.enable_analytics
1592
1595
  return model
1593
1596
 
1594
1597
  def get_deployment_id(self) -> UUID:
@@ -1646,7 +1649,9 @@ class SqlZenStore(BaseZenStore):
1646
1649
  """
1647
1650
  with Session(self.engine) as session:
1648
1651
  settings = self._get_server_settings(session=session)
1649
- return settings.to_model(include_metadata=hydrate)
1652
+ return settings.to_model(
1653
+ include_metadata=hydrate, include_resources=True
1654
+ )
1650
1655
 
1651
1656
  def update_server_settings(
1652
1657
  self, settings_update: ServerSettingsUpdate
@@ -1687,7 +1692,9 @@ class SqlZenStore(BaseZenStore):
1687
1692
  session.commit()
1688
1693
  session.refresh(settings)
1689
1694
 
1690
- return settings.to_model(include_metadata=True)
1695
+ return settings.to_model(
1696
+ include_metadata=True, include_resources=True
1697
+ )
1691
1698
 
1692
1699
  def _update_last_user_activity_timestamp(
1693
1700
  self, last_user_activity: datetime
@@ -2126,7 +2133,9 @@ class SqlZenStore(BaseZenStore):
2126
2133
  session.add(new_api_key)
2127
2134
  session.commit()
2128
2135
 
2129
- api_key_model = new_api_key.to_model(include_metadata=True)
2136
+ api_key_model = new_api_key.to_model(
2137
+ include_metadata=True, include_resources=True
2138
+ )
2130
2139
  api_key_model.set_key(key_value)
2131
2140
  return api_key_model
2132
2141
 
@@ -2154,7 +2163,9 @@ class SqlZenStore(BaseZenStore):
2154
2163
  api_key_name_or_id=api_key_name_or_id,
2155
2164
  session=session,
2156
2165
  )
2157
- return api_key.to_model(include_metadata=hydrate)
2166
+ return api_key.to_model(
2167
+ include_metadata=hydrate, include_resources=True
2168
+ )
2158
2169
 
2159
2170
  def get_internal_api_key(
2160
2171
  self, api_key_id: UUID, hydrate: bool = True
@@ -2178,7 +2189,9 @@ class SqlZenStore(BaseZenStore):
2178
2189
  ).first()
2179
2190
  if api_key is None:
2180
2191
  raise KeyError(f"API key with ID {api_key_id} not found.")
2181
- return api_key.to_internal_model(hydrate=hydrate)
2192
+ return api_key.to_internal_model(
2193
+ include_metadata=hydrate, include_resources=True
2194
+ )
2182
2195
 
2183
2196
  def list_api_keys(
2184
2197
  self,
@@ -2268,7 +2281,9 @@ class SqlZenStore(BaseZenStore):
2268
2281
 
2269
2282
  # Refresh the Model that was just created
2270
2283
  session.refresh(api_key)
2271
- return api_key.to_model(include_metadata=True)
2284
+ return api_key.to_model(
2285
+ include_metadata=True, include_resources=True
2286
+ )
2272
2287
 
2273
2288
  def update_internal_api_key(
2274
2289
  self, api_key_id: UUID, api_key_update: APIKeyInternalUpdate
@@ -2299,7 +2314,9 @@ class SqlZenStore(BaseZenStore):
2299
2314
 
2300
2315
  # Refresh the Model that was just created
2301
2316
  session.refresh(api_key)
2302
- return api_key.to_model(include_metadata=True)
2317
+ return api_key.to_model(
2318
+ include_metadata=True, include_resources=True
2319
+ )
2303
2320
 
2304
2321
  def rotate_api_key(
2305
2322
  self,
@@ -2567,7 +2584,9 @@ class SqlZenStore(BaseZenStore):
2567
2584
 
2568
2585
  session.add(artifact_schema)
2569
2586
  session.commit()
2570
- return artifact_schema.to_model(include_metadata=True)
2587
+ return artifact_schema.to_model(
2588
+ include_metadata=True, include_resources=True
2589
+ )
2571
2590
 
2572
2591
  def get_artifact(
2573
2592
  self, artifact_id: UUID, hydrate: bool = True
@@ -2594,7 +2613,9 @@ class SqlZenStore(BaseZenStore):
2594
2613
  f"Unable to get artifact with ID {artifact_id}: No "
2595
2614
  "artifact with this ID found."
2596
2615
  )
2597
- return artifact.to_model(include_metadata=hydrate)
2616
+ return artifact.to_model(
2617
+ include_metadata=hydrate, include_resources=True
2618
+ )
2598
2619
 
2599
2620
  def list_artifacts(
2600
2621
  self, filter_model: ArtifactFilter, hydrate: bool = False
@@ -2661,7 +2682,9 @@ class SqlZenStore(BaseZenStore):
2661
2682
  session.add(existing_artifact)
2662
2683
  session.commit()
2663
2684
  session.refresh(existing_artifact)
2664
- return existing_artifact.to_model(include_metadata=True)
2685
+ return existing_artifact.to_model(
2686
+ include_metadata=True, include_resources=True
2687
+ )
2665
2688
 
2666
2689
  def delete_artifact(self, artifact_id: UUID) -> None:
2667
2690
  """Deletes an artifact.
@@ -2683,79 +2706,214 @@ class SqlZenStore(BaseZenStore):
2683
2706
 
2684
2707
  # -------------------- Artifact Versions --------------------
2685
2708
 
2709
+ def _get_or_create_artifact_for_name(
2710
+ self, name: str, has_custom_name: bool
2711
+ ) -> ArtifactSchema:
2712
+ """Get or create an artifact with a specific name.
2713
+
2714
+ Args:
2715
+ name: The artifact name.
2716
+ has_custom_name: Whether the artifact has a custom name.
2717
+
2718
+ Returns:
2719
+ Schema of the artifact.
2720
+ """
2721
+ with Session(self.engine) as session:
2722
+ artifact_query = select(ArtifactSchema).where(
2723
+ ArtifactSchema.name == name
2724
+ )
2725
+ artifact = session.exec(artifact_query).first()
2726
+
2727
+ if artifact is None:
2728
+ try:
2729
+ with session.begin_nested():
2730
+ artifact_request = ArtifactRequest(
2731
+ name=name, has_custom_name=has_custom_name
2732
+ )
2733
+ artifact = ArtifactSchema.from_request(
2734
+ artifact_request
2735
+ )
2736
+ session.add(artifact)
2737
+ session.commit()
2738
+ session.refresh(artifact)
2739
+ except IntegrityError:
2740
+ # We failed to create the artifact due to the unique constraint
2741
+ # for artifact names -> The artifact was already created, we can
2742
+ # just fetch it from the DB now
2743
+ artifact = session.exec(artifact_query).one()
2744
+
2745
+ if artifact.has_custom_name is False and has_custom_name:
2746
+ # If a new version with custom name was created for an artifact
2747
+ # that previously had no custom name, we update it.
2748
+ artifact.has_custom_name = True
2749
+ session.commit()
2750
+ session.refresh(artifact)
2751
+
2752
+ return artifact
2753
+
2754
+ def _get_next_numeric_version_for_artifact(
2755
+ self, session: Session, artifact_id: UUID
2756
+ ) -> int:
2757
+ """Get the next numeric version for an artifact.
2758
+
2759
+ Args:
2760
+ session: DB session.
2761
+ artifact_id: ID of the artifact for which to get the next numeric
2762
+ version.
2763
+
2764
+ Returns:
2765
+ The next numeric version.
2766
+ """
2767
+ current_max_version = session.exec(
2768
+ select(func.max(ArtifactVersionSchema.version_number)).where(
2769
+ ArtifactVersionSchema.artifact_id == artifact_id
2770
+ )
2771
+ ).first()
2772
+
2773
+ if current_max_version is None:
2774
+ return 1
2775
+ else:
2776
+ return int(current_max_version) + 1
2777
+
2686
2778
  def create_artifact_version(
2687
2779
  self, artifact_version: ArtifactVersionRequest
2688
2780
  ) -> ArtifactVersionResponse:
2689
- """Creates an artifact version.
2781
+ """Create an artifact version.
2690
2782
 
2691
2783
  Args:
2692
2784
  artifact_version: The artifact version to create.
2693
2785
 
2786
+ Raises:
2787
+ EntityExistsError: If the artifact version already exists.
2788
+
2694
2789
  Returns:
2695
2790
  The created artifact version.
2696
-
2697
- Raises:
2698
- EntityExistsError: if an artifact with the same name and version
2699
- already exists.
2700
2791
  """
2701
- with Session(self.engine) as session:
2702
- # Check if an artifact with the given name and version exists
2703
- def _check(tolerance: int = 0) -> None:
2704
- query = session.exec(
2705
- select(ArtifactVersionSchema)
2706
- .where(
2707
- ArtifactVersionSchema.artifact_id
2708
- == artifact_version.artifact_id
2709
- )
2710
- .where(
2711
- ArtifactVersionSchema.version
2712
- == artifact_version.version
2792
+ if artifact_name := artifact_version.artifact_name:
2793
+ artifact_schema = self._get_or_create_artifact_for_name(
2794
+ name=artifact_name,
2795
+ has_custom_name=artifact_version.has_custom_name,
2796
+ )
2797
+ artifact_version.artifact_id = artifact_schema.id
2798
+
2799
+ assert artifact_version.artifact_id
2800
+
2801
+ artifact_version_id = None
2802
+
2803
+ if artifact_version.version is None:
2804
+ # No explicit version in the request -> We will try to
2805
+ # auto-increment the numeric version of the artifact version
2806
+ remaining_tries = MAX_RETRIES_FOR_VERSIONED_ENTITY_CREATION
2807
+ while remaining_tries > 0:
2808
+ remaining_tries -= 1
2809
+ try:
2810
+ with Session(self.engine) as session:
2811
+ artifact_version.version = str(
2812
+ self._get_next_numeric_version_for_artifact(
2813
+ session=session,
2814
+ artifact_id=artifact_version.artifact_id,
2815
+ )
2816
+ )
2817
+
2818
+ artifact_version_schema = (
2819
+ ArtifactVersionSchema.from_request(
2820
+ artifact_version
2821
+ )
2822
+ )
2823
+ session.add(artifact_version_schema)
2824
+ session.commit()
2825
+ artifact_version_id = artifact_version_schema.id
2826
+ except IntegrityError:
2827
+ if remaining_tries == 0:
2828
+ raise EntityExistsError(
2829
+ f"Failed to create version for artifact "
2830
+ f"{artifact_schema.name}. This is most likely "
2831
+ "caused by multiple parallel requests that try "
2832
+ "to create versions for this artifact in the "
2833
+ "database."
2834
+ )
2835
+ else:
2836
+ # Exponential backoff to account for heavy
2837
+ # parallelization
2838
+ sleep_duration = 0.05 * 1.5 ** (
2839
+ MAX_RETRIES_FOR_VERSIONED_ENTITY_CREATION
2840
+ - remaining_tries
2841
+ )
2842
+ logger.debug(
2843
+ "Failed to create artifact version %s "
2844
+ "(version %s) due to an integrity error. "
2845
+ "Retrying in %f seconds.",
2846
+ artifact_schema.name,
2847
+ artifact_version.version,
2848
+ sleep_duration,
2849
+ )
2850
+ time.sleep(sleep_duration)
2851
+ else:
2852
+ break
2853
+ else:
2854
+ # An explicit version was specified for the artifact version.
2855
+ # We don't do any incrementing and fail immediately if the
2856
+ # version already exists.
2857
+ with Session(self.engine) as session:
2858
+ try:
2859
+ artifact_version_schema = (
2860
+ ArtifactVersionSchema.from_request(artifact_version)
2713
2861
  )
2714
- )
2715
- existing_artifact = query.fetchmany(tolerance + 1)
2716
- if (
2717
- existing_artifact is not None
2718
- and len(existing_artifact) > tolerance
2719
- ):
2862
+ session.add(artifact_version_schema)
2863
+ session.commit()
2864
+ artifact_version_id = artifact_version_schema.id
2865
+ except IntegrityError:
2720
2866
  raise EntityExistsError(
2721
- f"Unable to create artifact with name "
2722
- f"'{existing_artifact[0].artifact.name}' and version "
2723
- f"'{artifact_version.version}': An artifact with the same "
2724
- "name and version already exists."
2867
+ f"Unable to create artifact version "
2868
+ f"{artifact_schema.name} (version "
2869
+ f"{artifact_version.version}): An artifact with the "
2870
+ "same name and version already exists."
2725
2871
  )
2726
2872
 
2727
- _check()
2728
- # Create the artifact version.
2729
- artifact_version_schema = ArtifactVersionSchema.from_request(
2730
- artifact_version
2731
- )
2732
- session.add(artifact_version_schema)
2873
+ assert artifact_version_id
2733
2874
 
2734
- # Save visualizations of the artifact.
2875
+ with Session(self.engine) as session:
2876
+ # Save visualizations of the artifact
2735
2877
  if artifact_version.visualizations:
2736
2878
  for vis in artifact_version.visualizations:
2737
2879
  vis_schema = ArtifactVisualizationSchema.from_model(
2738
2880
  artifact_visualization_request=vis,
2739
- artifact_version_id=artifact_version_schema.id,
2881
+ artifact_version_id=artifact_version_id,
2740
2882
  )
2741
2883
  session.add(vis_schema)
2742
2884
 
2743
- # Save tags of the artifact.
2885
+ # Save tags of the artifact
2744
2886
  if artifact_version.tags:
2745
2887
  self._attach_tags_to_resource(
2746
2888
  tag_names=artifact_version.tags,
2747
- resource_id=artifact_version_schema.id,
2889
+ resource_id=artifact_version_id,
2748
2890
  resource_type=TaggableResourceTypes.ARTIFACT_VERSION,
2749
2891
  )
2750
2892
 
2751
- try:
2752
- _check(1)
2753
- session.commit()
2754
- except EntityExistsError as e:
2755
- session.rollback()
2756
- raise e
2893
+ # Save metadata of the artifact
2894
+ if artifact_version.metadata:
2895
+ for key, value in artifact_version.metadata.items():
2896
+ run_metadata_schema = RunMetadataSchema(
2897
+ workspace_id=artifact_version.workspace,
2898
+ user_id=artifact_version.user,
2899
+ resource_id=artifact_version_id,
2900
+ resource_type=MetadataResourceTypes.ARTIFACT_VERSION,
2901
+ key=key,
2902
+ value=json.dumps(value),
2903
+ type=get_metadata_type(value),
2904
+ )
2905
+ session.add(run_metadata_schema)
2906
+
2907
+ session.commit()
2908
+ artifact_version_schema = session.exec(
2909
+ select(ArtifactVersionSchema).where(
2910
+ ArtifactVersionSchema.id == artifact_version_id
2911
+ )
2912
+ ).one()
2757
2913
 
2758
- return artifact_version_schema.to_model(include_metadata=True)
2914
+ return artifact_version_schema.to_model(
2915
+ include_metadata=True, include_resources=True
2916
+ )
2759
2917
 
2760
2918
  def get_artifact_version(
2761
2919
  self, artifact_version_id: UUID, hydrate: bool = True
@@ -2865,7 +3023,9 @@ class SqlZenStore(BaseZenStore):
2865
3023
  session.add(existing_artifact_version)
2866
3024
  session.commit()
2867
3025
  session.refresh(existing_artifact_version)
2868
- return existing_artifact_version.to_model(include_metadata=True)
3026
+ return existing_artifact_version.to_model(
3027
+ include_metadata=True, include_resources=True
3028
+ )
2869
3029
 
2870
3030
  def delete_artifact_version(self, artifact_version_id: UUID) -> None:
2871
3031
  """Deletes an artifact version.
@@ -2972,7 +3132,9 @@ class SqlZenStore(BaseZenStore):
2972
3132
  f"{artifact_visualization_id}: "
2973
3133
  f"No artifact visualization with this ID found."
2974
3134
  )
2975
- return artifact_visualization.to_model(include_metadata=hydrate)
3135
+ return artifact_visualization.to_model(
3136
+ include_metadata=hydrate, include_resources=True
3137
+ )
2976
3138
 
2977
3139
  # ------------------------ Code References ------------------------
2978
3140
 
@@ -3004,7 +3166,9 @@ class SqlZenStore(BaseZenStore):
3004
3166
  f"{code_reference_id}: "
3005
3167
  f"No code reference with this ID found."
3006
3168
  )
3007
- return code_reference.to_model(include_metadata=hydrate)
3169
+ return code_reference.to_model(
3170
+ include_metadata=hydrate, include_resources=True
3171
+ )
3008
3172
 
3009
3173
  # --------------------------- Code Repositories ---------------------------
3010
3174
 
@@ -3045,7 +3209,9 @@ class SqlZenStore(BaseZenStore):
3045
3209
  session.commit()
3046
3210
  session.refresh(new_repo)
3047
3211
 
3048
- return new_repo.to_model(include_metadata=True)
3212
+ return new_repo.to_model(
3213
+ include_metadata=True, include_resources=True
3214
+ )
3049
3215
 
3050
3216
  def get_code_repository(
3051
3217
  self, code_repository_id: UUID, hydrate: bool = True
@@ -3076,7 +3242,9 @@ class SqlZenStore(BaseZenStore):
3076
3242
  "ID found."
3077
3243
  )
3078
3244
 
3079
- return repo.to_model(include_metadata=hydrate)
3245
+ return repo.to_model(
3246
+ include_metadata=hydrate, include_resources=True
3247
+ )
3080
3248
 
3081
3249
  def list_code_repositories(
3082
3250
  self,
@@ -3137,7 +3305,9 @@ class SqlZenStore(BaseZenStore):
3137
3305
  session.add(existing_repo)
3138
3306
  session.commit()
3139
3307
 
3140
- return existing_repo.to_model(include_metadata=True)
3308
+ return existing_repo.to_model(
3309
+ include_metadata=True, include_resources=True
3310
+ )
3141
3311
 
3142
3312
  def delete_code_repository(self, code_repository_id: UUID) -> None:
3143
3313
  """Deletes a code repository.
@@ -3192,17 +3362,22 @@ class SqlZenStore(BaseZenStore):
3192
3362
  session=session,
3193
3363
  )
3194
3364
 
3365
+ is_default_stack_component = (
3366
+ component.name == DEFAULT_STACK_AND_COMPONENT_NAME
3367
+ and component.type
3368
+ in {
3369
+ StackComponentType.ORCHESTRATOR,
3370
+ StackComponentType.ARTIFACT_STORE,
3371
+ }
3372
+ )
3195
3373
  # We have to skip the validation of the default components
3196
3374
  # as it creates a loop of initialization.
3197
- if component.name != "default" or (
3198
- component.type != StackComponentType.ORCHESTRATOR
3199
- and component.type != StackComponentType.ARTIFACT_STORE
3200
- ):
3375
+ if not is_default_stack_component:
3201
3376
  from zenml.stack.utils import validate_stack_component_config
3202
3377
 
3203
3378
  validate_stack_component_config(
3204
3379
  configuration_dict=component.configuration,
3205
- flavor_name=component.flavor,
3380
+ flavor=component.flavor,
3206
3381
  component_type=component.type,
3207
3382
  zen_store=self,
3208
3383
  validate_custom_flavors=False,
@@ -3248,21 +3423,8 @@ class SqlZenStore(BaseZenStore):
3248
3423
  )
3249
3424
 
3250
3425
  # Create the component
3251
- new_component = StackComponentSchema(
3252
- name=component.name,
3253
- workspace_id=component.workspace,
3254
- user_id=component.user,
3255
- component_spec_path=component.component_spec_path,
3256
- type=component.type,
3257
- flavor=component.flavor,
3258
- configuration=base64.b64encode(
3259
- json.dumps(component.configuration).encode("utf-8")
3260
- ),
3261
- labels=base64.b64encode(
3262
- json.dumps(component.labels).encode("utf-8")
3263
- ),
3264
- connector=service_connector,
3265
- connector_resource_id=component.connector_resource_id,
3426
+ new_component = StackComponentSchema.from_request(
3427
+ request=component, service_connector=service_connector
3266
3428
  )
3267
3429
 
3268
3430
  session.add(new_component)
@@ -3270,7 +3432,9 @@ class SqlZenStore(BaseZenStore):
3270
3432
 
3271
3433
  session.refresh(new_component)
3272
3434
 
3273
- return new_component.to_model(include_metadata=True)
3435
+ return new_component.to_model(
3436
+ include_metadata=True, include_resources=True
3437
+ )
3274
3438
 
3275
3439
  def get_stack_component(
3276
3440
  self, component_id: UUID, hydrate: bool = True
@@ -3300,7 +3464,9 @@ class SqlZenStore(BaseZenStore):
3300
3464
  f"Stack component with ID {component_id} not found."
3301
3465
  )
3302
3466
 
3303
- return stack_component.to_model(include_metadata=hydrate)
3467
+ return stack_component.to_model(
3468
+ include_metadata=hydrate, include_resources=True
3469
+ )
3304
3470
 
3305
3471
  def list_stack_components(
3306
3472
  self,
@@ -3367,7 +3533,7 @@ class SqlZenStore(BaseZenStore):
3367
3533
 
3368
3534
  validate_stack_component_config(
3369
3535
  configuration_dict=component_update.configuration,
3370
- flavor_name=existing_component.flavor,
3536
+ flavor=existing_component.flavor,
3371
3537
  component_type=StackComponentType(existing_component.type),
3372
3538
  zen_store=self,
3373
3539
  validate_custom_flavors=False,
@@ -3423,7 +3589,9 @@ class SqlZenStore(BaseZenStore):
3423
3589
  session.add(existing_component)
3424
3590
  session.commit()
3425
3591
 
3426
- return existing_component.to_model(include_metadata=True)
3592
+ return existing_component.to_model(
3593
+ include_metadata=True, include_resources=True
3594
+ )
3427
3595
 
3428
3596
  def delete_stack_component(self, component_id: UUID) -> None:
3429
3597
  """Delete a stack component.
@@ -3564,7 +3732,9 @@ class SqlZenStore(BaseZenStore):
3564
3732
  session.commit()
3565
3733
  session.refresh(new_device)
3566
3734
 
3567
- device_model = new_device.to_internal_model(hydrate=True)
3735
+ device_model = new_device.to_internal_model(
3736
+ include_metadata=True, include_resources=True
3737
+ )
3568
3738
  # Replace the hashed user code with the original user code
3569
3739
  device_model.user_code = user_code
3570
3740
  # Replace the hashed device code with the original device code
@@ -3600,7 +3770,9 @@ class SqlZenStore(BaseZenStore):
3600
3770
  "this ID found."
3601
3771
  )
3602
3772
 
3603
- return device.to_model(include_metadata=hydrate)
3773
+ return device.to_model(
3774
+ include_metadata=hydrate, include_resources=True
3775
+ )
3604
3776
 
3605
3777
  def get_internal_authorized_device(
3606
3778
  self,
@@ -3646,7 +3818,9 @@ class SqlZenStore(BaseZenStore):
3646
3818
  "device with this client ID found."
3647
3819
  )
3648
3820
 
3649
- return device.to_internal_model(hydrate=hydrate)
3821
+ return device.to_internal_model(
3822
+ include_metadata=hydrate, include_resources=True
3823
+ )
3650
3824
 
3651
3825
  def list_authorized_devices(
3652
3826
  self,
@@ -3706,7 +3880,9 @@ class SqlZenStore(BaseZenStore):
3706
3880
  session.add(existing_device)
3707
3881
  session.commit()
3708
3882
 
3709
- return existing_device.to_model(include_metadata=True)
3883
+ return existing_device.to_model(
3884
+ include_metadata=True, include_resources=True
3885
+ )
3710
3886
 
3711
3887
  def update_internal_authorized_device(
3712
3888
  self, device_id: UUID, update: OAuthDeviceInternalUpdate
@@ -3744,7 +3920,9 @@ class SqlZenStore(BaseZenStore):
3744
3920
  session.add(existing_device)
3745
3921
  session.commit()
3746
3922
 
3747
- device_model = existing_device.to_internal_model(hydrate=True)
3923
+ device_model = existing_device.to_internal_model(
3924
+ include_metadata=True, include_resources=True
3925
+ )
3748
3926
  if user_code:
3749
3927
  # Replace the hashed user code with the original user code
3750
3928
  device_model.user_code = user_code
@@ -3860,7 +4038,9 @@ class SqlZenStore(BaseZenStore):
3860
4038
  session.add(new_flavor)
3861
4039
  session.commit()
3862
4040
 
3863
- return new_flavor.to_model(include_metadata=True)
4041
+ return new_flavor.to_model(
4042
+ include_metadata=True, include_resources=True
4043
+ )
3864
4044
 
3865
4045
  def get_flavor(
3866
4046
  self, flavor_id: UUID, hydrate: bool = True
@@ -3884,7 +4064,9 @@ class SqlZenStore(BaseZenStore):
3884
4064
  ).first()
3885
4065
  if flavor_in_db is None:
3886
4066
  raise KeyError(f"Flavor with ID {flavor_id} not found.")
3887
- return flavor_in_db.to_model(include_metadata=hydrate)
4067
+ return flavor_in_db.to_model(
4068
+ include_metadata=hydrate, include_resources=True
4069
+ )
3888
4070
 
3889
4071
  def list_flavors(
3890
4072
  self,
@@ -3941,7 +4123,9 @@ class SqlZenStore(BaseZenStore):
3941
4123
 
3942
4124
  # Refresh the Model that was just created
3943
4125
  session.refresh(existing_flavor)
3944
- return existing_flavor.to_model(include_metadata=True)
4126
+ return existing_flavor.to_model(
4127
+ include_metadata=True, include_resources=True
4128
+ )
3945
4129
 
3946
4130
  def delete_flavor(self, flavor_id: UUID) -> None:
3947
4131
  """Delete a flavor.
@@ -4008,7 +4192,9 @@ class SqlZenStore(BaseZenStore):
4008
4192
  f"{logs_id}: "
4009
4193
  f"No logs with this ID found."
4010
4194
  )
4011
- return logs.to_model(include_metadata=hydrate)
4195
+ return logs.to_model(
4196
+ include_metadata=hydrate, include_resources=True
4197
+ )
4012
4198
 
4013
4199
  # ----------------------------- Pipelines -----------------------------
4014
4200
 
@@ -4281,7 +4467,9 @@ class SqlZenStore(BaseZenStore):
4281
4467
  session.commit()
4282
4468
  session.refresh(new_build)
4283
4469
 
4284
- return new_build.to_model(include_metadata=True)
4470
+ return new_build.to_model(
4471
+ include_metadata=True, include_resources=True
4472
+ )
4285
4473
 
4286
4474
  def get_build(
4287
4475
  self, build_id: UUID, hydrate: bool = True
@@ -4312,7 +4500,9 @@ class SqlZenStore(BaseZenStore):
4312
4500
  "No build with this ID found."
4313
4501
  )
4314
4502
 
4315
- return build.to_model(include_metadata=hydrate)
4503
+ return build.to_model(
4504
+ include_metadata=hydrate, include_resources=True
4505
+ )
4316
4506
 
4317
4507
  def list_builds(
4318
4508
  self,
@@ -4393,7 +4583,9 @@ class SqlZenStore(BaseZenStore):
4393
4583
  session.commit()
4394
4584
  session.refresh(new_deployment)
4395
4585
 
4396
- return new_deployment.to_model(include_metadata=True)
4586
+ return new_deployment.to_model(
4587
+ include_metadata=True, include_resources=True
4588
+ )
4397
4589
 
4398
4590
  def get_deployment(
4399
4591
  self, deployment_id: UUID, hydrate: bool = True
@@ -4424,7 +4616,9 @@ class SqlZenStore(BaseZenStore):
4424
4616
  "No deployment with this ID found."
4425
4617
  )
4426
4618
 
4427
- return deployment.to_model(include_metadata=hydrate)
4619
+ return deployment.to_model(
4620
+ include_metadata=hydrate, include_resources=True
4621
+ )
4428
4622
 
4429
4623
  def list_deployments(
4430
4624
  self,
@@ -4507,7 +4701,7 @@ class SqlZenStore(BaseZenStore):
4507
4701
  raise EntityExistsError(
4508
4702
  f"Unable to create run template in workspace "
4509
4703
  f"'{existing_template.workspace.name}': A run template "
4510
- "with this name already exists."
4704
+ f"with the name '{template.name}' already exists."
4511
4705
  )
4512
4706
 
4513
4707
  deployment = session.exec(
@@ -5299,7 +5493,9 @@ class SqlZenStore(BaseZenStore):
5299
5493
  session.add(run_metadata_schema)
5300
5494
  session.commit()
5301
5495
  return_value.append(
5302
- run_metadata_schema.to_model(include_metadata=True)
5496
+ run_metadata_schema.to_model(
5497
+ include_metadata=True, include_resources=True
5498
+ )
5303
5499
  )
5304
5500
  return return_value
5305
5501
 
@@ -5331,7 +5527,9 @@ class SqlZenStore(BaseZenStore):
5331
5527
  f"{run_metadata_id}: "
5332
5528
  f"No run metadata with this ID found."
5333
5529
  )
5334
- return run_metadata.to_model(include_metadata=hydrate)
5530
+ return run_metadata.to_model(
5531
+ include_metadata=hydrate, include_resources=True
5532
+ )
5335
5533
 
5336
5534
  def list_run_metadata(
5337
5535
  self,
@@ -5374,7 +5572,9 @@ class SqlZenStore(BaseZenStore):
5374
5572
  new_schedule = ScheduleSchema.from_request(schedule)
5375
5573
  session.add(new_schedule)
5376
5574
  session.commit()
5377
- return new_schedule.to_model(include_metadata=True)
5575
+ return new_schedule.to_model(
5576
+ include_metadata=True, include_resources=True
5577
+ )
5378
5578
 
5379
5579
  def get_schedule(
5380
5580
  self, schedule_id: UUID, hydrate: bool = True
@@ -5402,7 +5602,9 @@ class SqlZenStore(BaseZenStore):
5402
5602
  f"Unable to get schedule with ID '{schedule_id}': "
5403
5603
  "No schedule with this ID found."
5404
5604
  )
5405
- return schedule.to_model(include_metadata=hydrate)
5605
+ return schedule.to_model(
5606
+ include_metadata=hydrate, include_resources=True
5607
+ )
5406
5608
 
5407
5609
  def list_schedules(
5408
5610
  self,
@@ -5462,7 +5664,9 @@ class SqlZenStore(BaseZenStore):
5462
5664
  existing_schedule = existing_schedule.update(schedule_update)
5463
5665
  session.add(existing_schedule)
5464
5666
  session.commit()
5465
- return existing_schedule.to_model(include_metadata=True)
5667
+ return existing_schedule.to_model(
5668
+ include_metadata=True, include_resources=True
5669
+ )
5466
5670
 
5467
5671
  def delete_schedule(self, schedule_id: UUID) -> None:
5468
5672
  """Deletes a schedule.
@@ -5928,7 +6132,9 @@ class SqlZenStore(BaseZenStore):
5928
6132
  session.add(new_secret)
5929
6133
  session.commit()
5930
6134
 
5931
- secret_model = new_secret.to_model(include_metadata=True)
6135
+ secret_model = new_secret.to_model(
6136
+ include_metadata=True, include_resources=True
6137
+ )
5932
6138
 
5933
6139
  try:
5934
6140
  # Set the secret values in the configured secrets store
@@ -5968,7 +6174,9 @@ class SqlZenStore(BaseZenStore):
5968
6174
  ).first()
5969
6175
  if secret_in_db is None:
5970
6176
  raise KeyError(f"Secret with ID {secret_id} not found.")
5971
- secret_model = secret_in_db.to_model(include_metadata=hydrate)
6177
+ secret_model = secret_in_db.to_model(
6178
+ include_metadata=hydrate, include_resources=True
6179
+ )
5972
6180
 
5973
6181
  secret_model.set_secrets(self._get_secret_values(secret_id=secret_id))
5974
6182
 
@@ -6071,7 +6279,9 @@ class SqlZenStore(BaseZenStore):
6071
6279
 
6072
6280
  # Refresh the Model that was just created
6073
6281
  session.refresh(existing_secret)
6074
- secret_model = existing_secret.to_model(include_metadata=True)
6282
+ secret_model = existing_secret.to_model(
6283
+ include_metadata=True, include_resources=True
6284
+ )
6075
6285
 
6076
6286
  if secret_update.values is not None:
6077
6287
  # Update the secret values in the configured secrets store
@@ -6287,7 +6497,9 @@ class SqlZenStore(BaseZenStore):
6287
6497
  # on commit an IntegrityError may arise we let it bubble up
6288
6498
  session.commit()
6289
6499
 
6290
- return new_account.to_service_account_model(include_metadata=True)
6500
+ return new_account.to_service_account_model(
6501
+ include_metadata=True, include_resources=True
6502
+ )
6291
6503
 
6292
6504
  def get_service_account(
6293
6505
  self,
@@ -6314,7 +6526,9 @@ class SqlZenStore(BaseZenStore):
6314
6526
  service_account=True,
6315
6527
  )
6316
6528
 
6317
- return account.to_service_account_model(include_metadata=hydrate)
6529
+ return account.to_service_account_model(
6530
+ include_metadata=hydrate, include_resources=True
6531
+ )
6318
6532
 
6319
6533
  def list_service_accounts(
6320
6534
  self,
@@ -6341,7 +6555,7 @@ class SqlZenStore(BaseZenStore):
6341
6555
  table=UserSchema,
6342
6556
  filter_model=filter_model,
6343
6557
  custom_schema_to_model_conversion=lambda user: user.to_service_account_model(
6344
- include_metadata=hydrate
6558
+ include_metadata=hydrate, include_resources=True
6345
6559
  ),
6346
6560
  hydrate=hydrate,
6347
6561
  )
@@ -6403,7 +6617,7 @@ class SqlZenStore(BaseZenStore):
6403
6617
  # Refresh the Model that was just created
6404
6618
  session.refresh(existing_service_account)
6405
6619
  return existing_service_account.to_service_account_model(
6406
- include_metadata=True
6620
+ include_metadata=True, include_resources=True
6407
6621
  )
6408
6622
 
6409
6623
  def delete_service_account(
@@ -6510,7 +6724,9 @@ class SqlZenStore(BaseZenStore):
6510
6724
 
6511
6725
  raise
6512
6726
 
6513
- connector = new_service_connector.to_model(include_metadata=True)
6727
+ connector = new_service_connector.to_model(
6728
+ include_metadata=True, include_resources=True
6729
+ )
6514
6730
  self._populate_connector_type(connector)
6515
6731
 
6516
6732
  return connector
@@ -6544,7 +6760,9 @@ class SqlZenStore(BaseZenStore):
6544
6760
  "found."
6545
6761
  )
6546
6762
 
6547
- connector = service_connector.to_model(include_metadata=hydrate)
6763
+ connector = service_connector.to_model(
6764
+ include_metadata=hydrate, include_resources=True
6765
+ )
6548
6766
  self._populate_connector_type(connector)
6549
6767
  return connector
6550
6768
 
@@ -6758,7 +6976,9 @@ class SqlZenStore(BaseZenStore):
6758
6976
  session.add(existing_connector)
6759
6977
  session.commit()
6760
6978
 
6761
- connector = existing_connector.to_model(include_metadata=True)
6979
+ connector = existing_connector.to_model(
6980
+ include_metadata=True, include_resources=True
6981
+ )
6762
6982
  self._populate_connector_type(connector)
6763
6983
  return connector
6764
6984
 
@@ -7276,7 +7496,7 @@ class SqlZenStore(BaseZenStore):
7276
7496
  hydrate=False,
7277
7497
  )
7278
7498
  need_to_generate_permanent_tokens = (
7279
- orchestrator.flavor.startswith("vm_")
7499
+ orchestrator.flavor_name.startswith("vm_")
7280
7500
  )
7281
7501
  else:
7282
7502
  need_to_generate_permanent_tokens = (
@@ -7532,7 +7752,9 @@ class SqlZenStore(BaseZenStore):
7532
7752
  session=session,
7533
7753
  )
7534
7754
 
7535
- return new_stack_schema.to_model(include_metadata=True)
7755
+ return new_stack_schema.to_model(
7756
+ include_metadata=True, include_resources=True
7757
+ )
7536
7758
 
7537
7759
  except Exception:
7538
7760
  for component_id in components_created_ids:
@@ -7568,7 +7790,9 @@ class SqlZenStore(BaseZenStore):
7568
7790
 
7569
7791
  if stack is None:
7570
7792
  raise KeyError(f"Stack with ID {stack_id} not found.")
7571
- return stack.to_model(include_metadata=hydrate)
7793
+ return stack.to_model(
7794
+ include_metadata=hydrate, include_resources=True
7795
+ )
7572
7796
 
7573
7797
  def list_stacks(
7574
7798
  self,
@@ -7660,7 +7884,9 @@ class SqlZenStore(BaseZenStore):
7660
7884
  session.commit()
7661
7885
  session.refresh(existing_stack)
7662
7886
 
7663
- return existing_stack.to_model(include_metadata=True)
7887
+ return existing_stack.to_model(
7888
+ include_metadata=True, include_resources=True
7889
+ )
7664
7890
 
7665
7891
  def delete_stack(self, stack_id: UUID) -> None:
7666
7892
  """Delete a stack.
@@ -7974,7 +8200,9 @@ class SqlZenStore(BaseZenStore):
7974
8200
 
7975
8201
  session.commit()
7976
8202
 
7977
- return step_schema.to_model(include_metadata=True)
8203
+ return step_schema.to_model(
8204
+ include_metadata=True, include_resources=True
8205
+ )
7978
8206
 
7979
8207
  def get_run_step(
7980
8208
  self, step_run_id: UUID, hydrate: bool = True
@@ -8926,7 +9154,9 @@ class SqlZenStore(BaseZenStore):
8926
9154
  },
8927
9155
  )
8928
9156
 
8929
- return new_user.to_model(include_metadata=True)
9157
+ return new_user.to_model(
9158
+ include_metadata=True, include_resources=True
9159
+ )
8930
9160
 
8931
9161
  def get_user(
8932
9162
  self,
@@ -8973,7 +9203,9 @@ class SqlZenStore(BaseZenStore):
8973
9203
  )
8974
9204
 
8975
9205
  return user.to_model(
8976
- include_private=include_private, include_metadata=hydrate
9206
+ include_private=include_private,
9207
+ include_metadata=hydrate,
9208
+ include_resources=True,
8977
9209
  )
8978
9210
 
8979
9211
  def get_auth_user(
@@ -9101,7 +9333,9 @@ class SqlZenStore(BaseZenStore):
9101
9333
 
9102
9334
  # Refresh the Model that was just created
9103
9335
  session.refresh(existing_user)
9104
- updated_user = existing_user.to_model(include_metadata=True)
9336
+ updated_user = existing_user.to_model(
9337
+ include_metadata=True, include_resources=True
9338
+ )
9105
9339
 
9106
9340
  survey_finished_after = (
9107
9341
  FINISHED_ONBOARDING_SURVEY_KEY in updated_user.user_metadata
@@ -9181,10 +9415,9 @@ class SqlZenStore(BaseZenStore):
9181
9415
  * server deployments that set the `auto_activate` server
9182
9416
  setting explicitly to `True`. This includes:
9183
9417
  * local ZenML server deployments: the server is deployed locally
9184
- with `zenml up`
9418
+ with `zenml login --local`
9185
9419
  * local ZenML docker deployments: the server is deployed locally
9186
- with `zenml up --docker`
9187
- * legacy dashboard deployments
9420
+ with `zenml login --local --docker`
9188
9421
 
9189
9422
  For all other cases, or if the external authentication scheme is used,
9190
9423
  no default admin user is created. The user must activate the server and
@@ -9279,7 +9512,9 @@ class SqlZenStore(BaseZenStore):
9279
9512
  # Explicitly refresh the new_workspace schema
9280
9513
  session.refresh(new_workspace)
9281
9514
 
9282
- workspace_model = new_workspace.to_model(include_metadata=True)
9515
+ workspace_model = new_workspace.to_model(
9516
+ include_metadata=True, include_resources=True
9517
+ )
9283
9518
 
9284
9519
  self._get_or_create_default_stack(workspace=workspace_model)
9285
9520
  return workspace_model
@@ -9301,7 +9536,9 @@ class SqlZenStore(BaseZenStore):
9301
9536
  workspace = self._get_workspace_schema(
9302
9537
  workspace_name_or_id, session=session
9303
9538
  )
9304
- return workspace.to_model(include_metadata=hydrate)
9539
+ return workspace.to_model(
9540
+ include_metadata=hydrate, include_resources=True
9541
+ )
9305
9542
 
9306
9543
  def list_workspaces(
9307
9544
  self,
@@ -9373,7 +9610,9 @@ class SqlZenStore(BaseZenStore):
9373
9610
 
9374
9611
  # Refresh the Model that was just created
9375
9612
  session.refresh(existing_workspace)
9376
- return existing_workspace.to_model(include_metadata=True)
9613
+ return existing_workspace.to_model(
9614
+ include_metadata=True, include_resources=True
9615
+ )
9377
9616
 
9378
9617
  def delete_workspace(self, workspace_name_or_id: Union[str, UUID]) -> None:
9379
9618
  """Deletes a workspace.
@@ -9814,7 +10053,9 @@ class SqlZenStore(BaseZenStore):
9814
10053
  resource_type=TaggableResourceTypes.MODEL,
9815
10054
  )
9816
10055
  session.commit()
9817
- return model_schema.to_model(include_metadata=True)
10056
+ return model_schema.to_model(
10057
+ include_metadata=True, include_resources=True
10058
+ )
9818
10059
 
9819
10060
  def get_model(
9820
10061
  self,
@@ -9843,7 +10084,9 @@ class SqlZenStore(BaseZenStore):
9843
10084
  f"Unable to get model with ID `{model_name_or_id}`: "
9844
10085
  f"No model with this ID found."
9845
10086
  )
9846
- return model.to_model(include_metadata=hydrate)
10087
+ return model.to_model(
10088
+ include_metadata=hydrate, include_resources=True
10089
+ )
9847
10090
 
9848
10091
  def list_models(
9849
10092
  self,
@@ -9939,7 +10182,9 @@ class SqlZenStore(BaseZenStore):
9939
10182
 
9940
10183
  # Refresh the Model that was just created
9941
10184
  session.refresh(existing_model)
9942
- return existing_model.to_model(include_metadata=True)
10185
+ return existing_model.to_model(
10186
+ include_metadata=True, include_resources=True
10187
+ )
9943
10188
 
9944
10189
  # ----------------------------- Model Versions -----------------------------
9945
10190
 
@@ -10017,7 +10262,9 @@ class SqlZenStore(BaseZenStore):
10017
10262
  session.rollback()
10018
10263
  raise e
10019
10264
 
10020
- return model_version_schema.to_model(include_metadata=True)
10265
+ return model_version_schema.to_model(
10266
+ include_metadata=True, include_resources=True
10267
+ )
10021
10268
 
10022
10269
  def get_model_version(
10023
10270
  self, model_version_id: UUID, hydrate: bool = True
@@ -10242,7 +10489,7 @@ class SqlZenStore(BaseZenStore):
10242
10489
  session.add(model_version_artifact_link_schema)
10243
10490
  session.commit()
10244
10491
  return model_version_artifact_link_schema.to_model(
10245
- include_metadata=True
10492
+ include_metadata=True, include_resources=True
10246
10493
  )
10247
10494
 
10248
10495
  def list_model_version_artifact_links(
@@ -10403,7 +10650,7 @@ class SqlZenStore(BaseZenStore):
10403
10650
  session.add(model_version_pipeline_run_link_schema)
10404
10651
  session.commit()
10405
10652
  return model_version_pipeline_run_link_schema.to_model(
10406
- include_metadata=True
10653
+ include_metadata=True, include_resources=True
10407
10654
  )
10408
10655
 
10409
10656
  def list_model_version_pipeline_run_links(
@@ -10567,7 +10814,9 @@ class SqlZenStore(BaseZenStore):
10567
10814
  session.add(tag_schema)
10568
10815
 
10569
10816
  session.commit()
10570
- return tag_schema.to_model(include_metadata=True)
10817
+ return tag_schema.to_model(
10818
+ include_metadata=True, include_resources=True
10819
+ )
10571
10820
 
10572
10821
  def delete_tag(
10573
10822
  self,
@@ -10618,7 +10867,9 @@ class SqlZenStore(BaseZenStore):
10618
10867
  f"Unable to get tag with ID `{tag_name_or_id}`: "
10619
10868
  f"No tag with this ID found."
10620
10869
  )
10621
- return tag.to_model(include_metadata=hydrate)
10870
+ return tag.to_model(
10871
+ include_metadata=hydrate, include_resources=True
10872
+ )
10622
10873
 
10623
10874
  def list_tags(
10624
10875
  self,
@@ -10676,7 +10927,7 @@ class SqlZenStore(BaseZenStore):
10676
10927
 
10677
10928
  # Refresh the tag that was just created
10678
10929
  session.refresh(tag)
10679
- return tag.to_model(include_metadata=True)
10930
+ return tag.to_model(include_metadata=True, include_resources=True)
10680
10931
 
10681
10932
  ####################
10682
10933
  # Tags <> resources
@@ -10719,7 +10970,9 @@ class SqlZenStore(BaseZenStore):
10719
10970
  session.add(tag_resource_schema)
10720
10971
 
10721
10972
  session.commit()
10722
- return tag_resource_schema.to_model(include_metadata=True)
10973
+ return tag_resource_schema.to_model(
10974
+ include_metadata=True, include_resources=True
10975
+ )
10723
10976
 
10724
10977
  def delete_tag_resource(
10725
10978
  self,