aioli-sdk 0.1.2.dev0__tar.gz → 0.2.0__tar.gz

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 (93) hide show
  1. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/PKG-INFO +1 -1
  2. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/__version__.py +1 -1
  3. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/cli.py +0 -2
  4. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/deployment.py +112 -24
  5. aioli-sdk-0.2.0/aioli/cli/model.py +433 -0
  6. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/registry.py +80 -8
  7. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/render.py +23 -1
  8. aioli-sdk-0.2.0/aioli/cli/test/test_cli.py +599 -0
  9. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli_sdk.egg-info/PKG-INFO +1 -1
  10. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli_sdk.egg-info/SOURCES.txt +10 -9
  11. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/__init__.py +13 -11
  12. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/api/__init__.py +2 -2
  13. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/api/authentication_api.py +3 -3
  14. aioli-sdk-0.1.2.dev0/aiolirest/api/services_api.py → aioli-sdk-0.2.0/aiolirest/api/deployments_api.py +474 -201
  15. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/api/information_api.py +3 -3
  16. aioli-sdk-0.1.2.dev0/aiolirest/api/models_api.py → aioli-sdk-0.2.0/aiolirest/api/packaged_models_api.py +955 -101
  17. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/api/registries_api.py +6 -6
  18. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/api/roles_api.py +3 -3
  19. aioli-sdk-0.2.0/aiolirest/api/templates_api.py +2746 -0
  20. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/api/users_api.py +3 -3
  21. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/api_client.py +3 -3
  22. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/configuration.py +4 -4
  23. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/exceptions.py +3 -3
  24. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/__init__.py +11 -9
  25. aioli-sdk-0.2.0/aiolirest/models/auto_scaling_template.py +97 -0
  26. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/autoscaling.py +3 -3
  27. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/configuration_resources.py +4 -4
  28. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/deployment.py +25 -11
  29. aioli-sdk-0.1.2.dev0/aiolirest/models/service_model_version.py → aioli-sdk-0.2.0/aiolirest/models/deployment_model_version.py +13 -11
  30. aioli-sdk-0.1.2.dev0/aiolirest/models/service_request.py → aioli-sdk-0.2.0/aiolirest/models/deployment_request.py +20 -18
  31. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/deployment_state.py +4 -4
  32. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/error_response.py +3 -3
  33. aioli-sdk-0.2.0/aiolirest/models/event_info.py +95 -0
  34. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/failure_info.py +4 -4
  35. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/login_request.py +3 -3
  36. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/login_response.py +3 -3
  37. aioli-sdk-0.1.2.dev0/aiolirest/models/service_auth_token.py → aioli-sdk-0.2.0/aiolirest/models/model_auth_token.py +6 -6
  38. aioli-sdk-0.2.0/aiolirest/models/observability.py +91 -0
  39. aioli-sdk-0.1.2.dev0/aiolirest/models/trained_model.py → aioli-sdk-0.2.0/aiolirest/models/packaged_model.py +33 -11
  40. aioli-sdk-0.2.0/aiolirest/models/packaged_model_request.py +119 -0
  41. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/resource_profile.py +3 -3
  42. aioli-sdk-0.1.2.dev0/aiolirest/models/deployment_request.py → aioli-sdk-0.2.0/aiolirest/models/resources_template.py +17 -19
  43. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/role.py +3 -3
  44. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/role_assignment.py +3 -3
  45. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/role_assignments.py +3 -3
  46. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/security.py +3 -3
  47. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/success_response.py +3 -3
  48. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/trained_model_registry.py +12 -12
  49. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/trained_model_registry_request.py +16 -14
  50. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/user.py +3 -3
  51. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/user_patch_request.py +3 -3
  52. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/models/user_request.py +3 -3
  53. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/rest.py +3 -3
  54. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/setup.py +1 -1
  55. aioli-sdk-0.1.2.dev0/aioli/cli/model.py +0 -198
  56. aioli-sdk-0.1.2.dev0/aioli/cli/service.py +0 -425
  57. aioli-sdk-0.1.2.dev0/aioli/cli/test/test_cli.py +0 -457
  58. aioli-sdk-0.1.2.dev0/aiolirest/api/deployments_api.py +0 -1405
  59. aioli-sdk-0.1.2.dev0/aiolirest/models/service.py +0 -115
  60. aioli-sdk-0.1.2.dev0/aiolirest/models/trained_model_request.py +0 -97
  61. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/README.md +0 -0
  62. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/__init__.py +0 -0
  63. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/__init__.py +0 -0
  64. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/__main__.py +0 -0
  65. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/_util.py +0 -0
  66. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/errors.py +0 -0
  67. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/role.py +0 -0
  68. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/sso.py +0 -0
  69. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/test/conftest.py +0 -0
  70. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/user.py +0 -0
  71. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/cli/version.py +0 -0
  72. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/__init__.py +0 -0
  73. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/api/__init__.py +0 -0
  74. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/api/_util.py +0 -0
  75. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/api/authentication.py +0 -0
  76. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/api/certs.py +0 -0
  77. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/api/errors.py +0 -0
  78. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/api/request.py +0 -0
  79. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/check.py +0 -0
  80. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/constants.py +0 -0
  81. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/declarative_argparse.py +0 -0
  82. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/requests.py +0 -0
  83. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/common/util.py +0 -0
  84. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli/util.py +0 -0
  85. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli_sdk.egg-info/dependency_links.txt +0 -0
  86. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli_sdk.egg-info/entry_points.txt +0 -0
  87. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli_sdk.egg-info/not-zip-safe +0 -0
  88. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli_sdk.egg-info/requires.txt +0 -0
  89. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aioli_sdk.egg-info/top_level.txt +0 -0
  90. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/api_response.py +0 -0
  91. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/aiolirest/py.typed +0 -0
  92. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/pyproject.toml +0 -0
  93. {aioli-sdk-0.1.2.dev0 → aioli-sdk-0.2.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: aioli-sdk
3
- Version: 0.1.2.dev0
3
+ Version: 0.2.0
4
4
  Summary: Aioli (AI OnLine Inference), a platform for deploying AI models at scale.
5
5
  Home-page: https://github.com/determined-ai/aioli
6
6
  Author: HPE AI Solutions
@@ -1,2 +1,2 @@
1
1
  # © Copyright 2024 Hewlett Packard Enterprise Development LP
2
- __version__ = "0.1.2-dev0"
2
+ __version__ = "0.2.0"
@@ -20,7 +20,6 @@ from aioli.cli.deployment import args_description as deployment_args_description
20
20
  from aioli.cli.model import args_description as model_args_description
21
21
  from aioli.cli.registry import args_description as registry_args_description
22
22
  from aioli.cli.role import args_description as role_args_description
23
- from aioli.cli.service import args_description as service_args_description
24
23
  from aioli.cli.sso import args_description as sso_args_description
25
24
  from aioli.cli.user import args_description as user_args_description
26
25
  from aioli.cli.version import args_description as version_args_description
@@ -55,7 +54,6 @@ all_args_description: ArgsDescription = (
55
54
  args_description
56
55
  + registry_args_description
57
56
  + model_args_description
58
- + service_args_description
59
57
  + deployment_args_description
60
58
  + version_args_description
61
59
  + user_args_description
@@ -5,9 +5,11 @@ from typing import Any, List
5
5
  import aiolirest
6
6
  from aioli import cli
7
7
  from aioli.cli import render
8
+ from aioli.common import api
8
9
  from aioli.common.api import authentication
9
10
  from aioli.common.api.errors import NotFoundException
10
- from aioli.common.declarative_argparse import Arg, ArgsDescription, Cmd
11
+ from aioli.common.declarative_argparse import Arg, ArgsDescription, Cmd, Group
12
+ from aiolirest.models.autoscaling import Autoscaling
11
13
  from aiolirest.models.deployment import Deployment, DeploymentState
12
14
  from aiolirest.models.deployment_request import DeploymentRequest
13
15
  from aiolirest.models.security import Security
@@ -20,14 +22,17 @@ def show_deployment(args: Namespace) -> None:
20
22
 
21
23
  deployment = lookup_deployment(args.name, api_instance)
22
24
 
23
- # For a more useful display, replace the service ID with its name
24
- services_api = aiolirest.ServicesApi(session)
25
- deployment.service = services_api.services_id_get(deployment.service).name
25
+ # For a more useful display, replace the model ID with its name
26
+ packaged_models_api = aiolirest.PackagedModelsApi(session)
27
+ deployment.model = packaged_models_api.models_id_get(deployment.model).name
26
28
 
27
29
  d = deployment.to_dict()
28
30
  # Remove clusterName for now - INF-243
29
31
  d.pop("clusterName")
30
- print(render.format_object_as_yaml(d))
32
+ if args.json:
33
+ render.print_json(d)
34
+ else:
35
+ print(render.format_object_as_yaml(d))
31
36
 
32
37
 
33
38
  @authentication.required
@@ -36,9 +41,39 @@ def list_deployments(args: Namespace) -> None:
36
41
  api_instance = aiolirest.DeploymentsApi(session)
37
42
  response = api_instance.deployments_get()
38
43
 
39
- def format_deployment(e: Deployment, reg_api: aiolirest.ServicesApi) -> List[Any]:
40
- service = reg_api.services_id_get(e.service)
41
-
44
+ model_api = aiolirest.PackagedModelsApi(session)
45
+
46
+ if args.json:
47
+ format_json(response, model_api)
48
+ else:
49
+ format_deployments(response, args, model_api)
50
+
51
+
52
+ def format_json(response: List[Deployment], model_api: aiolirest.PackagedModelsApi) -> None:
53
+ deps = []
54
+ for d in response:
55
+ # Don't use the d.to_json() method as it adds backslash escapes for double quote
56
+ m_dict = d.to_dict()
57
+ m_dict.pop("id")
58
+ m_dict.pop("modifiedAt")
59
+ # Use model name instead of id
60
+ model = model_api.models_id_get(d.model)
61
+ m_dict["model"] = model.name
62
+ # Remove pop as part of INF-503
63
+ m_dict.pop("service", None)
64
+ m_dict.pop("clusterName", None)
65
+ deps.append(m_dict)
66
+
67
+ render.print_json(deps)
68
+
69
+
70
+ def format_deployments(
71
+ response: List[Deployment],
72
+ args: Namespace,
73
+ packaged_models_api: aiolirest.PackagedModelsApi,
74
+ ) -> None:
75
+ def format_deployment(e: Deployment, models_api: aiolirest.PackagedModelsApi) -> List[Any]:
76
+ model = models_api.models_id_get(e.model)
42
77
  state = e.state
43
78
  if state is None:
44
79
  state = DeploymentState()
@@ -49,33 +84,32 @@ def list_deployments(args: Namespace) -> None:
49
84
 
50
85
  assert e.security is not None
51
86
 
87
+ auto_scaling = e.auto_scaling
88
+ if auto_scaling is None:
89
+ auto_scaling = Autoscaling()
90
+
52
91
  result = [
53
92
  e.name,
54
- service.name,
93
+ model.name,
55
94
  e.namespace,
56
95
  e.status,
57
96
  e.security.authentication_required,
58
97
  state.status,
59
98
  state.traffic_percentage,
60
- secondary_state.status,
61
- secondary_state.traffic_percentage,
62
99
  ]
63
100
 
64
101
  return result
65
102
 
66
103
  headers = [
67
104
  "Name",
68
- "Service",
105
+ "Model",
69
106
  "Namespace",
70
107
  "Status",
71
108
  "Auth Required",
72
109
  "State",
73
110
  "Traffic %",
74
- "Secondary State",
75
- "Traffic %",
76
111
  ]
77
- services_api = aiolirest.ServicesApi(session)
78
- values = [format_deployment(r, services_api) for r in response]
112
+ values = [format_deployment(r, packaged_models_api) for r in response]
79
113
  render.tabulate_or_csv(headers, values, args.csv)
80
114
 
81
115
 
@@ -88,13 +122,27 @@ def create(args: Namespace) -> None:
88
122
  val = args.authentication_required.lower() == "true"
89
123
  sec.authentication_required = val
90
124
 
125
+ auto = Autoscaling(
126
+ metric=args.autoscaling_metric,
127
+ )
128
+
129
+ if args.autoscaling_target is not None:
130
+ auto.target = args.autoscaling_target
131
+
132
+ if args.autoscaling_max_replicas is not None:
133
+ auto.max_replicas = args.autoscaling_max_replicas
134
+
135
+ if args.autoscaling_min_replicas is not None:
136
+ auto.min_replicas = args.autoscaling_min_replicas
137
+
91
138
  r = DeploymentRequest(
92
139
  name=args.name,
93
- service=args.service,
140
+ model=args.model,
94
141
  security=sec,
95
142
  namespace=args.namespace,
143
+ autoScaling=auto,
144
+ canaryTrafficPercent=args.canary_traffic_percent,
96
145
  )
97
-
98
146
  api_instance.deployments_post(r)
99
147
 
100
148
 
@@ -114,18 +162,39 @@ def update(args: Namespace) -> None:
114
162
  name=found.name,
115
163
  namespace=found.namespace,
116
164
  security=found.security,
117
- service=found.service,
165
+ model=found.model,
166
+ autoScaling=found.auto_scaling,
167
+ canaryTrafficPercent=found.canary_traffic_percent,
118
168
  )
119
169
 
170
+ if request.auto_scaling is None:
171
+ # Not likely, but testing these prevents complaints from mypy
172
+ raise api.errors.BadResponseException("Unexpected null result")
173
+
120
174
  if args.name is not None:
121
175
  request.name = args.name
122
176
 
123
- if args.service is not None:
124
- request.service = args.service
177
+ if args.model is not None:
178
+ request.model = args.model
125
179
 
126
180
  if args.namespace is not None:
127
181
  request.namespace = args.namespace
128
182
 
183
+ if args.autoscaling_min_replicas is not None:
184
+ request.auto_scaling.min_replicas = args.autoscaling_min_replicas
185
+
186
+ if args.autoscaling_max_replicas is not None:
187
+ request.auto_scaling.max_replicas = args.autoscaling_max_replicas
188
+
189
+ if args.autoscaling_metric is not None:
190
+ request.auto_scaling.metric = args.autoscaling_metric
191
+
192
+ if args.autoscaling_target is not None:
193
+ request.auto_scaling.target = args.autoscaling_target
194
+
195
+ if args.canary_traffic_percent is not None:
196
+ request.canary_traffic_percent = args.canary_traffic_percent
197
+
129
198
  assert request.security is not None
130
199
 
131
200
  if args.authentication_required is not None:
@@ -149,9 +218,23 @@ def delete_deployment(args: Namespace) -> None:
149
218
  common_deployment_args: ArgsDescription = [
150
219
  Arg(
151
220
  "--authentication-required",
152
- help="Deployed service requires callers to provide authentication",
221
+ help="Deployed model requires callers to provide authentication",
153
222
  ),
154
223
  Arg("--namespace", help="The Kubernetes namespace to be used for the deployment"),
224
+ Arg("--autoscaling-min-replicas", help="Minimum number of replicas", type=int),
225
+ Arg(
226
+ "--autoscaling-max-replicas",
227
+ help="Maximum number of replicas created based upon demand",
228
+ type=int,
229
+ ),
230
+ Arg("--autoscaling-metric", help="Metric name which controls autoscaling"),
231
+ Arg("--autoscaling-target", help="Metric target value", type=int),
232
+ Arg(
233
+ "--canary-traffic-percent",
234
+ help="Percent traffic to pass to new model version",
235
+ type=int,
236
+ default=100,
237
+ ),
155
238
  ]
156
239
 
157
240
  main_cmd = Cmd(
@@ -166,6 +249,7 @@ main_cmd = Cmd(
166
249
  "list deployments",
167
250
  [
168
251
  Arg("--csv", action="store_true", help="print as CSV"),
252
+ Arg("--json", action="store_true", help="print as JSON"),
169
253
  ],
170
254
  is_default=True,
171
255
  ),
@@ -180,7 +264,7 @@ main_cmd = Cmd(
180
264
  help="The name of the deployment. Must begin with a letter, but may contain "
181
265
  "letters, numbers, underscore, and hyphen",
182
266
  ),
183
- Arg("--service", help="Service name or ID to be deployed", required="true"),
267
+ Arg("--model", help="Model to be deployed", required="true"),
184
268
  ]
185
269
  + common_deployment_args,
186
270
  ),
@@ -194,6 +278,10 @@ main_cmd = Cmd(
194
278
  "name",
195
279
  help="The name of the deployment.",
196
280
  ),
281
+ Group(
282
+ Arg("--yaml", action="store_true", help="print as YAML", default=True),
283
+ Arg("--json", action="store_true", help="print as JSON"),
284
+ ),
197
285
  ],
198
286
  ),
199
287
  # Update command
@@ -208,7 +296,7 @@ main_cmd = Cmd(
208
296
  help="The new name of the deployment. Must begin with a letter, but may "
209
297
  "contain letters, numbers, underscore, and hyphen",
210
298
  ),
211
- Arg("--service", help="Service name or ID to be deployed"),
299
+ Arg("--model", help="Model to be deployed", required="true"),
212
300
  ]
213
301
  + common_deployment_args,
214
302
  ),