thestage 0.6.4__py3-none-any.whl → 0.6.6__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 (73) hide show
  1. thestage/__init__.py +1 -1
  2. thestage/color_scheme/color_scheme.py +1 -0
  3. thestage/controllers/base_controller.py +4 -3
  4. thestage/controllers/config_controller.py +16 -4
  5. thestage/controllers/container_controller.py +147 -49
  6. thestage/controllers/instance_controller.py +35 -9
  7. thestage/controllers/project_controller.py +334 -86
  8. thestage/entities/container.py +5 -3
  9. thestage/entities/project_inference_simulator.py +2 -1
  10. thestage/entities/project_inference_simulator_model.py +1 -1
  11. thestage/entities/project_task.py +2 -3
  12. thestage/entities/rented_instance.py +2 -2
  13. thestage/entities/self_hosted_instance.py +2 -2
  14. thestage/helpers/error_handler.py +3 -3
  15. thestage/services/clients/git/git_client.py +8 -12
  16. thestage/services/clients/thestage_api/api_client.py +144 -109
  17. thestage/services/clients/thestage_api/dtos/base_controller/connect_resolve_response.py +21 -0
  18. thestage/services/clients/thestage_api/dtos/container_param_request.py +1 -1
  19. thestage/services/clients/thestage_api/dtos/container_response.py +1 -21
  20. thestage/services/clients/thestage_api/dtos/docker_container_controller/docker_container_list_request.py +2 -1
  21. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_request.py +7 -1
  22. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_response.py +0 -1
  23. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_sagemaker_request.py +1 -0
  24. thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_request.py +2 -1
  25. thestage/services/clients/thestage_api/dtos/inference_controller/{inference_simulator_list_for_project_request.py → inference_simulator_list_request.py} +3 -2
  26. thestage/services/clients/thestage_api/dtos/inference_controller/{inference_simulator_list_for_project_response.py → inference_simulator_list_response.py} +1 -1
  27. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_model_list_for_project_request.py +2 -1
  28. thestage/services/clients/thestage_api/dtos/instance_rented_response.py +4 -37
  29. thestage/services/clients/thestage_api/dtos/logging_controller/log_polling_request.py +3 -3
  30. thestage/services/clients/thestage_api/dtos/logging_controller/user_logs_query_request.py +3 -11
  31. thestage/services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_request.py +1 -0
  32. thestage/services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_request.py +2 -1
  33. thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_request.py +2 -4
  34. thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_request.py +5 -3
  35. thestage/services/clients/thestage_api/dtos/project_response.py +3 -15
  36. thestage/services/clients/thestage_api/dtos/selfhosted_instance_response.py +2 -20
  37. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_key_to_user_response.py +1 -1
  38. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_public_key_to_instance_request.py +4 -2
  39. thestage/services/clients/thestage_api/dtos/ssh_key_controller/is_user_has_public_ssh_key_response.py +1 -1
  40. thestage/services/clients/thestage_api/dtos/task_controller/task_list_for_project_request.py +4 -1
  41. thestage/services/clients/thestage_api/dtos/task_controller/task_view_response.py +0 -2
  42. thestage/services/config_provider/config_provider.py +2 -2
  43. thestage/services/connect/connect_service.py +76 -73
  44. thestage/services/container/container_service.py +23 -19
  45. thestage/services/container/mapper/container_mapper.py +2 -1
  46. thestage/services/instance/instance_service.py +13 -20
  47. thestage/services/instance/mapper/instance_mapper.py +1 -3
  48. thestage/services/instance/mapper/selfhosted_mapper.py +3 -4
  49. thestage/services/logging/logging_service.py +40 -40
  50. thestage/services/project/dto/inference_simulator_dto.py +1 -10
  51. thestage/services/project/dto/inference_simulator_model_dto.py +2 -10
  52. thestage/services/project/dto/project_config.py +3 -2
  53. thestage/services/project/mapper/project_inference_simulator_mapper.py +1 -0
  54. thestage/services/project/mapper/project_inference_simulator_model_mapper.py +3 -3
  55. thestage/services/project/mapper/project_task_mapper.py +2 -3
  56. thestage/services/project/project_service.py +161 -131
  57. thestage/services/remote_server_service.py +1 -0
  58. thestage/services/task/dto/task_dto.py +3 -23
  59. {thestage-0.6.4.dist-info → thestage-0.6.6.dist-info}/METADATA +3 -2
  60. {thestage-0.6.4.dist-info → thestage-0.6.6.dist-info}/RECORD +63 -72
  61. {thestage-0.6.4.dist-info → thestage-0.6.6.dist-info}/WHEEL +1 -1
  62. thestage/services/clients/thestage_api/dtos/cloud_provider_region.py +0 -19
  63. thestage/services/clients/thestage_api/dtos/docker_container_assigned_device.py +0 -10
  64. thestage/services/clients/thestage_api/dtos/enums/currency_type.py +0 -10
  65. thestage/services/clients/thestage_api/dtos/enums/daemon_status.py +0 -9
  66. thestage/services/clients/thestage_api/dtos/enums/disk_type.py +0 -7
  67. thestage/services/clients/thestage_api/dtos/enums/drive_type.py +0 -7
  68. thestage/services/clients/thestage_api/dtos/enums/instance_type.py +0 -7
  69. thestage/services/clients/thestage_api/dtos/enums/location_region.py +0 -11
  70. thestage/services/clients/thestage_api/dtos/enums/power_status.py +0 -10
  71. thestage/services/clients/thestage_api/dtos/price_definition.py +0 -14
  72. {thestage-0.6.4.dist-info → thestage-0.6.6.dist-info}/entry_points.txt +0 -0
  73. {thestage-0.6.4.dist-info → thestage-0.6.6.dist-info/licenses}/LICENSE.txt +0 -0
