zenml-nightly 0.75.0.dev20250312__py3-none-any.whl → 0.75.0.dev20250314__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 (191) hide show
  1. zenml/VERSION +1 -1
  2. zenml/__init__.py +2 -0
  3. zenml/analytics/context.py +7 -0
  4. zenml/analytics/enums.py +2 -2
  5. zenml/artifacts/utils.py +2 -4
  6. zenml/cli/__init__.py +8 -9
  7. zenml/cli/base.py +2 -2
  8. zenml/cli/code_repository.py +1 -1
  9. zenml/cli/login.py +6 -0
  10. zenml/cli/model.py +7 -15
  11. zenml/cli/pipeline.py +3 -3
  12. zenml/cli/project.py +172 -0
  13. zenml/cli/secret.py +47 -44
  14. zenml/cli/service_accounts.py +0 -1
  15. zenml/cli/service_connectors.py +15 -17
  16. zenml/cli/stack.py +0 -3
  17. zenml/cli/stack_components.py +2 -2
  18. zenml/cli/tag.py +3 -5
  19. zenml/cli/utils.py +25 -23
  20. zenml/client.py +749 -475
  21. zenml/config/global_config.py +48 -37
  22. zenml/config/pipeline_configurations.py +3 -2
  23. zenml/config/pipeline_run_configuration.py +2 -1
  24. zenml/config/secret_reference_mixin.py +1 -1
  25. zenml/constants.py +6 -6
  26. zenml/enums.py +0 -7
  27. zenml/event_hub/event_hub.py +3 -1
  28. zenml/exceptions.py +0 -24
  29. zenml/integrations/aws/orchestrators/sagemaker_orchestrator.py +5 -3
  30. zenml/integrations/bitbucket/plugins/event_sources/bitbucket_webhook_event_source.py +1 -4
  31. zenml/integrations/gcp/service_connectors/gcp_service_connector.py +7 -6
  32. zenml/integrations/github/plugins/event_sources/github_webhook_event_source.py +1 -4
  33. zenml/integrations/mlflow/steps/mlflow_registry.py +3 -3
  34. zenml/integrations/seldon/model_deployers/seldon_model_deployer.py +1 -1
  35. zenml/integrations/wandb/__init__.py +1 -1
  36. zenml/integrations/wandb/experiment_trackers/wandb_experiment_tracker.py +29 -9
  37. zenml/integrations/wandb/flavors/wandb_experiment_tracker_flavor.py +5 -3
  38. zenml/model/model.py +10 -10
  39. zenml/model_registries/base_model_registry.py +1 -1
  40. zenml/models/__init__.py +45 -28
  41. zenml/models/v2/base/base.py +0 -5
  42. zenml/models/v2/base/filter.py +2 -2
  43. zenml/models/v2/base/scoped.py +135 -156
  44. zenml/models/v2/core/action.py +12 -12
  45. zenml/models/v2/core/api_key.py +1 -1
  46. zenml/models/v2/core/artifact.py +31 -18
  47. zenml/models/v2/core/artifact_version.py +57 -40
  48. zenml/models/v2/core/code_repository.py +12 -12
  49. zenml/models/v2/core/component.py +22 -33
  50. zenml/models/v2/core/device.py +3 -2
  51. zenml/models/v2/core/event_source.py +14 -14
  52. zenml/models/v2/core/flavor.py +19 -47
  53. zenml/models/v2/core/logs.py +1 -2
  54. zenml/models/v2/core/model.py +23 -20
  55. zenml/models/v2/core/model_version.py +51 -42
  56. zenml/models/v2/core/pipeline.py +16 -16
  57. zenml/models/v2/core/pipeline_build.py +14 -14
  58. zenml/models/v2/core/pipeline_deployment.py +12 -14
  59. zenml/models/v2/core/pipeline_run.py +21 -29
  60. zenml/models/v2/core/project.py +203 -0
  61. zenml/models/v2/core/run_metadata.py +2 -2
  62. zenml/models/v2/core/run_template.py +16 -17
  63. zenml/models/v2/core/schedule.py +12 -21
  64. zenml/models/v2/core/secret.py +94 -128
  65. zenml/models/v2/core/server_settings.py +2 -2
  66. zenml/models/v2/core/service.py +57 -26
  67. zenml/models/v2/core/service_connector.py +14 -16
  68. zenml/models/v2/core/stack.py +24 -26
  69. zenml/models/v2/core/step_run.py +16 -28
  70. zenml/models/v2/core/tag.py +41 -15
  71. zenml/models/v2/core/trigger.py +13 -13
  72. zenml/models/v2/core/trigger_execution.py +2 -2
  73. zenml/models/v2/core/user.py +2 -2
  74. zenml/models/v2/misc/statistics.py +45 -0
  75. zenml/models/v2/misc/tag.py +27 -0
  76. zenml/orchestrators/cache_utils.py +7 -7
  77. zenml/orchestrators/input_utils.py +1 -0
  78. zenml/orchestrators/step_launcher.py +1 -2
  79. zenml/orchestrators/step_run_utils.py +2 -4
  80. zenml/orchestrators/step_runner.py +10 -1
  81. zenml/orchestrators/utils.py +4 -4
  82. zenml/pipelines/build_utils.py +2 -4
  83. zenml/pipelines/pipeline_decorator.py +3 -2
  84. zenml/pipelines/pipeline_definition.py +8 -9
  85. zenml/pipelines/run_utils.py +4 -4
  86. zenml/service_connectors/service_connector.py +0 -10
  87. zenml/service_connectors/service_connector_utils.py +0 -2
  88. zenml/stack/authentication_mixin.py +1 -1
  89. zenml/stack/flavor.py +3 -14
  90. zenml/stack/stack.py +0 -1
  91. zenml/stack/stack_component.py +1 -5
  92. zenml/steps/base_step.py +10 -2
  93. zenml/steps/step_context.py +19 -0
  94. zenml/utils/string_utils.py +1 -1
  95. zenml/utils/tag_utils.py +642 -0
  96. zenml/zen_server/cloud_utils.py +21 -0
  97. zenml/zen_server/exceptions.py +0 -6
  98. zenml/zen_server/rbac/endpoint_utils.py +134 -46
  99. zenml/zen_server/rbac/models.py +65 -3
  100. zenml/zen_server/rbac/rbac_interface.py +9 -0
  101. zenml/zen_server/rbac/rbac_sql_zen_store.py +15 -7
  102. zenml/zen_server/rbac/utils.py +155 -30
  103. zenml/zen_server/rbac/zenml_cloud_rbac.py +39 -11
  104. zenml/zen_server/routers/actions_endpoints.py +3 -5
  105. zenml/zen_server/routers/artifact_endpoint.py +0 -5
  106. zenml/zen_server/routers/artifact_version_endpoints.py +15 -9
  107. zenml/zen_server/routers/auth_endpoints.py +22 -7
  108. zenml/zen_server/routers/code_repositories_endpoints.py +54 -3
  109. zenml/zen_server/routers/devices_endpoints.py +0 -4
  110. zenml/zen_server/routers/event_source_endpoints.py +0 -5
  111. zenml/zen_server/routers/flavors_endpoints.py +0 -5
  112. zenml/zen_server/routers/logs_endpoints.py +0 -1
  113. zenml/zen_server/routers/model_versions_endpoints.py +100 -23
  114. zenml/zen_server/routers/models_endpoints.py +50 -69
  115. zenml/zen_server/routers/pipeline_builds_endpoints.py +55 -3
  116. zenml/zen_server/routers/pipeline_deployments_endpoints.py +56 -4
  117. zenml/zen_server/routers/pipelines_endpoints.py +70 -3
  118. zenml/zen_server/routers/plugin_endpoints.py +0 -1
  119. zenml/zen_server/routers/projects_endpoints.py +283 -0
  120. zenml/zen_server/routers/run_metadata_endpoints.py +97 -0
  121. zenml/zen_server/routers/run_templates_endpoints.py +64 -3
  122. zenml/zen_server/routers/runs_endpoints.py +58 -8
  123. zenml/zen_server/routers/schedule_endpoints.py +67 -6
  124. zenml/zen_server/routers/secrets_endpoints.py +38 -4
  125. zenml/zen_server/routers/server_endpoints.py +53 -1
  126. zenml/zen_server/routers/service_accounts_endpoints.py +14 -15
  127. zenml/zen_server/routers/service_connectors_endpoints.py +94 -14
  128. zenml/zen_server/routers/service_endpoints.py +18 -7
  129. zenml/zen_server/routers/stack_components_endpoints.py +66 -7
  130. zenml/zen_server/routers/stacks_endpoints.py +95 -6
  131. zenml/zen_server/routers/steps_endpoints.py +17 -11
  132. zenml/zen_server/routers/tag_resource_endpoints.py +115 -0
  133. zenml/zen_server/routers/tags_endpoints.py +6 -17
  134. zenml/zen_server/routers/triggers_endpoints.py +5 -8
  135. zenml/zen_server/routers/users_endpoints.py +9 -12
  136. zenml/zen_server/template_execution/utils.py +8 -7
  137. zenml/zen_server/utils.py +21 -0
  138. zenml/zen_server/zen_server_api.py +7 -2
  139. zenml/zen_stores/base_zen_store.py +50 -69
  140. zenml/zen_stores/migrations/versions/12eff0206201_rename_workspace_to_project.py +768 -0
  141. zenml/zen_stores/migrations/versions/1cb6477f72d6_move_artifact_save_type.py +20 -10
  142. zenml/zen_stores/migrations/versions/1f9d1cd00b90_add_unique_name_constraints.py +231 -0
  143. zenml/zen_stores/migrations/versions/288f4fb6e112_make_tags_user_scoped.py +74 -0
  144. zenml/zen_stores/migrations/versions/2e695a26fe7a_add_user_default_workspace.py +45 -0
  145. zenml/zen_stores/migrations/versions/3b1776345020_remove_workspace_from_globals.py +81 -0
  146. zenml/zen_stores/migrations/versions/41b28cae31ce_make_artifacts_workspace_scoped.py +136 -0
  147. zenml/zen_stores/migrations/versions/9e7bf0970266_adding_exclusive_attribute_to_tags.py +47 -0
  148. zenml/zen_stores/migrations/versions/b557b2871693_update_step_run_input_types.py +8 -4
  149. zenml/zen_stores/migrations/versions/cbc6acd71f92_add_workspace_display_name.py +58 -0
  150. zenml/zen_stores/migrations/versions/cc269488e5a9_separate_run_metadata.py +12 -6
  151. zenml/zen_stores/migrations/versions/f1d723fd723b_add_secret_private_attr.py +61 -0
  152. zenml/zen_stores/migrations/versions/f76a368a25a5_add_stack_description.py +35 -0
  153. zenml/zen_stores/rest_zen_store.py +223 -230
  154. zenml/zen_stores/schemas/__init__.py +2 -2
  155. zenml/zen_stores/schemas/action_schemas.py +15 -8
  156. zenml/zen_stores/schemas/api_key_schemas.py +8 -1
  157. zenml/zen_stores/schemas/artifact_schemas.py +35 -10
  158. zenml/zen_stores/schemas/code_repository_schemas.py +22 -17
  159. zenml/zen_stores/schemas/component_schemas.py +9 -14
  160. zenml/zen_stores/schemas/event_source_schemas.py +15 -8
  161. zenml/zen_stores/schemas/flavor_schemas.py +14 -20
  162. zenml/zen_stores/schemas/model_schemas.py +18 -17
  163. zenml/zen_stores/schemas/pipeline_build_schemas.py +7 -7
  164. zenml/zen_stores/schemas/pipeline_deployment_schemas.py +10 -8
  165. zenml/zen_stores/schemas/pipeline_run_schemas.py +9 -12
  166. zenml/zen_stores/schemas/pipeline_schemas.py +9 -9
  167. zenml/zen_stores/schemas/{workspace_schemas.py → project_schemas.py} +53 -65
  168. zenml/zen_stores/schemas/run_metadata_schemas.py +5 -5
  169. zenml/zen_stores/schemas/run_template_schemas.py +17 -13
  170. zenml/zen_stores/schemas/schedule_schema.py +16 -21
  171. zenml/zen_stores/schemas/secret_schemas.py +15 -25
  172. zenml/zen_stores/schemas/service_connector_schemas.py +8 -17
  173. zenml/zen_stores/schemas/service_schemas.py +7 -8
  174. zenml/zen_stores/schemas/stack_schemas.py +12 -15
  175. zenml/zen_stores/schemas/step_run_schemas.py +14 -15
  176. zenml/zen_stores/schemas/tag_schemas.py +30 -2
  177. zenml/zen_stores/schemas/trigger_schemas.py +15 -8
  178. zenml/zen_stores/schemas/user_schemas.py +12 -2
  179. zenml/zen_stores/schemas/utils.py +16 -0
  180. zenml/zen_stores/secrets_stores/service_connector_secrets_store.py +0 -3
  181. zenml/zen_stores/sql_zen_store.py +2984 -2369
  182. zenml/zen_stores/template_utils.py +1 -1
  183. zenml/zen_stores/zen_store_interface.py +136 -126
  184. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/METADATA +1 -1
  185. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/RECORD +188 -173
  186. zenml/cli/workspace.py +0 -86
  187. zenml/models/v2/core/workspace.py +0 -131
  188. zenml/zen_server/routers/workspaces_endpoints.py +0 -1469
  189. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/LICENSE +0 -0
  190. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/WHEEL +0 -0
  191. {zenml_nightly-0.75.0.dev20250312.dist-info → zenml_nightly-0.75.0.dev20250314.dist-info}/entry_points.txt +0 -0
