mlrun 1.7.0rc15__py3-none-any.whl → 1.7.0rc17__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.

Potentially problematic release.


This version of mlrun might be problematic. Click here for more details.

Files changed (77) hide show
  1. mlrun/__init__.py +10 -1
  2. mlrun/__main__.py +18 -4
  3. mlrun/alerts/__init__.py +15 -0
  4. mlrun/alerts/alert.py +144 -0
  5. mlrun/artifacts/__init__.py +7 -1
  6. mlrun/artifacts/base.py +28 -3
  7. mlrun/artifacts/dataset.py +8 -0
  8. mlrun/artifacts/manager.py +18 -0
  9. mlrun/artifacts/model.py +8 -1
  10. mlrun/artifacts/plots.py +13 -0
  11. mlrun/common/schemas/__init__.py +10 -2
  12. mlrun/common/schemas/alert.py +64 -5
  13. mlrun/common/schemas/api_gateway.py +4 -0
  14. mlrun/common/schemas/artifact.py +15 -0
  15. mlrun/common/schemas/auth.py +2 -0
  16. mlrun/common/schemas/model_monitoring/__init__.py +4 -1
  17. mlrun/common/schemas/model_monitoring/constants.py +17 -1
  18. mlrun/common/schemas/model_monitoring/model_endpoints.py +60 -1
  19. mlrun/common/schemas/project.py +5 -1
  20. mlrun/config.py +11 -4
  21. mlrun/datastore/datastore_profile.py +10 -7
  22. mlrun/db/base.py +24 -4
  23. mlrun/db/httpdb.py +97 -43
  24. mlrun/db/nopdb.py +25 -4
  25. mlrun/errors.py +5 -0
  26. mlrun/launcher/base.py +3 -2
  27. mlrun/lists.py +4 -0
  28. mlrun/model.py +15 -8
  29. mlrun/model_monitoring/__init__.py +1 -1
  30. mlrun/model_monitoring/applications/_application_steps.py +1 -2
  31. mlrun/model_monitoring/applications/context.py +1 -1
  32. mlrun/model_monitoring/applications/histogram_data_drift.py +64 -38
  33. mlrun/model_monitoring/db/__init__.py +2 -0
  34. mlrun/model_monitoring/db/stores/base/store.py +9 -36
  35. mlrun/model_monitoring/db/stores/sqldb/sql_store.py +63 -110
  36. mlrun/model_monitoring/db/stores/v3io_kv/kv_store.py +56 -202
  37. mlrun/model_monitoring/db/tsdb/__init__.py +71 -0
  38. mlrun/model_monitoring/db/tsdb/base.py +135 -0
  39. mlrun/model_monitoring/db/tsdb/v3io/__init__.py +15 -0
  40. mlrun/model_monitoring/db/tsdb/v3io/stream_graph_steps.py +117 -0
  41. mlrun/model_monitoring/db/tsdb/v3io/v3io_connector.py +442 -0
  42. mlrun/model_monitoring/db/v3io_tsdb_reader.py +134 -0
  43. mlrun/model_monitoring/stream_processing.py +46 -210
  44. mlrun/model_monitoring/writer.py +50 -100
  45. mlrun/platforms/__init__.py +10 -9
  46. mlrun/platforms/iguazio.py +19 -200
  47. mlrun/projects/operations.py +11 -7
  48. mlrun/projects/pipelines.py +13 -76
  49. mlrun/projects/project.py +62 -17
  50. mlrun/render.py +9 -3
  51. mlrun/run.py +5 -38
  52. mlrun/runtimes/__init__.py +1 -0
  53. mlrun/runtimes/base.py +3 -3
  54. mlrun/runtimes/kubejob.py +2 -1
  55. mlrun/runtimes/nuclio/api_gateway.py +163 -77
  56. mlrun/runtimes/nuclio/application/application.py +160 -7
  57. mlrun/runtimes/nuclio/function.py +25 -45
  58. mlrun/runtimes/pod.py +16 -36
  59. mlrun/runtimes/remotesparkjob.py +1 -1
  60. mlrun/runtimes/sparkjob/spark3job.py +1 -1
  61. mlrun/runtimes/utils.py +0 -38
  62. mlrun/track/tracker.py +2 -1
  63. mlrun/utils/helpers.py +51 -31
  64. mlrun/utils/logger.py +11 -6
  65. mlrun/utils/notifications/notification/base.py +1 -1
  66. mlrun/utils/notifications/notification/slack.py +9 -4
  67. mlrun/utils/notifications/notification/webhook.py +1 -1
  68. mlrun/utils/notifications/notification_pusher.py +21 -14
  69. mlrun/utils/version/version.json +2 -2
  70. {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/METADATA +4 -3
  71. {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/RECORD +75 -69
  72. mlrun/kfpops.py +0 -860
  73. mlrun/platforms/other.py +0 -305
  74. {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/LICENSE +0 -0
  75. {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/WHEEL +0 -0
  76. {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/entry_points.txt +0 -0
  77. {mlrun-1.7.0rc15.dist-info → mlrun-1.7.0rc17.dist-info}/top_level.txt +0 -0
mlrun/run.py CHANGED
@@ -29,11 +29,13 @@ from typing import Optional, Union
29
29
  import nuclio
30
30
  import yaml
31
31
  from kfp import Client
32
+ from mlrun_pipelines.common.models import RunStatuses
33
+ from mlrun_pipelines.common.ops import format_summary_from_kfp_run, show_kfp_run
34
+ from mlrun_pipelines.models import PipelineRun
32
35
 
33
36
  import mlrun.common.schemas
34
37
  import mlrun.errors
35
38
  import mlrun.utils.helpers
36
- from mlrun.kfpops import format_summary_from_kfp_run, show_kfp_run
37
39
 
38
40
  from .common.helpers import parse_versioned_object_uri
39
41
  from .config import config as mlconf
@@ -68,41 +70,6 @@ from .utils import (
68
70
  )
69
71
 
70
72
 
71
- class RunStatuses:
72
- succeeded = "Succeeded"
73
- failed = "Failed"
74
- skipped = "Skipped"
75
- error = "Error"
76
- running = "Running"
77
-
78
- @staticmethod
79
- def all():
80
- return [
81
- RunStatuses.succeeded,
82
- RunStatuses.failed,
83
- RunStatuses.skipped,
84
- RunStatuses.error,
85
- RunStatuses.running,
86
- ]
87
-
88
- @staticmethod
89
- def stable_statuses():
90
- return [
91
- RunStatuses.succeeded,
92
- RunStatuses.failed,
93
- RunStatuses.skipped,
94
- RunStatuses.error,
95
- ]
96
-
97
- @staticmethod
98
- def transient_statuses():
99
- return [
100
- status
101
- for status in RunStatuses.all()
102
- if status not in RunStatuses.stable_statuses()
103
- ]
104
-
105
-
106
73
  def function_to_module(code="", workdir=None, secrets=None, silent=False):
107
74
  """Load code, notebook or mlrun function as .py module
108
75
  this function can import a local/remote py file or notebook
@@ -1021,7 +988,7 @@ def get_pipeline(
1021
988
  :param project: the project of the pipeline run
1022
989
  :param remote: read kfp data from mlrun service (default=True)
1023
990
 
1024
- :return: kfp run dict
991
+ :return: kfp run
1025
992
  """
1026
993
  namespace = namespace or mlconf.namespace
1027
994
  if remote:
@@ -1045,7 +1012,7 @@ def get_pipeline(
1045
1012
  not format_
1046
1013
  or format_ == mlrun.common.schemas.PipelinesFormat.summary.value
1047
1014
  ):
1048
- resp = format_summary_from_kfp_run(resp)
1015
+ resp = format_summary_from_kfp_run(PipelineRun(resp))
1049
1016
 
1050
1017
  show_kfp_run(resp)
1051
1018
  return resp
@@ -43,6 +43,7 @@ from .nuclio import (
43
43
  new_v2_model_server,
44
44
  nuclio_init_hook,
45
45
  )
46
+ from .nuclio.api_gateway import APIGateway
46
47
  from .nuclio.application import ApplicationRuntime
47
48
  from .nuclio.serving import serving_subkind
48
49
  from .remotesparkjob import RemoteSparkRuntime
mlrun/runtimes/base.py CHANGED
@@ -21,6 +21,7 @@ from os import environ
21
21
  from typing import Callable, Optional, Union
22
22
 
23
23
  import requests.exceptions
24
+ from mlrun_pipelines.common.ops import mlrun_op
24
25
  from nuclio.build import mlrun_footer
25
26
 
26
27
  import mlrun.common.constants
@@ -37,7 +38,6 @@ from mlrun.utils.helpers import generate_object_uri, verify_field_regex
37
38
  from ..config import config
38
39
  from ..datastore import store_manager
39
40
  from ..errors import err_to_str
40
- from ..kfpops import mlrun_op
41
41
  from ..lists import RunList
42
42
  from ..model import BaseMetadata, HyperParamOptions, ImageBuilder, ModelObj, RunObject
43
43
  from ..utils import (
@@ -707,11 +707,11 @@ class BaseRuntime(ModelObj):
707
707
  "key": "the_key".
708
708
  :param auto_build: when set to True and the function require build it will be built on the first
709
709
  function run, use only if you dont plan on changing the build config between runs
710
- :return: KubeFlow containerOp
710
+ :return: mlrun_pipelines.models.PipelineNodeWrapper
711
711
  """
712
712
 
713
713
  # if the function contain KFP PipelineParams (futures) pass the full spec to the
714
- # ContainerOp this way KFP will substitute the params with previous step outputs
714
+ # PipelineNodeWrapper this way KFP will substitute the params with previous step outputs
715
715
  if use_db and not self._has_pipeline_param():
716
716
  # if the same function is built as part of the pipeline we do not use the versioned function
717
717
  # rather the latest function w the same tag so we can pick up the updated image/status
mlrun/runtimes/kubejob.py CHANGED
@@ -14,11 +14,12 @@
14
14
 
15
15
  import warnings
16
16
 
17
+ from mlrun_pipelines.common.ops import build_op
18
+
17
19
  import mlrun.common.schemas
18
20
  import mlrun.db
19
21
  import mlrun.errors
20
22
 
21
- from ..kfpops import build_op
22
23
  from ..model import RunObject
23
24
  from .pod import KubeResource
24
25
 
@@ -17,31 +17,31 @@ from typing import Optional, Union
17
17
  from urllib.parse import urljoin
18
18
 
19
19
  import requests
20
- from requests.auth import HTTPBasicAuth
20
+ from nuclio.auth import AuthInfo as NuclioAuthInfo
21
+ from nuclio.auth import AuthKinds as NuclioAuthKinds
21
22
 
22
23
  import mlrun
23
- import mlrun.common.schemas
24
+ import mlrun.common.schemas as schemas
25
+ import mlrun.common.types
26
+ from mlrun.model import ModelObj
27
+ from mlrun.platforms.iguazio import min_iguazio_versions
28
+ from mlrun.utils import logger
24
29
 
25
- from ...model import ModelObj
26
- from ..utils import logger
27
- from .function import RemoteRuntime, get_fullname, min_nuclio_versions
28
- from .serving import ServingRuntime
30
+ from .function import get_fullname, min_nuclio_versions
29
31
 
30
- NUCLIO_API_GATEWAY_AUTHENTICATION_MODE_BASIC_AUTH = "basicAuth"
31
- NUCLIO_API_GATEWAY_AUTHENTICATION_MODE_NONE = "none"
32
32
  PROJECT_NAME_LABEL = "nuclio.io/project-name"
33
33
 
34
34
 
35
35
  class APIGatewayAuthenticator(typing.Protocol):
36
36
  @property
37
37
  def authentication_mode(self) -> str:
38
- return NUCLIO_API_GATEWAY_AUTHENTICATION_MODE_NONE
38
+ return schemas.APIGatewayAuthenticationMode.none.value
39
39
 
40
40
  @classmethod
41
- def from_scheme(cls, api_gateway_spec: mlrun.common.schemas.APIGatewaySpec):
41
+ def from_scheme(cls, api_gateway_spec: schemas.APIGatewaySpec):
42
42
  if (
43
43
  api_gateway_spec.authenticationMode
44
- == NUCLIO_API_GATEWAY_AUTHENTICATION_MODE_BASIC_AUTH
44
+ == schemas.APIGatewayAuthenticationMode.basic.value
45
45
  ):
46
46
  if api_gateway_spec.authentication:
47
47
  return BasicAuth(
@@ -50,12 +50,17 @@ class APIGatewayAuthenticator(typing.Protocol):
50
50
  )
51
51
  else:
52
52
  return BasicAuth()
53
+ elif (
54
+ api_gateway_spec.authenticationMode
55
+ == schemas.APIGatewayAuthenticationMode.access_key.value
56
+ ):
57
+ return AccessKeyAuth()
53
58
  else:
54
59
  return NoneAuth()
55
60
 
56
61
  def to_scheme(
57
62
  self,
58
- ) -> Optional[dict[str, Optional[mlrun.common.schemas.APIGatewayBasicAuth]]]:
63
+ ) -> Optional[dict[str, Optional[schemas.APIGatewayBasicAuth]]]:
59
64
  return None
60
65
 
61
66
 
@@ -81,18 +86,28 @@ class BasicAuth(APIGatewayAuthenticator):
81
86
 
82
87
  @property
83
88
  def authentication_mode(self) -> str:
84
- return NUCLIO_API_GATEWAY_AUTHENTICATION_MODE_BASIC_AUTH
89
+ return schemas.APIGatewayAuthenticationMode.basic.value
85
90
 
86
91
  def to_scheme(
87
92
  self,
88
- ) -> Optional[dict[str, Optional[mlrun.common.schemas.APIGatewayBasicAuth]]]:
93
+ ) -> Optional[dict[str, Optional[schemas.APIGatewayBasicAuth]]]:
89
94
  return {
90
- "basicAuth": mlrun.common.schemas.APIGatewayBasicAuth(
95
+ "basicAuth": schemas.APIGatewayBasicAuth(
91
96
  username=self._username, password=self._password
92
97
  )
93
98
  }
94
99
 
95
100
 
101
+ class AccessKeyAuth(APIGatewayAuthenticator):
102
+ """
103
+ An API gateway authenticator with access key authentication.
104
+ """
105
+
106
+ @property
107
+ def authentication_mode(self) -> str:
108
+ return schemas.APIGatewayAuthenticationMode.access_key.value
109
+
110
+
96
111
  class APIGatewayMetadata(ModelObj):
97
112
  _dict_fields = ["name", "namespace", "labels", "annotations", "creation_timestamp"]
98
113
 
@@ -138,17 +153,17 @@ class APIGatewaySpec(ModelObj):
138
153
  def __init__(
139
154
  self,
140
155
  functions: Union[
141
- list[str],
142
- Union[
143
- list[
144
- Union[
145
- RemoteRuntime,
146
- ServingRuntime,
147
- ]
148
- ],
149
- RemoteRuntime,
150
- ServingRuntime,
156
+ list[
157
+ Union[
158
+ str,
159
+ "mlrun.runtimes.nuclio.function.RemoteRuntime",
160
+ "mlrun.runtimes.nuclio.serving.ServingRuntime",
161
+ "mlrun.runtimes.nuclio.application.ApplicationRuntime",
162
+ ]
151
163
  ],
164
+ "mlrun.runtimes.nuclio.function.RemoteRuntime",
165
+ "mlrun.runtimes.nuclio.serving.ServingRuntime",
166
+ "mlrun.runtimes.nuclio.application.ApplicationRuntime",
152
167
  ],
153
168
  project: str = None,
154
169
  description: str = "",
@@ -156,20 +171,24 @@ class APIGatewaySpec(ModelObj):
156
171
  path: str = "/",
157
172
  authentication: Optional[APIGatewayAuthenticator] = NoneAuth(),
158
173
  canary: Optional[list[int]] = None,
174
+ ports: Optional[list[int]] = None,
159
175
  ):
160
176
  """
161
177
  :param functions: The list of functions associated with the API gateway
162
178
  Can be a list of function names (["my-func1", "my-func2"])
163
179
  or a list or a single entity of
164
180
  :py:class:`~mlrun.runtimes.nuclio.function.RemoteRuntime` OR
165
- :py:class:`~mlrun.runtimes.nuclio.serving.ServingRuntime`
181
+ :py:class:`~mlrun.runtimes.nuclio.serving.ServingRuntime` OR
182
+ :py:class:`~mlrun.runtimes.nuclio.application.ApplicationRuntime`
166
183
  :param project: The project name
167
184
  :param description: Optional description of the API gateway
168
185
  :param path: Optional path of the API gateway, default value is "/"
169
186
  :param authentication: The authentication for the API gateway of type
170
187
  :py:class:`~mlrun.runtimes.nuclio.api_gateway.BasicAuth`
171
188
  :param host: The host of the API gateway (optional). If not set, it will be automatically generated
172
- :param canary: The canary percents for the API gateway of type list[int]; for instance: [20,80]
189
+ :param canary: The canary percents for the API gateway of type list[int]; for instance: [20,80] (optional)
190
+ :param ports: The ports of the API gateway, as a list of integers that correspond to the functions in the
191
+ functions list. for instance: [8050] or [8050, 8081] (optional)
173
192
  """
174
193
  self.description = description
175
194
  self.host = host
@@ -178,26 +197,28 @@ class APIGatewaySpec(ModelObj):
178
197
  self.functions = functions
179
198
  self.canary = canary
180
199
  self.project = project
200
+ self.ports = ports
181
201
 
182
- self.validate(project=project, functions=functions, canary=canary)
202
+ self.validate(project=project, functions=functions, canary=canary, ports=ports)
183
203
 
184
204
  def validate(
185
205
  self,
186
206
  project: str,
187
207
  functions: Union[
188
- list[str],
189
- Union[
190
- list[
191
- Union[
192
- RemoteRuntime,
193
- ServingRuntime,
194
- ]
195
- ],
196
- RemoteRuntime,
197
- ServingRuntime,
208
+ list[
209
+ Union[
210
+ str,
211
+ "mlrun.runtimes.nuclio.function.RemoteRuntime",
212
+ "mlrun.runtimes.nuclio.serving.ServingRuntime",
213
+ "mlrun.runtimes.nuclio.application.ApplicationRuntime",
214
+ ]
198
215
  ],
216
+ "mlrun.runtimes.nuclio.function.RemoteRuntime",
217
+ "mlrun.runtimes.nuclio.serving.ServingRuntime",
218
+ "mlrun.runtimes.nuclio.application.ApplicationRuntime",
199
219
  ],
200
220
  canary: Optional[list[int]] = None,
221
+ ports: Optional[list[int]] = None,
201
222
  ):
202
223
  self.functions = self._validate_functions(project=project, functions=functions)
203
224
 
@@ -205,6 +226,10 @@ class APIGatewaySpec(ModelObj):
205
226
  if canary:
206
227
  self.canary = self._validate_canary(canary)
207
228
 
229
+ # validating ports
230
+ if ports:
231
+ self.ports = self._validate_ports(ports)
232
+
208
233
  def _validate_canary(self, canary: list[int]):
209
234
  if len(self.functions) != len(canary):
210
235
  raise mlrun.errors.MLRunInvalidArgumentError(
@@ -221,20 +246,29 @@ class APIGatewaySpec(ModelObj):
221
246
  )
222
247
  return canary
223
248
 
249
+ def _validate_ports(self, ports):
250
+ if len(self.functions) != len(ports):
251
+ raise mlrun.errors.MLRunInvalidArgumentError(
252
+ "Function and port lists lengths do not match"
253
+ )
254
+
255
+ return ports
256
+
224
257
  @staticmethod
225
258
  def _validate_functions(
226
259
  project: str,
227
260
  functions: Union[
228
- list[str],
229
- Union[
230
- list[
231
- Union[
232
- RemoteRuntime,
233
- ServingRuntime,
234
- ]
235
- ],
236
- Union[RemoteRuntime, ServingRuntime],
261
+ list[
262
+ Union[
263
+ str,
264
+ "mlrun.runtimes.nuclio.function.RemoteRuntime",
265
+ "mlrun.runtimes.nuclio.serving.ServingRuntime",
266
+ "mlrun.runtimes.nuclio.application.ApplicationRuntime",
267
+ ]
237
268
  ],
269
+ "mlrun.runtimes.nuclio.function.RemoteRuntime",
270
+ "mlrun.runtimes.nuclio.serving.ServingRuntime",
271
+ "mlrun.runtimes.nuclio.application.ApplicationRuntime",
238
272
  ],
239
273
  ):
240
274
  if not isinstance(functions, list):
@@ -312,8 +346,9 @@ class APIGateway(ModelObj):
312
346
  def invoke(
313
347
  self,
314
348
  method="POST",
315
- headers: dict = {},
316
- auth: Optional[tuple[str, str]] = None,
349
+ headers: dict = None,
350
+ credentials: Optional[tuple[str, str]] = None,
351
+ path: Optional[str] = None,
317
352
  **kwargs,
318
353
  ):
319
354
  """
@@ -321,7 +356,9 @@ class APIGateway(ModelObj):
321
356
 
322
357
  :param method: (str, optional) The HTTP method for the invocation.
323
358
  :param headers: (dict, optional) The HTTP headers for the invocation.
324
- :param auth: (Optional[tuple[str, str]], optional) The authentication creds for the invocation if required.
359
+ :param credentials: (Optional[tuple[str, str]], optional) The (username,password) for the invocation if required
360
+ can also be set by the environment variable (_, V3IO_ACCESS_KEY) for access key authentication.
361
+ :param path: (str, optional) The sub-path for the invocation.
325
362
  :param kwargs: (dict) Additional keyword arguments.
326
363
 
327
364
  :return: The response from the API gateway invocation.
@@ -338,20 +375,44 @@ class APIGateway(ModelObj):
338
375
  f"API gateway is not ready. " f"Current state: {self.state}"
339
376
  )
340
377
 
378
+ auth = None
379
+
341
380
  if (
342
381
  self.spec.authentication.authentication_mode
343
- == NUCLIO_API_GATEWAY_AUTHENTICATION_MODE_BASIC_AUTH
344
- and not auth
382
+ == schemas.APIGatewayAuthenticationMode.basic.value
345
383
  ):
346
- raise mlrun.errors.MLRunInvalidArgumentError(
347
- "API Gateway invocation requires authentication. Please pass credentials"
348
- )
384
+ if not credentials:
385
+ raise mlrun.errors.MLRunInvalidArgumentError(
386
+ "API Gateway invocation requires authentication. Please pass credentials"
387
+ )
388
+ auth = NuclioAuthInfo(
389
+ username=credentials[0], password=credentials[1]
390
+ ).to_requests_auth()
391
+
392
+ if (
393
+ self.spec.authentication.authentication_mode
394
+ == schemas.APIGatewayAuthenticationMode.access_key.value
395
+ ):
396
+ # inject access key from env
397
+ if credentials:
398
+ auth = NuclioAuthInfo(
399
+ username=credentials[0],
400
+ password=credentials[1],
401
+ mode=NuclioAuthKinds.iguazio,
402
+ ).to_requests_auth()
403
+ else:
404
+ auth = NuclioAuthInfo().from_envvar().to_requests_auth()
405
+ if not auth:
406
+ raise mlrun.errors.MLRunInvalidArgumentError(
407
+ "API Gateway invocation requires authentication. Please set V3IO_ACCESS_KEY env var"
408
+ )
409
+ url = urljoin(self.invoke_url, path or "")
349
410
  return requests.request(
350
411
  method=method,
351
- url=self.invoke_url,
352
- headers=headers,
412
+ url=url,
413
+ headers=headers or {},
414
+ auth=auth,
353
415
  **kwargs,
354
- auth=HTTPBasicAuth(*auth) if auth else None,
355
416
  )
356
417
 
357
418
  def wait_for_readiness(self, max_wait_time=90):
@@ -376,10 +437,10 @@ class APIGateway(ModelObj):
376
437
  )
377
438
 
378
439
  def is_ready(self):
379
- if self.state is not mlrun.common.schemas.api_gateway.APIGatewayState.ready:
440
+ if self.state is not schemas.api_gateway.APIGatewayState.ready:
380
441
  # try to sync the state
381
442
  self.sync()
382
- return self.state == mlrun.common.schemas.api_gateway.APIGatewayState.ready
443
+ return self.state == schemas.api_gateway.APIGatewayState.ready
383
444
 
384
445
  def sync(self):
385
446
  """
@@ -407,16 +468,27 @@ class APIGateway(ModelObj):
407
468
  """
408
469
  self.spec.authentication = BasicAuth(username=username, password=password)
409
470
 
471
+ @min_iguazio_versions("3.5.5")
472
+ def with_access_key_auth(self):
473
+ """
474
+ Set access key authentication for the API gateway.
475
+ """
476
+ self.spec.authentication = AccessKeyAuth()
477
+
410
478
  def with_canary(
411
479
  self,
412
480
  functions: Union[
413
- list[str],
414
481
  list[
415
482
  Union[
416
- RemoteRuntime,
417
- ServingRuntime,
483
+ str,
484
+ "mlrun.runtimes.nuclio.function.RemoteRuntime",
485
+ "mlrun.runtimes.nuclio.serving.ServingRuntime",
486
+ "mlrun.runtimes.nuclio.application.ApplicationRuntime",
418
487
  ]
419
488
  ],
489
+ "mlrun.runtimes.nuclio.function.RemoteRuntime",
490
+ "mlrun.runtimes.nuclio.serving.ServingRuntime",
491
+ "mlrun.runtimes.nuclio.application.ApplicationRuntime",
420
492
  ],
421
493
  canary: list[int],
422
494
  ):
@@ -427,7 +499,8 @@ class APIGateway(ModelObj):
427
499
  Can be a list of function names (["my-func1", "my-func2"])
428
500
  or a list of nuclio functions of types
429
501
  :py:class:`~mlrun.runtimes.nuclio.function.RemoteRuntime` OR
430
- :py:class:`~mlrun.runtimes.nuclio.serving.ServingRuntime`
502
+ :py:class:`~mlrun.runtimes.nuclio.serving.ServingRuntime` OR
503
+ :py:class:`~mlrun.runtimes.nuclio.application.ApplicationRuntime`
431
504
  :param canary: The canary percents for the API gateway of type list[int]; for instance: [20,80]
432
505
 
433
506
  """
@@ -440,14 +513,25 @@ class APIGateway(ModelObj):
440
513
  project=self.spec.project, functions=functions, canary=canary
441
514
  )
442
515
 
516
+ def with_ports(self, ports: list[int]):
517
+ """
518
+ Set ports for the API gateway
519
+
520
+ :param ports: The ports of the API gateway, as a list of integers that correspond to the functions in the
521
+ functions list. for instance: [8050] or [8050, 8081]
522
+ """
523
+ self.spec.validate(
524
+ project=self.spec.project, functions=self.spec.functions, ports=ports
525
+ )
526
+
443
527
  @classmethod
444
- def from_scheme(cls, api_gateway: mlrun.common.schemas.APIGateway):
528
+ def from_scheme(cls, api_gateway: schemas.APIGateway):
445
529
  project = api_gateway.metadata.labels.get(PROJECT_NAME_LABEL)
446
530
  functions, canary = cls._resolve_canary(api_gateway.spec.upstreams)
447
531
  state = (
448
532
  api_gateway.status.state
449
533
  if api_gateway.status
450
- else mlrun.common.schemas.APIGatewayState.none
534
+ else schemas.APIGatewayState.none
451
535
  )
452
536
  new_api_gateway = cls(
453
537
  metadata=APIGatewayMetadata(
@@ -466,14 +550,14 @@ class APIGateway(ModelObj):
466
550
  new_api_gateway.state = state
467
551
  return new_api_gateway
468
552
 
469
- def to_scheme(self) -> mlrun.common.schemas.APIGateway:
553
+ def to_scheme(self) -> schemas.APIGateway:
470
554
  upstreams = (
471
555
  [
472
- mlrun.common.schemas.APIGatewayUpstream(
556
+ schemas.APIGatewayUpstream(
473
557
  nucliofunction={"name": self.spec.functions[0]},
474
558
  percentage=self.spec.canary[0],
475
559
  ),
476
- mlrun.common.schemas.APIGatewayUpstream(
560
+ schemas.APIGatewayUpstream(
477
561
  # do not set percent for the second function,
478
562
  # so we can define which function to display as a primary one in UI
479
563
  nucliofunction={"name": self.spec.functions[1]},
@@ -481,22 +565,24 @@ class APIGateway(ModelObj):
481
565
  ]
482
566
  if self.spec.canary
483
567
  else [
484
- mlrun.common.schemas.APIGatewayUpstream(
568
+ schemas.APIGatewayUpstream(
485
569
  nucliofunction={"name": function_name},
486
570
  )
487
571
  for function_name in self.spec.functions
488
572
  ]
489
573
  )
490
- api_gateway = mlrun.common.schemas.APIGateway(
491
- metadata=mlrun.common.schemas.APIGatewayMetadata(
492
- name=self.metadata.name, labels={}
493
- ),
494
- spec=mlrun.common.schemas.APIGatewaySpec(
574
+ if self.spec.ports:
575
+ for i, port in enumerate(self.spec.ports):
576
+ upstreams[i].port = port
577
+
578
+ api_gateway = schemas.APIGateway(
579
+ metadata=schemas.APIGatewayMetadata(name=self.metadata.name, labels={}),
580
+ spec=schemas.APIGatewaySpec(
495
581
  name=self.metadata.name,
496
582
  description=self.spec.description,
497
583
  host=self.spec.host,
498
584
  path=self.spec.path,
499
- authenticationMode=mlrun.common.schemas.APIGatewayAuthenticationMode.from_str(
585
+ authenticationMode=schemas.APIGatewayAuthenticationMode.from_str(
500
586
  self.spec.authentication.authentication_mode
501
587
  ),
502
588
  upstreams=upstreams,
@@ -526,7 +612,7 @@ class APIGateway(ModelObj):
526
612
 
527
613
  @staticmethod
528
614
  def _resolve_canary(
529
- upstreams: list[mlrun.common.schemas.APIGatewayUpstream],
615
+ upstreams: list[schemas.APIGatewayUpstream],
530
616
  ) -> tuple[Union[list[str], None], Union[list[int], None]]:
531
617
  if len(upstreams) == 1:
532
618
  return [upstreams[0].nucliofunction.get("name")], None