@@ -4,6 +4,8 @@ import httpx
4
4
 
5
5
  from thestage.helpers.error_handler import error_handler
6
6
  from thestage.services.clients.thestage_api.core.api_client_core import TheStageApiClientCore
7
+ from thestage.services.clients.thestage_api.dtos.base_controller.connect_resolve_response import \
8
+ ConnectResolveOptionsResponse
7
9
  from thestage.services.clients.thestage_api.dtos.docker_container_controller.docker_container_list_request import \
8
10
  DockerContainerListRequest
9
11
  from thestage.services.clients.thestage_api.dtos.docker_container_controller.docker_container_list_response import \
@@ -21,10 +23,10 @@ from thestage.services.clients.thestage_api.dtos.inference_controller.get_infere
21
23
  GetInferenceSimulatorRequest
22
24
  from thestage.services.clients.thestage_api.dtos.inference_controller.get_inference_simulator_response import \
23
25
  GetInferenceSimulatorResponse
24
- from thestage.services.clients.thestage_api.dtos.inference_controller.inference_simulator_list_for_project_request import \
25
- InferenceSimulatorListForProjectRequest
26
- from thestage.services.clients.thestage_api.dtos.inference_controller.inference_simulator_list_for_project_response import \
27
- InferenceSimulatorListForProjectResponse
26
+ from thestage.services.clients.thestage_api.dtos.inference_controller.inference_simulator_list_request import \
27
+ InferenceSimulatorListRequest
28
+ from thestage.services.clients.thestage_api.dtos.inference_controller.inference_simulator_list_response import \
29
+ InferenceSimulatorListResponse
28
30
  from thestage.services.clients.thestage_api.dtos.inference_controller.inference_simulator_model_list_for_project_request import \
29
31
  InferenceSimulatorModelListForProjectRequest
30
32
  from thestage.services.clients.thestage_api.dtos.inference_controller.inference_simulator_model_list_for_project_response import \
@@ -104,15 +106,15 @@ class TheStageApiClient(TheStageApiClientCore):
104
106
 
105
107
  def get_task(
106
108
  self,
107
- task_id: int,
109
+ task_public_id: str,
108
110
  ) -> Optional[TaskViewResponse]:
109
111
  data = {
110
- "taskId": task_id,
112
+ "taskPublicId": task_public_id,
111
113
  }
112
114
 
113
115
  response = self._request(
114
116
  method='POST',
115
- url='/user-api/v1/task/view',
117
+ url='/user-api/v2/task/view',
116
118
  data=data,
117
119
  token=self.__config_provider.get_config().main.thestage_auth_token,
118
120
  )
@@ -122,14 +124,16 @@ class TheStageApiClient(TheStageApiClientCore):
122
124
 
123
125
  def get_task_list_for_project(
124
126
  self,
125
- project_slug: str,
127
+ project_public_id: Optional[str],
128
+ project_slug: Optional[str],
126
129
  page: int = 1,
127
130
  limit: int = 10,
128
131
  ) -> Optional[PaginatedEntityList[TaskDto]]:
129
132
  request = TaskListForProjectRequest(
133
+ projectPublicId=project_public_id,
130
134
  projectSlug=project_slug,
131
135
  entityFilterRequest=EntityFilterRequest(
132
- orderByField="id",
136
+ orderByField="createdAt",
133
137
  orderByDirection=OrderDirectionType.DESC,
134
138
  page=page,
135
139
  limit=limit,
@@ -138,7 +142,7 @@ class TheStageApiClient(TheStageApiClientCore):
138
142
 
139
143
  response = self._request(
140
144
  method='POST',
141
- url='/user-api/v1/task/list-for-project',
145
+ url='/user-api/v2/task/list',
142
146
  data=request.model_dump(),
143
147
  token=self.__config_provider.get_config().main.thestage_auth_token,
144
148
  )
@@ -146,18 +150,20 @@ class TheStageApiClient(TheStageApiClientCore):
146
150
  result = TaskListForProjectResponse.model_validate(response) if response else None
147
151
  return result.tasks if result and result.is_success else None
148
152
 
149
- def get_inference_simulator_list_for_project(
153
+ def get_inference_simulator_list(
150
154
  self,
151
- project_slug: str,
155
+ project_public_id: Optional[str],
156
+ project_slug: Optional[str],
152
157
  statuses: List[str] = [],
153
158
  page: int = 1,
154
159
  limit: int = 10,
155
160
  ) -> Optional[PaginatedEntityList[InferenceSimulatorDto]]:
156
- request = InferenceSimulatorListForProjectRequest(
161
+ request = InferenceSimulatorListRequest(
162
+ projectPublicId=project_public_id,
157
163
  projectSlug=project_slug,
158
164
  statuses=statuses,
159
165
  entityFilterRequest=EntityFilterRequest(
160
- orderByField="id",
166
+ orderByField="createdAt",
161
167
  orderByDirection=OrderDirectionType.DESC,
162
168
  page=page,
163
169
  limit=limit,
@@ -166,25 +172,27 @@ class TheStageApiClient(TheStageApiClientCore):
166
172
 
167
173
  response = self._request(
168
174
  method='POST',
169
- url='/user-api/v1/project/inference-simulator/list',
175
+ url='/user-api/v2/inference-simulator/list',
170
176
  data=request.model_dump(),
171
177
  token=self.__config_provider.get_config().main.thestage_auth_token,
172
178
  )
173
- result = InferenceSimulatorListForProjectResponse.model_validate(response) if response else None
179
+ result = InferenceSimulatorListResponse.model_validate(response) if response else None
174
180
  return result.inferenceSimulators if result and result.is_success else None
175
181
 
176
182
  def get_inference_simulator_model_list_for_project(
177
183
  self,
178
- project_slug: str,
184
+ project_public_id: Optional[str],
185
+ project_slug: Optional[str],
179
186
  statuses: Optional[List[str]] = None,
180
187
  page: int = 1,
181
188
  limit: int = 10,
182
189
  ) -> Optional[PaginatedEntityList[InferenceSimulatorModelDto]]:
183
190
  request = InferenceSimulatorModelListForProjectRequest(
191
+ projectPublicId=project_public_id,
184
192
  projectSlug=project_slug,
185
193
  statuses=statuses,
186
194
  entityFilterRequest=EntityFilterRequest(
187
- orderByField="id",
195
+ orderByField="createdAt",
188
196
  orderByDirection=OrderDirectionType.DESC,
189
197
  page=page,
190
198
  limit=limit,
@@ -193,7 +201,7 @@ class TheStageApiClient(TheStageApiClientCore):
193
201
 
194
202
  response = self._request(
195
203
  method='POST',
196
- url='/user-api/v1/project/inference-simulator-model/list',
204
+ url='/user-api/v2/inference-simulator-model/list',
197
205
  data=request.model_dump(),
198
206
  token=self.__config_provider.get_config().main.thestage_auth_token,
199
207
  )
@@ -203,19 +211,17 @@ class TheStageApiClient(TheStageApiClientCore):
203
211
  def get_rented_instance_list(
204
212
  self,
205
213
  statuses: List[str],
206
- query: Optional[str] = None,
207
214
  page: int = 1,
208
215
  limit: int = 10,
209
216
  ) -> PaginatedEntityList[InstanceRentedDto]:
210
217
  data = {
211
218
  #"statuses": [item.value for item in statuses],
212
219
  "entityFilterRequest": {
213
- "orderByField": "id",
220
+ "orderByField": "createdAt",
214
221
  "orderByDirection": "DESC",
215
222
  "page": page,
216
223
  "limit": limit
217
224
  },
218
- "queryString": query
219
225
  }
220
226
 
221
227
  if statuses:
@@ -223,7 +229,7 @@ class TheStageApiClient(TheStageApiClientCore):
223
229
 
224
230
  response = self._request(
225
231
  method='POST',
226
- url='/user-api/v2/instance-rented/list',
232
+ url='/user-api/v3/instance-rented/list',
227
233
  data=data,
228
234
  token=self.__config_provider.get_config().main.thestage_auth_token,
229
235
  )
@@ -257,19 +263,20 @@ class TheStageApiClient(TheStageApiClientCore):
257
263
 
258
264
  def get_rented_instance(
259
265
  self,
266
+ instance_public_id: Optional[str] = None,
260
267
  instance_slug: Optional[str] = None,
261
- instance_id: Optional[int] = None,
262
268
  ) -> Optional[InstanceRentedDto]:
263
- if not instance_slug and not instance_id:
269
+ if not instance_slug and not instance_public_id:
264
270
  return None
265
271
 
266
272
  data = {
273
+ "instanceRentedPublicId": instance_public_id,
267
274
  "instanceRentedSlug": instance_slug,
268
275
  }
269
276
 
270
277
  response = self._request(
271
278
  method='POST',
272
- url='/user-api/v2/instance-rented/view-by-slug',
279
+ url='/user-api/v3/instance-rented/view',
273
280
  data=data,
274
281
  token=self.__config_provider.get_config().main.thestage_auth_token,
275
282
  )
@@ -278,19 +285,20 @@ class TheStageApiClient(TheStageApiClientCore):
278
285
 
279
286
  def get_selfhosted_instance(
280
287
  self,
288
+ instance_public_id: Optional[str] = None,
281
289
  instance_slug: Optional[str] = None,
282
- instance_id: Optional[int] = None,
283
290
  ) -> Optional[SelfHostedInstanceDto]:
284
- if not instance_slug and not instance_id:
291
+ if not instance_slug and not instance_public_id:
285
292
  return None
286
293
 
287
294
  data = {
295
+ "selfhostedInstancePublicId": instance_public_id,
288
296
  "selfhostedInstanceSlug": instance_slug,
289
297
  }
290
298
 
291
299
  response = self._request(
292
300
  method='POST',
293
- url='/user-api/v2/self-hosted-instance/view-by-slug',
301
+ url='/user-api/v3/self-hosted-instance/view',
294
302
  data=data,
295
303
  token=self.__config_provider.get_config().main.thestage_auth_token,
296
304
  )
@@ -300,19 +308,16 @@ class TheStageApiClient(TheStageApiClientCore):
300
308
  def get_selfhosted_instance_list(
301
309
  self,
302
310
  statuses: List[str],
303
- query: Optional[str] = None,
304
311
  page: int = 1,
305
312
  limit: int = 10,
306
313
  ) -> PaginatedEntityList[SelfHostedInstanceDto]:
307
314
  data = {
308
- #"statuses": [item.value for item in statuses] if statuses else [],
309
315
  "entityFilterRequest": {
310
- "orderByField": "id",
316
+ "orderByField": "createdAt",
311
317
  "orderByDirection": "DESC",
312
318
  "page": page,
313
319
  "limit": limit
314
- },
315
- "queryString": query
320
+ }
316
321
  }
317
322
 
318
323
  if statuses:
@@ -320,7 +325,7 @@ class TheStageApiClient(TheStageApiClientCore):
320
325
 
321
326
  response = self._request(
322
327
  method='POST',
323
- url='/user-api/v2/self-hosted-instance/list',
328
+ url='/user-api/v3/self-hosted-instance/list',
324
329
  data=data,
325
330
  token=self.__config_provider.get_config().main.thestage_auth_token,
326
331
  )
@@ -342,15 +347,15 @@ class TheStageApiClient(TheStageApiClientCore):
342
347
 
343
348
  def cancel_task(
344
349
  self,
345
- task_id: int,
350
+ task_public_id: str,
346
351
  ) -> Optional[TheStageBaseResponse]:
347
352
  data = {
348
- "taskId": task_id,
353
+ "taskPublicId": task_public_id,
349
354
  }
350
355
 
351
356
  response = self._request(
352
357
  method='POST',
353
- url='/user-api/v1/task/cancel-task',
358
+ url='/user-api/v2/task/cancel',
354
359
  data=data,
355
360
  token=self.__config_provider.get_config().main.thestage_auth_token,
356
361
  )
@@ -360,16 +365,18 @@ class TheStageApiClient(TheStageApiClientCore):
360
365
 
361
366
  def get_container_list(
362
367
  self,
363
- project_id: Optional[int] = None,
368
+ project_public_id: Optional[str] = None,
369
+ project_slug: Optional[str] = None,
364
370
  statuses: List[str] = [],
365
371
  page: int = 1,
366
372
  limit: int = 10,
367
373
  ) -> PaginatedEntityList[DockerContainerDto]:
368
374
  request = DockerContainerListRequest(
369
375
  statuses=statuses,
370
- projectId=project_id,
376
+ projectPublicId=project_public_id,
377
+ projectSlug=project_slug,
371
378
  entityFilterRequest=EntityFilterRequest(
372
- orderByField="id",
379
+ orderByField="createdAt",
373
380
  orderByDirection=OrderDirectionType.DESC,
374
381
  page=page,
375
382
  limit=limit,
@@ -378,7 +385,7 @@ class TheStageApiClient(TheStageApiClientCore):
378
385
 
379
386
  response = self._request(
380
387
  method='POST',
381
- url='/user-api/v1/docker-container/list',
388
+ url='/user-api/v2/docker-container/list',
382
389
  data=request.model_dump(),
383
390
  token=self.__config_provider.get_config().main.thestage_auth_token
384
391
  )
@@ -390,23 +397,16 @@ class TheStageApiClient(TheStageApiClientCore):
390
397
  def get_container(
391
398
  self,
392
399
  container_slug: Optional[str] = None,
393
- container_id: Optional[int] = None,
400
+ container_public_id: Optional[str] = None,
394
401
  ) -> Optional[DockerContainerDto]:
395
- if not container_slug and not container_id:
396
- return None
397
-
398
- if container_id:
399
- data = {
400
- "dockerContainerId": container_id,
401
- }
402
- else:
403
- data = {
404
- "dockerContainerSlug": container_slug,
405
- }
402
+ data = {
403
+ "dockerContainerPublicId": container_public_id,
404
+ "dockerContainerSlug": container_slug,
405
+ }
406
406
 
407
407
  response = self._request(
408
408
  method='POST',
409
- url='/user-api/v1/docker-container/view',
409
+ url='/user-api/v2/docker-container/view',
410
410
  data=data,
411
411
  token=self.__config_provider.get_config().main.thestage_auth_token,
412
412
  )
@@ -420,7 +420,7 @@ class TheStageApiClient(TheStageApiClientCore):
420
420
 
421
421
  response = self._request(
422
422
  method='POST',
423
- url='/user-api/v1/docker-container/action',
423
+ url='/user-api/v2/docker-container/action',
424
424
  data=request_param.model_dump(by_alias=True),
425
425
  token=self.__config_provider.get_config().main.thestage_auth_token,
426
426
  )
@@ -439,14 +439,15 @@ class TheStageApiClient(TheStageApiClientCore):
439
439
  data = ContainerBusinessStatusMapperResponse.model_validate(response) if response else None
440
440
  return data.docker_container_status_map if data else None
441
441
 
442
- def get_project_by_slug(self, slug: str) -> Optional[ProjectDto]:
442
+ def get_project(self, slug: Optional[str], public_id: Optional[str]) -> Optional[ProjectDto]:
443
443
  data = {
444
444
  "projectSlug": slug,
445
+ "projectPublicId": public_id,
445
446
  }
446
447
 
447
448
  response = self._request(
448
449
  method='POST',
449
- url='/user-api/v1/project/view-by-slug',
450
+ url='/user-api/v2/project/view',
450
451
  data=data,
451
452
  token=self.__config_provider.get_config().main.thestage_auth_token,
452
453
  )
@@ -455,9 +456,9 @@ class TheStageApiClient(TheStageApiClientCore):
455
456
  project = ProjectDto.model_validate(result.project) if result else None
456
457
  return project if result and result.is_success else None
457
458
 
458
- def get_project_deploy_ssh_key(self, slug: str) -> str:
459
+ def get_project_deploy_ssh_key(self, public_id: str) -> str:
459
460
  request = ProjectGetDeploySshKeyRequest(
460
- projectSlug=slug
461
+ projectPublicId=public_id,
461
462
  )
462
463
 
463
464
  response = self._request(
@@ -472,15 +473,15 @@ class TheStageApiClient(TheStageApiClientCore):
472
473
 
473
474
  def execute_project_task(
474
475
  self,
475
- project_slug: str,
476
+ project_public_id: str,
476
477
  run_command: str,
477
478
  task_title: str,
478
- docker_container_slug: Optional[str] = None,
479
+ docker_container_public_id: str,
479
480
  commit_hash: Optional[str] = None,
480
481
  ) -> Optional[ProjectRunTaskResponse]:
481
482
  request = ProjectRunTaskRequest(
482
- projectSlug=project_slug,
483
- dockerContainerSlug=docker_container_slug,
483
+ projectPublicId=project_public_id,
484
+ dockerContainerPublicId=docker_container_public_id,
484
485
  commitHash=commit_hash,
485
486
  runCommand=run_command,
486
487
  taskTitle=task_title,
@@ -488,31 +489,31 @@ class TheStageApiClient(TheStageApiClientCore):
488
489
 
489
490
  response = self._request(
490
491
  method='POST',
491
- url='/user-api/v1/project/execute-task',
492
+ url='/user-api/v2/task/execute',
492
493
  data=request.model_dump(),
493
494
  token=self.__config_provider.get_config().main.thestage_auth_token,
494
495
  )
495
496
 
496
497
  return ProjectRunTaskResponse.model_validate(response) if response else None
497
498
 
498
- async def poll_logs_httpx(self, docker_container_id: Optional[int], last_log_timestamp: str,
499
- last_log_id: str, task_id: Optional[int] = None,
500
- inference_simulator_id: Optional[int] = None) -> Optional[LogPollingResponse]:
499
+ async def poll_logs_httpx(self, docker_container_public_id: Optional[str], last_log_timestamp: str,
500
+ last_log_id: str, task_public_id: Optional[str] = None,
501
+ inference_simulator_public_id: Optional[str] = None) -> Optional[LogPollingResponse]:
501
502
  request_headers = {'Content-Type': 'application/json'}
502
503
  token = self.__config_provider.get_config().main.thestage_auth_token
503
504
  if token: request_headers['Authorization'] = f"Bearer {token}"
504
505
 
505
506
  request = LogPollingRequest(
506
- inferenceSimulatorId=inference_simulator_id,
507
- taskId=task_id,
508
- dockerContainerId=docker_container_id,
507
+ inferenceSimulatorPublicId=inference_simulator_public_id,
508
+ taskPublicId=task_public_id,
509
+ dockerContainerPublicId=docker_container_public_id,
509
510
  lastLogTimestamp=last_log_timestamp,
510
511
  lastLogId=last_log_id
511
512
  )
512
513
 
513
514
  async with httpx.AsyncClient() as client:
514
515
  response = await client.post(
515
- url=f"{self._get_host()}/user-api/v1/logging/poll",
516
+ url=f"{self._get_host()}/user-api/v2/logging/poll",
516
517
  headers=request_headers,
517
518
  json=request.model_dump(),
518
519
  timeout=3.5
@@ -528,7 +529,7 @@ class TheStageApiClient(TheStageApiClientCore):
528
529
 
529
530
  response = self._request(
530
531
  method='POST',
531
- url='/user-api/v1/ssh-key/add-public-key-to-user',
532
+ url='/user-api/v2/ssh-key/add-public-key-to-user',
532
533
  data=request.model_dump(),
533
534
  token=self.__config_provider.get_config().main.thestage_auth_token,
534
535
  )
@@ -543,7 +544,7 @@ class TheStageApiClient(TheStageApiClientCore):
543
544
 
544
545
  response = self._request(
545
546
  method='POST',
546
- url='/user-api/v1/ssh-key/is-user-has-public-ssh-key',
547
+ url='/user-api/v2/ssh-key/is-user-has-public-ssh-key',
547
548
  data=request.model_dump(),
548
549
  token=self.__config_provider.get_config().main.thestage_auth_token,
549
550
  )
@@ -551,16 +552,16 @@ class TheStageApiClient(TheStageApiClientCore):
551
552
  result = IsUserHasSshPublicKeyResponse.model_validate(response) if response else None
552
553
  return result
553
554
 
554
- def add_public_ssh_key_to_instance_rented(self, instance_rented_id: int,
555
- ssh_key_pair_id: int) -> AddSshPublicKeyToInstanceResponse:
555
+ def add_public_ssh_key_to_instance_rented(self, instance_rented_public_id: str,
556
+ ssh_key_pair_public_id: str) -> AddSshPublicKeyToInstanceResponse:
556
557
  request = AddSshPublicKeyToInstanceRequest(
557
- instanceRentedId=instance_rented_id,
558
- sshPublicKeyId=ssh_key_pair_id,
558
+ instanceRentedPublicId=instance_rented_public_id,
559
+ sshPublicKeyPublicId=ssh_key_pair_public_id,
559
560
  )
560
561
 
561
562
  response = self._request(
562
563
  method='POST',
563
- url='/user-api/v1/ssh-key/add-public-ssh-key-to-instance-rented',
564
+ url='/user-api/v2/ssh-key/add-public-ssh-key-to-instance-rented',
564
565
  data=request.model_dump(),
565
566
  token=self.__config_provider.get_config().main.thestage_auth_token,
566
567
  )
@@ -570,25 +571,29 @@ class TheStageApiClient(TheStageApiClientCore):
570
571
 
571
572
  def start_project_inference_simulator(
572
573
  self,
573
- project_slug: str,
574
+ project_public_id: str,
574
575
  commit_hash: Optional[str] = None,
575
- rented_instance_unique_id: Optional[str] = None,
576
- self_hosted_instance_unique_id: Optional[str] = None,
576
+ rented_instance_public_id: Optional[str] = None,
577
+ rented_instance_slug: Optional[str] = None,
578
+ self_hosted_instance_public_id: Optional[str] = None,
579
+ self_hosted_instance_slug: Optional[str] = None,
577
580
  inference_dir: Optional[str] = None,
578
581
  is_skip_installation: Optional[bool] = False,
579
582
  ) -> Optional[ProjectStartInferenceSimulatorResponse]:
580
583
  request = ProjectStartInferenceSimulatorRequest(
581
- projectSlug=project_slug,
584
+ projectPublicId=project_public_id,
582
585
  commitHash=commit_hash,
583
- instanceRentedUId=rented_instance_unique_id,
584
- selfhostedInstanceUId=self_hosted_instance_unique_id,
586
+ instanceRentedPublicId=rented_instance_public_id,
587
+ instanceRentedSlug=rented_instance_slug,
588
+ selfhostedInstancePublicId=self_hosted_instance_public_id,
589
+ selfhostedInstanceSlug=self_hosted_instance_slug,
585
590
  inferenceDir=inference_dir,
586
591
  isSkipInstallation=is_skip_installation,
587
592
  )
588
593
 
589
594
  response = self._request(
590
595
  method='POST',
591
- url='/user-api/v1/project/inference-simulator/create',
596
+ url='/user-api/v2/project/inference-simulator/create',
592
597
  data=request.model_dump(),
593
598
  token=self.__config_provider.get_config().main.thestage_auth_token,
594
599
  )
@@ -597,15 +602,17 @@ class TheStageApiClient(TheStageApiClientCore):
597
602
 
598
603
  def push_project_inference_simulator_model(
599
604
  self,
600
- slug: str,
605
+ public_id: Optional[str],
606
+ slug: Optional[str],
601
607
  ) -> Optional[ProjectPushInferenceSimulatorModelResponse]:
602
608
  request = ProjectPushInferenceSimulatorModelRequest(
603
- slug=slug,
609
+ inferenceSimulatorPublicId=public_id,
610
+ inferenceSimulatorSlug=slug,
604
611
  )
605
612
 
606
613
  response = self._request(
607
614
  method='POST',
608
- url='/user-api/v1/project/inference-simulator/push-model',
615
+ url='/user-api/v2/inference-simulator/push-model',
609
616
  data=request.model_dump(),
610
617
  token=self.__config_provider.get_config().main.thestage_auth_token,
611
618
  )
@@ -639,15 +646,17 @@ class TheStageApiClient(TheStageApiClientCore):
639
646
  @error_handler()
640
647
  def get_inference_simulator(
641
648
  self,
642
- slug: str,
649
+ public_id: Optional[str] = None,
650
+ slug: Optional[str] = None,
643
651
  ) -> Optional[GetInferenceSimulatorResponse]:
644
652
  request = GetInferenceSimulatorRequest(
653
+ publicId=public_id,
645
654
  slug=slug,
646
655
  )
647
656
 
648
657
  response = self._request(
649
658
  method='POST',
650
- url='/user-api/v1/inference-simulator/get',
659
+ url='/user-api/v2/inference-simulator/get',
651
660
  data=request.model_dump(),
652
661
  token=self.__config_provider.get_config().main.thestage_auth_token,
653
662
  )
@@ -656,22 +665,28 @@ class TheStageApiClient(TheStageApiClientCore):
656
665
  @error_handler()
657
666
  def deploy_inference_model_to_instance(
658
667
  self,
659
- unique_id: str,
660
- unique_id_with_timestamp: str,
661
- rented_instance_unique_id: Optional[str] = None,
662
- self_hosted_instance_unique_id: Optional[str] = None,
668
+ model_public_id: str,
669
+ model_slug: str,
670
+ new_inference_simulator_slug: str,
671
+ rented_instance_public_id: Optional[str] = None,
672
+ rented_instance_slug: Optional[str] = None,
673
+ self_hosted_instance_public_id: Optional[str] = None,
674
+ self_hosted_instance_slug: Optional[str] = None,
663
675
 
664
676
  ) -> Optional[DeployInferenceModelToInstanceResponse]:
665
677
  request = DeployInferenceModelToInstanceRequest(
666
- inferenceSimulatorSlug=unique_id_with_timestamp,
667
- modelSlug=unique_id,
668
- instanceRentedSlug=rented_instance_unique_id,
669
- selfhostedInstanceSlug=self_hosted_instance_unique_id
678
+ inferenceSimulatorSlug=new_inference_simulator_slug,
679
+ modelPublicId=model_public_id,
680
+ modelSlug=model_slug,
681
+ instancePublicId=rented_instance_public_id,
682
+ instanceRentedSlug=rented_instance_slug,
683
+ selfhostedInstancePublicId=self_hosted_instance_public_id,
684
+ selfhostedInstanceSlug=self_hosted_instance_slug
670
685
  )
671
686
 
672
687
  response = self._request(
673
688
  method='POST',
674
- url='/user-api/v1/inference-simulator-model/deploy/instance',
689
+ url='/user-api/v2/inference-simulator-model/deploy/instance',
675
690
  data=request.model_dump(),
676
691
  token=self.__config_provider.get_config().main.thestage_auth_token,
677
692
  )
@@ -680,11 +695,13 @@ class TheStageApiClient(TheStageApiClientCore):
680
695
  @error_handler()
681
696
  def deploy_inference_model_to_sagemaker(
682
697
  self,
683
- unique_id: str,
698
+ model_public_id: Optional[str],
699
+ model_slug: Optional[str],
684
700
  arn: Optional[str] = None,
685
701
  ) -> Optional[DeployInferenceModelToSagemakerResponse]:
686
702
  request = DeployInferenceModelToSagemakerRequest(
687
- modelSlug=unique_id,
703
+ modelPublicId=model_public_id,
704
+ modelSlug=model_slug,
688
705
  arn=arn,
689
706
  )
690
707
 
@@ -696,23 +713,41 @@ class TheStageApiClient(TheStageApiClientCore):
696
713
  )
697
714
  return DeployInferenceModelToSagemakerResponse.model_validate(response) if response else None
698
715
 
699
- def query_user_logs(self, limit: int, task_id: Optional[int] = None,
700
- inference_simulator_id: Optional[int] = None,
701
- container_id: Optional[int] = None) -> UserLogsQueryResponse:
716
+ def query_user_logs(self, limit: int, task_public_id: Optional[str] = None,
717
+ inference_simulator_public_id: Optional[str] = None,
718
+ container_public_id: Optional[str] = None) -> UserLogsQueryResponse:
702
719
  request = UserLogsQueryRequest(
703
- inferenceSimulatorId=inference_simulator_id,
704
- taskId=task_id,
705
- containerId=container_id,
720
+ inferenceSimulatorPublicId=inference_simulator_public_id,
721
+ taskPublicId=task_public_id,
722
+ containerPublicId=container_public_id,
706
723
  limit=limit,
707
724
  ascendingOrder=False,
708
725
  )
709
726
 
710
727
  response = self._request(
711
728
  method='POST',
712
- url='/user-api/v1/logging/query-user-logs',
729
+ url='/user-api/v2/logging/query-user-logs',
713
730
  data=request.model_dump(),
714
731
  token=self.__config_provider.get_config().main.thestage_auth_token,
715
732
  )
716
733
 
717
734
  result = UserLogsQueryResponse.model_validate(response) if response else None
718
735
  return result
736
+
737
+
738
+ def resolve_connect_options(
739
+ self,
740
+ entity_identifier: str
741
+ ) -> Optional[ConnectResolveOptionsResponse]:
742
+ data = {
743
+ "entityIdentifier": entity_identifier,
744
+ }
745
+
746
+ response = self._request(
747
+ method='POST',
748
+ url='/user-api/v1/connect/resolve-options',
749
+ data=data,
750
+ token=self.__config_provider.get_config().main.thestage_auth_token,
751
+ )
752
+
753
+ return ConnectResolveOptionsResponse.model_validate(response) if response else None
@@ -0,0 +1,21 @@
1
+ from typing import Optional, List
2
+
3
+ from pydantic import Field, BaseModel
4
+
5
+ from thestage.services.clients.thestage_api.dtos.base_response import TheStageBaseResponse
6
+ from thestage.services.clients.thestage_api.dtos.frontend_status import FrontendStatusDto
7
+ from thestage.services.task.dto.task_dto import TaskDto
8
+
9
+
10
+ class EntityMatchData(BaseModel):
11
+ publicId: str = Field(alias='publicId')
12
+ frontendStatus: FrontendStatusDto = Field(alias='frontendStatus')
13
+ canConnect: bool = Field(alias='canConnect')
14
+ matchedField: Optional[str] = Field(None, alias='matchedField')
15
+
16
+
17
+ class ConnectResolveOptionsResponse(TheStageBaseResponse):
18
+ taskMatchData: List[EntityMatchData] = Field(None, alias='taskMatchData')
19
+ dockerContainerMatchData: List[EntityMatchData] = Field(None, alias='dockerContainerMatchData')
20
+ instanceRentedMatchData: List[EntityMatchData] = Field(None, alias='instanceRentedMatchData')
21
+ selfhostedInstanceMatchData: List[EntityMatchData] = Field(None, alias='selfhostedInstanceMatchData')
@@ -7,5 +7,5 @@ from thestage.services.clients.thestage_api.dtos.enums.container_pending_action
7
7
  class DockerContainerActionRequestDto(BaseModel):
8
8
  model_config = ConfigDict(use_enum_values=True)
9
9
 
10
- container_id: Optional[int] = Field(None, alias='dockerContainerId')
10
+ container_public_id: Optional[str] = Field(None, alias='dockerContainerPublicId')
11
11
  action: DockerContainerAction = Field(None, alias='action')