@@ -1131,7 +1131,6 @@ def describe_service_connector(
1131
1131
  )
1132
1132
 
1133
1133
  connector = connector_client.to_response_model(
1134
- workspace=client.active_workspace,
1135
1134
  user=client.active_user,
1136
1135
  )
1137
1136
  else:
@@ -1903,29 +1902,28 @@ def login_service_connector(
1903
1902
  "list-resources",
1904
1903
  help="""List all resources accessible by service connectors.
1905
1904
 
1906
- This command can be used to list all resources that can be accessed by service
1907
- connectors configured in your workspace. You can filter the list by connector
1905
+ This command can be used to list all resources that can be accessed by the
1906
+ currently registered service connectors. You can filter the list by connector
1908
1907
  type and/or resource type.
1909
1908
 
1910
1909
  Use this command to answer questions like:
1911
1910
 
1912
1911
  - show a list of all Kubernetes clusters that can be accessed by way of service
1913
- connectors configured in my workspace
1914
- - show a list of all connectors configured for my workspace along with all the
1915
- resources they can access or the error state they are in, if any
1912
+ connectors
1913
+ - show a list of all connectors along with all the resources they can access or
1914
+ the error state they are in, if any
1916
1915
 
1917
- NOTE: since this command exercises all service connectors in your workspace, it
1918
- may take a while to complete.
1916
+ NOTE: since this command exercises all service connectors currently registered
1917
+ with ZenML, it may take a while to complete.
1919
1918
 
1920
1919
  Examples:
1921
1920
 
1922
- - show a list of all S3 buckets that can be accessed by service connectors
1923
- configured in your workspace:
1921
+ - show a list of all S3 buckets that can be accessed by service connectors:
1924
1922
 
1925
1923
  $ zenml service-connector list-resources --resource-type s3-bucket
1926
1924
 
1927
- - show a list of all resources that the AWS connectors in your workspace can
1928
- access:
1925
+ - show a list of all resources that the AWS connectors currently registered
1926
+ with ZenML can access:
1929
1927
 
1930
1928
  $ zenml service-connector list-resources --connector-type aws
1931
1929
 
@@ -1983,10 +1981,10 @@ def list_service_connector_resources(
1983
1981
  if not resource_type and not resource_id:
1984
1982
  cli_utils.warning(
1985
1983
  "Fetching all service connector resources can take a long time, "
1986
- "depending on the number of connectors configured in your "
1987
- "workspace. Consider using the '--connector-type', "
1988
- "'--resource-type' and '--resource-id' options to narrow down the "
1989
- "list of resources to fetch."
1984
+ "depending on the number of connectors currently registered with "
1985
+ "ZenML. Consider using the '--connector-type', '--resource-type' "
1986
+ "and '--resource-id' options to narrow down the list of resources "
1987
+ "to fetch."
1990
1988
  )
1991
1989
 
1992
1990
  with console.status(
@@ -2031,7 +2029,7 @@ def list_service_connector_resources(
2031
2029
 
2032
2030
  click.echo(
2033
2031
  f"The {resource_str} can be accessed by"
2034
- f"{connector_str} service connectors configured in your workspace:"
2032
+ f"{connector_str} service connectors:"
2035
2033
  )
2036
2034
 
2037
2035
  cli_utils.print_service_connector_resource_table(
zenml/cli/stack.py CHANGED
@@ -503,8 +503,6 @@ def register_stack(
503
503
  try:
504
504
  created_stack = client.zen_store.create_stack(
505
505
  stack=StackRequest(
506
- user=client.active_user.id,
507
- workspace=client.active_workspace.id,
508
506
  name=stack_name,
509
507
  components=components,
510
508
  service_connectors=[service_connector]
@@ -1914,7 +1912,6 @@ def _get_stack_component_info(
1914
1912
  "Enter the subscription ID:"
1915
1913
  )
1916
1914
  config["resource_group"] = Prompt.ask("Enter the resource group:")
1917
- config["workspace"] = Prompt.ask("Enter the workspace name:")
1918
1915
  elif flavor == "vertex":
1919
1916
  config["location"] = query_region(
1920
1917
  StackDeploymentProvider.GCP, "Vertex AI job"
@@ -1424,8 +1424,8 @@ def connect_stack_component_with_service_connector(
1424
1424
 
1425
1425
  cli_utils.error(
1426
1426
  f"No compatible valid resources were found for the "
1427
- f"'{component_model.name}' {display_name} in your "
1428
- f"workspace. {additional_info}You can create a new "
1427
+ f"'{component_model.name}' {display_name}. "
1428
+ f"{additional_info}You can create a new "
1429
1429
  "connector using the 'zenml service-connector register' "
1430
1430
  "command or list the compatible resources using the "
1431
1431
  f"'zenml service-connector list-resources{command_args}' "
zenml/cli/tag.py CHANGED
@@ -26,8 +26,6 @@ from zenml.exceptions import EntityExistsError
26
26
  from zenml.logger import get_logger
27
27
  from zenml.models import (
28
28
  TagFilter,
29
- TagRequest,
30
- TagUpdate,
31
29
  )
32
30
  from zenml.utils.dict_utils import remove_none_values
33
31
 
@@ -47,7 +45,7 @@ def list_tags(**kwargs: Any) -> None:
47
45
  Args:
48
46
  **kwargs: Keyword arguments to filter models.
49
47
  """
50
- tags = Client().list_tags(TagFilter(**kwargs))
48
+ tags = Client().list_tags(**kwargs)
51
49
 
52
50
  if not tags:
53
51
  cli_utils.declare("No tags found.")
@@ -83,7 +81,7 @@ def register_tag(name: str, color: Optional[ColorVariants]) -> None:
83
81
  """
84
82
  request_dict = remove_none_values(dict(name=name, color=color))
85
83
  try:
86
- tag = Client().create_tag(TagRequest(**request_dict))
84
+ tag = Client().create_tag(**request_dict)
87
85
  except (EntityExistsError, ValueError) as e:
88
86
  cli_utils.error(str(e))
89
87
 
@@ -126,7 +124,7 @@ def update_tag(
126
124
 
127
125
  tag = Client().update_tag(
128
126
  tag_name_or_id=tag_name_or_id,
129
- tag_update_model=TagUpdate(**update_dict),
127
+ **update_dict,
130
128
  )
131
129
 
132
130
  cli_utils.print_pydantic_models(
zenml/cli/utils.py CHANGED
@@ -81,6 +81,7 @@ from zenml.stack.flavor import Flavor
81
81
  from zenml.stack.stack_component import StackComponentConfig
82
82
  from zenml.utils import secret_utils
83
83
  from zenml.utils.time_utils import expires_in
84
+ from zenml.utils.typing_utils import get_origin, is_union
84
85
 
85
86
  if TYPE_CHECKING:
86
87
  from uuid import UUID
@@ -1778,7 +1779,6 @@ def print_service_connector_configuration(
1778
1779
  "AUTH METHOD": connector.auth_method,
1779
1780
  "RESOURCE TYPES": ", ".join(connector.emojified_resource_types),
1780
1781
  "RESOURCE NAME": connector.resource_id or "<multiple>",
1781
- "SECRET ID": connector.secret_id or "",
1782
1782
  "SESSION DURATION": expiration,
1783
1783
  "EXPIRES IN": (
1784
1784
  expires_in(
@@ -1795,7 +1795,6 @@ def print_service_connector_configuration(
1795
1795
  else "N/A"
1796
1796
  ),
1797
1797
  "OWNER": user_name,
1798
- "WORKSPACE": connector.workspace.name,
1799
1798
  "CREATED_AT": connector.created,
1800
1799
  "UPDATED_AT": connector.updated,
1801
1800
  }
@@ -2161,9 +2160,6 @@ def print_debug_stack() -> None:
2161
2160
  console.print(f"ID: {str(stack.id)}")
2162
2161
  if stack.user and stack.user.name and stack.user.id: # mypy check
2163
2162
  console.print(f"User: {stack.user.name} / {str(stack.user.id)}")
2164
- console.print(
2165
- f"Workspace: {stack.workspace.name} / {str(stack.workspace.id)}"
2166
- )
2167
2163
 
2168
2164
  for component_type, components in stack.components.items():
2169
2165
  component = components[0]
@@ -2190,9 +2186,6 @@ def print_debug_stack() -> None:
2190
2186
  console.print(
2191
2187
  f"User: {component_response.user.name} / {str(component_response.user.id)}"
2192
2188
  )
2193
- console.print(
2194
- f"Workspace: {component_response.workspace.name} / {str(component_response.workspace.id)}"
2195
- )
2196
2189
 
2197
2190
 
2198
2191
  def _component_display_name(
@@ -2275,22 +2268,13 @@ def print_pipeline_runs_table(
2275
2268
  print_table(runs_dicts)
2276
2269
 
2277
2270
 
2278
- def warn_unsupported_non_default_workspace() -> None:
2279
- """Warning for unsupported non-default workspace."""
2280
- from zenml.constants import (
2281
- ENV_ZENML_DISABLE_WORKSPACE_WARNINGS,
2282
- handle_bool_env_var,
2283
- )
2284
-
2285
- disable_warnings = handle_bool_env_var(
2286
- ENV_ZENML_DISABLE_WORKSPACE_WARNINGS, False
2287
- )
2288
- if not disable_warnings:
2271
+ def check_zenml_pro_project_availability() -> None:
2272
+ """Check if the ZenML Pro project feature is available."""
2273
+ client = Client()
2274
+ if not client.zen_store.get_store_info().is_pro_server():
2289
2275
  warning(
2290
- "Currently the concept of `workspace` is not supported "
2291
- "within the Dashboard. The Project functionality will be "
2292
- "completed in the coming weeks. For the time being it "
2293
- "is recommended to stay within the `default` workspace."
2276
+ "The ZenML projects feature is available only on ZenML Pro. "
2277
+ "Please visit https://zenml.io/pro to learn more."
2294
2278
  )
2295
2279
 
2296
2280
 
@@ -2402,6 +2386,23 @@ def create_data_type_help_text(
2402
2386
  return f"{field}"
2403
2387
 
2404
2388
 
2389
+ def _is_list_field(field_info: Any) -> bool:
2390
+ """Check if a field is a list field.
2391
+
2392
+ Args:
2393
+ field_info: The field info to check.
2394
+
2395
+ Returns:
2396
+ True if the field is a list field, False otherwise.
2397
+ """
2398
+ field_type = field_info.annotation
2399
+ origin = get_origin(field_type)
2400
+ return origin is list or (
2401
+ is_union(origin)
2402
+ and any(get_origin(arg) is list for arg in field_type.__args__)
2403
+ )
2404
+
2405
+
2405
2406
  def list_options(filter_model: Type[BaseFilter]) -> Callable[[F], F]:
2406
2407
  """Create a decorator to generate the correct list of filter parameters.
2407
2408
 
@@ -2430,6 +2431,7 @@ def list_options(filter_model: Type[BaseFilter]) -> Callable[[F], F]:
2430
2431
  type=str,
2431
2432
  default=v.default,
2432
2433
  required=False,
2434
+ multiple=_is_list_field(v),
2433
2435
  help=create_filter_help_text(filter_model, k),
2434
2436
  )
2435
2437
  )