thestage 0.5.471__py3-none-any.whl → 0.6.2__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 (179) hide show
  1. thestage/.env +5 -5
  2. thestage/__init__.py +3 -4
  3. thestage/__main__.py +9 -9
  4. thestage/cli_command.py +56 -56
  5. thestage/cli_command_helper.py +51 -51
  6. thestage/color_scheme/color_scheme.py +7 -7
  7. thestage/config/__init__.py +18 -18
  8. thestage/config/config_storage.py +5 -5
  9. thestage/config/env_base.py +7 -7
  10. thestage/controllers/__init__.py +0 -0
  11. thestage/controllers/base_controller.py +67 -67
  12. thestage/controllers/config_controller.py +137 -137
  13. thestage/controllers/container_controller.py +389 -389
  14. thestage/controllers/instance_controller.py +183 -183
  15. thestage/controllers/project_controller.py +810 -783
  16. thestage/controllers/utils_controller.py +32 -32
  17. thestage/debug_main.dist.py +28 -28
  18. thestage/entities/__init__.py +0 -0
  19. thestage/entities/container.py +17 -17
  20. thestage/entities/enums/__init__.py +0 -0
  21. thestage/entities/enums/order_direction_type.py +6 -6
  22. thestage/entities/enums/shell_type.py +7 -7
  23. thestage/entities/enums/tail_output_type.py +6 -6
  24. thestage/entities/enums/yes_no_response.py +7 -7
  25. thestage/entities/file_item.py +27 -27
  26. thestage/entities/project_inference_simulator.py +18 -18
  27. thestage/entities/project_inference_simulator_model.py +16 -16
  28. thestage/entities/project_task.py +19 -19
  29. thestage/entities/rented_instance.py +19 -19
  30. thestage/entities/self_hosted_instance.py +18 -18
  31. thestage/exceptions/__init__.py +0 -0
  32. thestage/exceptions/auth_exception.py +6 -6
  33. thestage/exceptions/base_exception.py +13 -13
  34. thestage/exceptions/business_logic_exception.py +6 -6
  35. thestage/exceptions/config_exception.py +6 -6
  36. thestage/exceptions/file_system_exception.py +6 -6
  37. thestage/exceptions/git_access_exception.py +17 -17
  38. thestage/exceptions/remote_server_exception.py +24 -24
  39. thestage/git/ProgressPrinter.py +22 -22
  40. thestage/helpers/__init__.py +0 -0
  41. thestage/helpers/error_handler.py +115 -115
  42. thestage/helpers/exception_hook.py +14 -14
  43. thestage/helpers/logger/__init__.py +0 -0
  44. thestage/helpers/logger/app_logger.py +50 -50
  45. thestage/helpers/ssh_util.py +38 -38
  46. thestage/i18n/en_GB/messages.po +947 -947
  47. thestage/i18n/translation.py +9 -9
  48. thestage/main.py +36 -36
  49. thestage/services/.env +6 -6
  50. thestage/services/__init__.py +0 -0
  51. thestage/services/abstract_mapper.py +9 -9
  52. thestage/services/abstract_service.py +87 -87
  53. thestage/services/app_config_service.py +52 -52
  54. thestage/services/clients/__init__.py +0 -0
  55. thestage/services/clients/git/__init__.py +0 -0
  56. thestage/services/clients/git/git_client.py +436 -331
  57. thestage/services/clients/thestage_api/__init__.py +0 -0
  58. thestage/services/clients/thestage_api/api_client.py +718 -720
  59. thestage/services/clients/thestage_api/core/api_client_core.py +108 -108
  60. thestage/services/clients/thestage_api/core/http_client_exception.py +12 -12
  61. thestage/services/clients/thestage_api/dtos/__init__.py +0 -0
  62. thestage/services/clients/thestage_api/dtos/base_response.py +13 -13
  63. thestage/services/clients/thestage_api/dtos/cloud_provider_region.py +19 -19
  64. thestage/services/clients/thestage_api/dtos/container_param_request.py +11 -11
  65. thestage/services/clients/thestage_api/dtos/container_response.py +67 -67
  66. thestage/services/clients/thestage_api/dtos/docker_container_assigned_device.py +10 -10
  67. thestage/services/clients/thestage_api/dtos/docker_container_controller/docker_container_list_request.py +13 -13
  68. thestage/services/clients/thestage_api/dtos/docker_container_controller/docker_container_list_response.py +13 -13
  69. thestage/services/clients/thestage_api/dtos/docker_container_mapping.py +10 -10
  70. thestage/services/clients/thestage_api/dtos/entity_filter_request.py +14 -14
  71. thestage/services/clients/thestage_api/dtos/enums/__init__.py +0 -0
  72. thestage/services/clients/thestage_api/dtos/enums/container_pending_action.py +10 -10
  73. thestage/services/clients/thestage_api/dtos/enums/container_status.py +17 -17
  74. thestage/services/clients/thestage_api/dtos/enums/cpu_type.py +8 -8
  75. thestage/services/clients/thestage_api/dtos/enums/currency_type.py +10 -10
  76. thestage/services/clients/thestage_api/dtos/enums/daemon_status.py +9 -9
  77. thestage/services/clients/thestage_api/dtos/enums/disk_type.py +7 -7
  78. thestage/services/clients/thestage_api/dtos/enums/drive_type.py +7 -7
  79. thestage/services/clients/thestage_api/dtos/enums/gpu_name.py +8 -8
  80. thestage/services/clients/thestage_api/dtos/enums/inference_model_status.py +9 -9
  81. thestage/services/clients/thestage_api/dtos/enums/inference_simulator_status.py +15 -15
  82. thestage/services/clients/thestage_api/dtos/enums/instance_rented_status.py +17 -17
  83. thestage/services/clients/thestage_api/dtos/enums/instance_type.py +7 -7
  84. thestage/services/clients/thestage_api/dtos/enums/location_region.py +11 -11
  85. thestage/services/clients/thestage_api/dtos/enums/power_status.py +10 -10
  86. thestage/services/clients/thestage_api/dtos/enums/provider_name.py +11 -11
  87. thestage/services/clients/thestage_api/dtos/enums/selfhosted_status.py +10 -10
  88. thestage/services/clients/thestage_api/dtos/enums/task_execution_status.py +12 -12
  89. thestage/services/clients/thestage_api/dtos/enums/task_status.py +12 -12
  90. thestage/services/clients/thestage_api/dtos/frontend_status.py +10 -10
  91. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_request.py +13 -13
  92. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_response.py +13 -13
  93. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_sagemaker_request.py +12 -12
  94. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_sagemaker_response.py +12 -12
  95. thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_request.py +10 -10
  96. thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_response.py +13 -13
  97. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_list_for_project_request.py +14 -14
  98. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_list_for_project_response.py +12 -12
  99. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_model_list_for_project_request.py +12 -12
  100. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_model_list_for_project_response.py +13 -13
  101. thestage/services/clients/thestage_api/dtos/inference_simulator_model_response.py +11 -11
  102. thestage/services/clients/thestage_api/dtos/inference_simulator_response.py +11 -11
  103. thestage/services/clients/thestage_api/dtos/installed_service.py +17 -17
  104. thestage/services/clients/thestage_api/dtos/instance_detected_gpus.py +20 -20
  105. thestage/services/clients/thestage_api/dtos/instance_rented_response.py +71 -71
  106. thestage/services/clients/thestage_api/dtos/logging_controller/docker_container_log_stream_request.py +7 -7
  107. thestage/services/clients/thestage_api/dtos/logging_controller/log_polling_request.py +13 -13
  108. thestage/services/clients/thestage_api/dtos/logging_controller/log_polling_response.py +14 -14
  109. thestage/services/clients/thestage_api/dtos/logging_controller/task_log_stream_request.py +7 -7
  110. thestage/services/clients/thestage_api/dtos/logging_controller/user_logs_query_request.py +21 -21
  111. thestage/services/clients/thestage_api/dtos/logging_controller/user_logs_query_response.py +14 -14
  112. thestage/services/clients/thestage_api/dtos/paginated_entity_list.py +11 -11
  113. thestage/services/clients/thestage_api/dtos/pagination_data.py +10 -10
  114. thestage/services/clients/thestage_api/dtos/price_definition.py +14 -14
  115. thestage/services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_request.py +7 -7
  116. thestage/services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_response.py +10 -10
  117. thestage/services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_request.py +8 -8
  118. thestage/services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_response.py +6 -6
  119. thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_request.py +15 -15
  120. thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_response.py +10 -10
  121. thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_request.py +13 -14
  122. thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_response.py +10 -10
  123. thestage/services/clients/thestage_api/dtos/project_response.py +32 -32
  124. thestage/services/clients/thestage_api/dtos/selfhosted_instance_response.py +56 -56
  125. thestage/services/clients/thestage_api/dtos/sftp_path_helper.py +13 -13
  126. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_key_to_user_request.py +8 -8
  127. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_key_to_user_response.py +11 -11
  128. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_public_key_to_instance_request.py +8 -8
  129. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_public_key_to_instance_response.py +11 -11
  130. thestage/services/clients/thestage_api/dtos/ssh_key_controller/is_user_has_public_ssh_key_request.py +7 -7
  131. thestage/services/clients/thestage_api/dtos/ssh_key_controller/is_user_has_public_ssh_key_response.py +12 -12
  132. thestage/services/clients/thestage_api/dtos/task_controller/task_list_for_project_request.py +10 -10
  133. thestage/services/clients/thestage_api/dtos/task_controller/task_list_for_project_response.py +12 -12
  134. thestage/services/clients/thestage_api/dtos/task_controller/task_status_localized_map_response.py +9 -9
  135. thestage/services/clients/thestage_api/dtos/task_controller/task_view_response.py +12 -12
  136. thestage/services/clients/thestage_api/dtos/user_controller/user_profile.py +12 -12
  137. thestage/services/clients/thestage_api/dtos/validate_token_response.py +11 -11
  138. thestage/services/config_provider/__init__.py +0 -0
  139. thestage/services/config_provider/config_provider.py +237 -237
  140. thestage/services/connect/connect_service.py +196 -196
  141. thestage/services/connect/dto/remote_server_config.py +9 -9
  142. thestage/services/container/__init__.py +0 -0
  143. thestage/services/container/container_service.py +374 -374
  144. thestage/services/container/mapper/__init__.py +0 -0
  145. thestage/services/container/mapper/container_mapper.py +30 -30
  146. thestage/services/core_files/config_entity.py +26 -26
  147. thestage/services/filesystem_service.py +133 -133
  148. thestage/services/instance/__init__.py +0 -0
  149. thestage/services/instance/instance_service.py +303 -303
  150. thestage/services/instance/mapper/__init__.py +0 -0
  151. thestage/services/instance/mapper/instance_mapper.py +24 -24
  152. thestage/services/instance/mapper/selfhosted_mapper.py +33 -33
  153. thestage/services/logging/byte_print_style.py +5 -5
  154. thestage/services/logging/dto/log_message.py +15 -15
  155. thestage/services/logging/dto/log_type.py +6 -6
  156. thestage/services/logging/exception/log_polling_exception.py +6 -6
  157. thestage/services/logging/logging_constants.py +3 -3
  158. thestage/services/logging/logging_service.py +367 -367
  159. thestage/services/project/__init__.py +0 -0
  160. thestage/services/project/dto/inference_simulator_dto.py +22 -22
  161. thestage/services/project/dto/inference_simulator_model_dto.py +20 -20
  162. thestage/services/project/dto/project_config.py +14 -14
  163. thestage/services/project/mapper/__init__.py +0 -0
  164. thestage/services/project/mapper/project_inference_simulator_mapper.py +21 -21
  165. thestage/services/project/mapper/project_inference_simulator_model_mapper.py +21 -21
  166. thestage/services/project/mapper/project_task_mapper.py +22 -22
  167. thestage/services/project/project_service.py +1253 -1241
  168. thestage/services/remote_server_service.py +609 -609
  169. thestage/services/service_factory.py +97 -97
  170. thestage/services/task/dto/task_dto.py +40 -40
  171. thestage/services/validation_service.py +61 -61
  172. {thestage-0.5.471.dist-info → thestage-0.6.2.dist-info}/LICENSE.txt +12 -12
  173. {thestage-0.5.471.dist-info → thestage-0.6.2.dist-info}/METADATA +1 -1
  174. thestage-0.6.2.dist-info/RECORD +176 -0
  175. {thestage-0.5.471.dist-info → thestage-0.6.2.dist-info}/WHEEL +1 -1
  176. thestage/debug_tests.py +0 -12
  177. thestage/services/clients/.DS_Store +0 -0
  178. thestage-0.5.471.dist-info/RECORD +0 -178
  179. {thestage-0.5.471.dist-info → thestage-0.6.2.dist-info}/entry_points.txt +0 -0
@@ -1,720 +1,718 @@
1
- from typing import Optional, List, Tuple, Dict, Iterator
2
-
3
- import httpx
4
-
5
- from thestage.helpers.error_handler import error_handler
6
- from thestage.services.clients.thestage_api.core.api_client_core import TheStageApiClientCore
7
- from thestage.services.clients.thestage_api.dtos.docker_container_controller.docker_container_list_request import \
8
- DockerContainerListRequest
9
- from thestage.services.clients.thestage_api.dtos.docker_container_controller.docker_container_list_response import \
10
- DockerContainerListResponse
11
- from thestage.services.clients.thestage_api.dtos.entity_filter_request import EntityFilterRequest
12
- from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_instance_request import \
13
- DeployInferenceModelToInstanceRequest
14
- from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_instance_response import \
15
- DeployInferenceModelToInstanceResponse
16
- from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_sagemaker_request import \
17
- DeployInferenceModelToSagemakerRequest
18
- from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_sagemaker_response import \
19
- DeployInferenceModelToSagemakerResponse
20
- from thestage.services.clients.thestage_api.dtos.inference_controller.get_inference_simulator_request import \
21
- GetInferenceSimulatorRequest
22
- from thestage.services.clients.thestage_api.dtos.inference_controller.get_inference_simulator_response import \
23
- 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
28
- from thestage.services.clients.thestage_api.dtos.inference_controller.inference_simulator_model_list_for_project_request import \
29
- InferenceSimulatorModelListForProjectRequest
30
- from thestage.services.clients.thestage_api.dtos.inference_controller.inference_simulator_model_list_for_project_response import \
31
- InferenceSimulatorModelListForProjectResponse
32
- from thestage.services.clients.thestage_api.dtos.inference_simulator_model_response import \
33
- InferenceSimulatorModelStatusMapperResponse
34
- from thestage.services.clients.thestage_api.dtos.inference_simulator_response import \
35
- InferenceSimulatorStatusMapperResponse
36
- from thestage.services.clients.thestage_api.dtos.logging_controller.log_polling_request import LogPollingRequest
37
- from thestage.services.clients.thestage_api.dtos.logging_controller.log_polling_response import LogPollingResponse
38
- from thestage.services.clients.thestage_api.dtos.logging_controller.user_logs_query_request import UserLogsQueryRequest
39
- from thestage.services.clients.thestage_api.dtos.logging_controller.user_logs_query_response import \
40
- UserLogsQueryResponse
41
- from thestage.services.clients.thestage_api.dtos.paginated_entity_list import PaginatedEntityList
42
- from thestage.services.clients.thestage_api.dtos.project_controller.project_get_deploy_ssh_key_request import \
43
- ProjectGetDeploySshKeyRequest
44
- from thestage.services.clients.thestage_api.dtos.project_controller.project_get_deploy_ssh_key_response import \
45
- ProjectGetDeploySshKeyResponse
46
- from thestage.services.clients.thestage_api.dtos.project_controller.project_push_inference_simulator_model_request import \
47
- ProjectPushInferenceSimulatorModelRequest
48
- from thestage.services.clients.thestage_api.dtos.project_controller.project_push_inference_simulator_model_response import \
49
- ProjectPushInferenceSimulatorModelResponse
50
- from thestage.services.clients.thestage_api.dtos.project_controller.project_run_task_request import \
51
- ProjectRunTaskRequest
52
- from thestage.services.clients.thestage_api.dtos.project_controller.project_run_task_response import \
53
- ProjectRunTaskResponse
54
- from thestage.services.clients.thestage_api.dtos.project_controller.project_start_inference_simulator_request import \
55
- ProjectStartInferenceSimulatorRequest
56
- from thestage.services.clients.thestage_api.dtos.project_controller.project_start_inference_simulator_response import \
57
- ProjectStartInferenceSimulatorResponse
58
- from thestage.services.clients.thestage_api.dtos.project_response import ProjectDto, ProjectViewResponse
59
- from thestage.services.clients.thestage_api.dtos.selfhosted_instance_response import SelfHostedInstanceListResponse, \
60
- SelfHostedInstanceDto, SelfHostedRentedItemResponse, SelfHostedRentedRentedBusinessStatusMapperResponse
61
- from thestage.services.clients.thestage_api.dtos.container_param_request import DockerContainerActionRequestDto
62
- from thestage.services.clients.thestage_api.dtos.container_response import DockerContainerDto, \
63
- DockerContainerViewResponse, ContainerBusinessStatusMapperResponse
64
- from thestage.entities.enums.order_direction_type import OrderDirectionType
65
- from thestage.services.clients.thestage_api.dtos.ssh_key_controller.add_ssh_key_to_user_request import \
66
- AddSshKeyToUserRequest
67
- from thestage.services.clients.thestage_api.dtos.ssh_key_controller.add_ssh_key_to_user_response import \
68
- AddSshKeyToUserResponse
69
- from thestage.services.clients.thestage_api.dtos.ssh_key_controller.add_ssh_public_key_to_instance_request import \
70
- AddSshPublicKeyToInstanceRequest
71
- from thestage.services.clients.thestage_api.dtos.ssh_key_controller.add_ssh_public_key_to_instance_response import \
72
- AddSshPublicKeyToInstanceResponse
73
- from thestage.services.clients.thestage_api.dtos.ssh_key_controller.is_user_has_public_ssh_key_request import \
74
- IsUserHasSshPublicKeyRequest
75
- from thestage.services.clients.thestage_api.dtos.ssh_key_controller.is_user_has_public_ssh_key_response import \
76
- IsUserHasSshPublicKeyResponse
77
- from thestage.services.clients.thestage_api.dtos.task_controller.task_list_for_project_request import \
78
- TaskListForProjectRequest
79
- from thestage.services.clients.thestage_api.dtos.task_controller.task_list_for_project_response import \
80
- TaskListForProjectResponse
81
- from thestage.services.clients.thestage_api.dtos.task_controller.task_status_localized_map_response import \
82
- TaskStatusLocalizedMapResponse
83
- from thestage.services.clients.thestage_api.dtos.task_controller.task_view_response import TaskViewResponse
84
- from thestage.services.clients.thestage_api.dtos.instance_rented_response import InstanceRentedListResponse, \
85
- InstanceRentedDto, InstanceRentedItemResponse, InstanceRentedBusinessStatusMapperResponse
86
-
87
- from thestage.services.clients.thestage_api.dtos.base_response import TheStageBaseResponse
88
- from thestage.services.config_provider.config_provider import ConfigProvider
89
- from thestage.services.project.dto.inference_simulator_dto import InferenceSimulatorDto
90
- from thestage.services.project.dto.inference_simulator_model_dto import InferenceSimulatorModelDto
91
- from thestage.services.task.dto.task_dto import TaskDto
92
-
93
-
94
- class TheStageApiClient(TheStageApiClientCore):
95
- __config_provider: ConfigProvider = None
96
-
97
- def __init__(
98
- self,
99
- config_provider: ConfigProvider,
100
- ):
101
- # TODO this is super bullshit, remove all abstract classes
102
- super().__init__(url=config_provider.get_config().main.thestage_api_url)
103
- self.__config_provider = config_provider
104
-
105
- def get_task(
106
- self,
107
- task_id: int,
108
- ) -> Optional[TaskViewResponse]:
109
- data = {
110
- "taskId": task_id,
111
- }
112
-
113
- response = self._request(
114
- method='POST',
115
- url='/user-api/v1/task/view',
116
- data=data,
117
- token=self.__config_provider.get_config().main.thestage_auth_token,
118
- )
119
-
120
- result = TaskViewResponse.model_validate(response) if response else None
121
- return result if result and result.is_success else None
122
-
123
- def get_task_list_for_project(
124
- self,
125
- project_slug: str,
126
- page: int = 1,
127
- limit: int = 10,
128
- ) -> Optional[PaginatedEntityList[TaskDto]]:
129
- request = TaskListForProjectRequest(
130
- projectSlug=project_slug,
131
- entityFilterRequest=EntityFilterRequest(
132
- orderByField="id",
133
- orderByDirection=OrderDirectionType.DESC,
134
- page=page,
135
- limit=limit,
136
- ),
137
- )
138
-
139
- response = self._request(
140
- method='POST',
141
- url='/user-api/v1/task/list-for-project',
142
- data=request.model_dump(),
143
- token=self.__config_provider.get_config().main.thestage_auth_token,
144
- )
145
-
146
- result = TaskListForProjectResponse.model_validate(response) if response else None
147
- return result.tasks if result and result.is_success else None
148
-
149
- def get_inference_simulator_list_for_project(
150
- self,
151
- project_slug: str,
152
- statuses: List[str] = [],
153
- page: int = 1,
154
- limit: int = 10,
155
- ) -> Optional[PaginatedEntityList[InferenceSimulatorDto]]:
156
- request = InferenceSimulatorListForProjectRequest(
157
- projectSlug=project_slug,
158
- statuses=statuses,
159
- entityFilterRequest=EntityFilterRequest(
160
- orderByField="id",
161
- orderByDirection=OrderDirectionType.DESC,
162
- page=page,
163
- limit=limit,
164
- ),
165
- )
166
-
167
- response = self._request(
168
- method='POST',
169
- url='/user-api/v1/project/inference-simulator/list',
170
- data=request.model_dump(),
171
- token=self.__config_provider.get_config().main.thestage_auth_token,
172
- )
173
- result = InferenceSimulatorListForProjectResponse.model_validate(response) if response else None
174
- return result.inferenceSimulators if result and result.is_success else None
175
-
176
- def get_inference_simulator_model_list_for_project(
177
- self,
178
- project_slug: str,
179
- statuses: Optional[List[str]] = None,
180
- page: int = 1,
181
- limit: int = 10,
182
- ) -> Optional[PaginatedEntityList[InferenceSimulatorModelDto]]:
183
- request = InferenceSimulatorModelListForProjectRequest(
184
- projectSlug=project_slug,
185
- statuses=statuses,
186
- entityFilterRequest=EntityFilterRequest(
187
- orderByField="id",
188
- orderByDirection=OrderDirectionType.DESC,
189
- page=page,
190
- limit=limit,
191
- ),
192
- )
193
-
194
- response = self._request(
195
- method='POST',
196
- url='/user-api/v1/project/inference-simulator-model/list',
197
- data=request.model_dump(),
198
- token=self.__config_provider.get_config().main.thestage_auth_token,
199
- )
200
- result = InferenceSimulatorModelListForProjectResponse.model_validate(response) if response else None
201
- return result.inferenceSimulatorModels if result and result.is_success else None
202
-
203
- def get_rented_instance_list(
204
- self,
205
- statuses: List[str],
206
- query: Optional[str] = None,
207
- page: int = 1,
208
- limit: int = 10,
209
- ) -> PaginatedEntityList[InstanceRentedDto]:
210
- data = {
211
- #"statuses": [item.value for item in statuses],
212
- "entityFilterRequest": {
213
- "orderByField": "id",
214
- "orderByDirection": "DESC",
215
- "page": page,
216
- "limit": limit
217
- },
218
- "queryString": query
219
- }
220
-
221
- if statuses:
222
- data['businessStatuses'] = statuses
223
-
224
- response = self._request(
225
- method='POST',
226
- url='/user-api/v2/instance-rented/list',
227
- data=data,
228
- token=self.__config_provider.get_config().main.thestage_auth_token,
229
- )
230
-
231
- result = InstanceRentedListResponse.model_validate(response) if response else None
232
- return result.paginated_list if result and result.paginated_list else ([], None)
233
-
234
- def get_rented_business_status_map(self) -> Optional[Dict[str, str]]:
235
- response = self._request(
236
- method='POST',
237
- url='/user-api/v2/instance-rented/business-status-localized-map',
238
- data=None,
239
- token=self.__config_provider.get_config().main.thestage_auth_token,
240
- )
241
-
242
- data = InstanceRentedBusinessStatusMapperResponse.model_validate(response) if response else None
243
-
244
- return data.instance_rented_business_status_map if data else None
245
-
246
- def get_task_localized_status_map(self) -> Optional[Dict[str, str]]:
247
- response = self._request(
248
- method='POST',
249
- url='/user-api/v1/task/status-localized-mapping',
250
- data=None,
251
- token=self.__config_provider.get_config().main.thestage_auth_token,
252
- )
253
-
254
- data = TaskStatusLocalizedMapResponse.model_validate(response) if response else None
255
-
256
- return data.taskStatusMap if data else None
257
-
258
- def get_rented_instance(
259
- self,
260
- instance_slug: Optional[str] = None,
261
- instance_id: Optional[int] = None,
262
- ) -> Optional[InstanceRentedDto]:
263
- if not instance_slug and not instance_id:
264
- return None
265
-
266
- data = {
267
- "instanceRentedSlug": instance_slug,
268
- }
269
-
270
- response = self._request(
271
- method='POST',
272
- url='/user-api/v2/instance-rented/view-by-slug',
273
- data=data,
274
- token=self.__config_provider.get_config().main.thestage_auth_token,
275
- )
276
-
277
- return InstanceRentedItemResponse.model_validate(response).instance_rented if response else None
278
-
279
- def get_selfhosted_instance(
280
- self,
281
- instance_slug: Optional[str] = None,
282
- instance_id: Optional[int] = None,
283
- ) -> Optional[SelfHostedInstanceDto]:
284
- if not instance_slug and not instance_id:
285
- return None
286
-
287
- data = {
288
- "selfhostedInstanceSlug": instance_slug,
289
- }
290
-
291
- response = self._request(
292
- method='POST',
293
- url='/user-api/v2/self-hosted-instance/view-by-slug',
294
- data=data,
295
- token=self.__config_provider.get_config().main.thestage_auth_token,
296
- )
297
-
298
- return SelfHostedRentedItemResponse.model_validate(response).selfhosted_instance if response else None
299
-
300
- def get_selfhosted_instance_list(
301
- self,
302
- statuses: List[str],
303
- query: Optional[str] = None,
304
- page: int = 1,
305
- limit: int = 10,
306
- ) -> PaginatedEntityList[SelfHostedInstanceDto]:
307
- data = {
308
- #"statuses": [item.value for item in statuses] if statuses else [],
309
- "entityFilterRequest": {
310
- "orderByField": "id",
311
- "orderByDirection": "DESC",
312
- "page": page,
313
- "limit": limit
314
- },
315
- "queryString": query
316
- }
317
-
318
- if statuses:
319
- data['businessStatuses'] = statuses
320
-
321
- response = self._request(
322
- method='POST',
323
- url='/user-api/v2/self-hosted-instance/list',
324
- data=data,
325
- token=self.__config_provider.get_config().main.thestage_auth_token,
326
- )
327
-
328
- result = SelfHostedInstanceListResponse.model_validate(response) if response else None
329
- return result.paginated_list if result and result.paginated_list else ([], None)
330
-
331
- def get_selfhosted_business_status_map(self) -> Optional[Dict[str, str]]:
332
- response = self._request(
333
- method='POST',
334
- url='/user-api/v2/self-hosted-instance/business-status-localized-map',
335
- data=None,
336
- token=self.__config_provider.get_config().main.thestage_auth_token,
337
- )
338
-
339
- data = SelfHostedRentedRentedBusinessStatusMapperResponse.model_validate(response) if response else None
340
- return data.selfhosted_instance_business_status_map if data else None
341
-
342
-
343
- def cancel_task(
344
- self,
345
- task_id: int,
346
- ) -> Optional[TheStageBaseResponse]:
347
- data = {
348
- "taskId": task_id,
349
- }
350
-
351
- response = self._request(
352
- method='POST',
353
- url='/user-api/v1/task/cancel-task',
354
- data=data,
355
- token=self.__config_provider.get_config().main.thestage_auth_token,
356
- )
357
-
358
- result = TheStageBaseResponse.model_validate(response) if response else None
359
- return result if result else None
360
-
361
- def get_container_list(
362
- self,
363
- project_id: Optional[int] = None,
364
- statuses: List[str] = [],
365
- page: int = 1,
366
- limit: int = 10,
367
- ) -> PaginatedEntityList[DockerContainerDto]:
368
- request = DockerContainerListRequest(
369
- statuses=statuses,
370
- projectId=project_id,
371
- entityFilterRequest=EntityFilterRequest(
372
- orderByField="id",
373
- orderByDirection=OrderDirectionType.DESC,
374
- page=page,
375
- limit=limit,
376
- ),
377
- )
378
-
379
- response = self._request(
380
- method='POST',
381
- url='/user-api/v1/docker-container/list',
382
- data=request.model_dump(),
383
- token=self.__config_provider.get_config().main.thestage_auth_token
384
- )
385
-
386
- result = DockerContainerListResponse.model_validate(response) if response else None
387
- # return result.paginatedList.entities, result.paginatedList.pagination_data.total_pages if result and result.is_success else None
388
- return result.paginatedList if result and result.is_success else None
389
-
390
- def get_container(
391
- self,
392
- container_slug: Optional[str] = None,
393
- container_id: Optional[int] = None,
394
- ) -> 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
- }
406
-
407
- response = self._request(
408
- method='POST',
409
- url='/user-api/v1/docker-container/view',
410
- data=data,
411
- token=self.__config_provider.get_config().main.thestage_auth_token,
412
- )
413
-
414
- return DockerContainerViewResponse.model_validate(response).docker_container if response else None
415
-
416
- def container_action(
417
- self,
418
- request_param: DockerContainerActionRequestDto,
419
- ) -> TheStageBaseResponse:
420
-
421
- response = self._request(
422
- method='POST',
423
- url='/user-api/v1/docker-container/action',
424
- data=request_param.model_dump(by_alias=True),
425
- token=self.__config_provider.get_config().main.thestage_auth_token,
426
- )
427
-
428
- result = TheStageBaseResponse.model_validate(response) if response else None
429
- return result
430
-
431
- def get_container_business_status_map(self) -> Optional[Dict[str, str]]:
432
- response = self._request(
433
- method='POST',
434
- url='/user-api/v1/docker-container/status-localized-mapping',
435
- data=None,
436
- token=self.__config_provider.get_config().main.thestage_auth_token,
437
- )
438
-
439
- data = ContainerBusinessStatusMapperResponse.model_validate(response) if response else None
440
- return data.docker_container_status_map if data else None
441
-
442
- def get_project_by_slug(self, slug: str) -> Optional[ProjectDto]:
443
- data = {
444
- "projectSlug": slug,
445
- }
446
-
447
- response = self._request(
448
- method='POST',
449
- url='/user-api/v1/project/view-by-slug',
450
- data=data,
451
- token=self.__config_provider.get_config().main.thestage_auth_token,
452
- )
453
-
454
- result = ProjectViewResponse.model_validate(response) if response else None
455
- project = ProjectDto.model_validate(result.project) if result else None
456
- return project if result and result.is_success else None
457
-
458
- def get_project_deploy_ssh_key(self, slug: str) -> str:
459
- request = ProjectGetDeploySshKeyRequest(
460
- projectSlug=slug
461
- )
462
-
463
- response = self._request(
464
- method='POST',
465
- url='/user-api/v1/project/get-deploy-ssh-key',
466
- data=request.model_dump(),
467
- token=self.__config_provider.get_config().main.thestage_auth_token,
468
- )
469
-
470
- result = ProjectGetDeploySshKeyResponse.model_validate(response) if response else None
471
- return result.privateKey if result and result.is_success else None
472
-
473
- def execute_project_task(
474
- self,
475
- project_slug: str,
476
- run_command: str,
477
- task_title: str,
478
- docker_container_slug: Optional[str] = None,
479
- commit_hash: Optional[str] = None,
480
- ) -> Optional[ProjectRunTaskResponse]:
481
- request = ProjectRunTaskRequest(
482
- projectSlug=project_slug,
483
- dockerContainerSlug=docker_container_slug,
484
- commitHash=commit_hash,
485
- runCommand=run_command,
486
- taskTitle=task_title,
487
- )
488
-
489
- response = self._request(
490
- method='POST',
491
- url='/user-api/v1/project/execute-task',
492
- data=request.model_dump(),
493
- token=self.__config_provider.get_config().main.thestage_auth_token,
494
- )
495
-
496
- return ProjectRunTaskResponse.model_validate(response) if response else None
497
-
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]:
501
- request_headers = {'Content-Type': 'application/json'}
502
- token = self.__config_provider.get_config().main.thestage_auth_token
503
- if token: request_headers['Authorization'] = f"Bearer {token}"
504
-
505
- request = LogPollingRequest(
506
- inferenceSimulatorId=inference_simulator_id,
507
- taskId=task_id,
508
- dockerContainerId=docker_container_id,
509
- lastLogTimestamp=last_log_timestamp,
510
- lastLogId=last_log_id
511
- )
512
-
513
- async with httpx.AsyncClient() as client:
514
- response = await client.post(
515
- url=f"{self._get_host()}/user-api/v1/logging/poll",
516
- headers=request_headers,
517
- json=request.model_dump(),
518
- timeout=3.5
519
- )
520
-
521
- return LogPollingResponse.model_validate(response.json()) if response else None
522
-
523
- def add_public_ssh_key_to_user(self, public_key: str, note: str) -> AddSshKeyToUserResponse:
524
- request = AddSshKeyToUserRequest(
525
- sshKey=public_key,
526
- note=note
527
- )
528
-
529
- response = self._request(
530
- method='POST',
531
- url='/user-api/v1/ssh-key/add-public-key-to-user',
532
- data=request.model_dump(),
533
- token=self.__config_provider.get_config().main.thestage_auth_token,
534
- )
535
-
536
- result = AddSshKeyToUserResponse.model_validate(response) if response else None
537
- return result
538
-
539
- def is_user_has_ssh_public_key(self, public_key: str) -> IsUserHasSshPublicKeyResponse:
540
- request = IsUserHasSshPublicKeyRequest(
541
- sshKey=public_key,
542
- )
543
-
544
- response = self._request(
545
- method='POST',
546
- url='/user-api/v1/ssh-key/is-user-has-public-ssh-key',
547
- data=request.model_dump(),
548
- token=self.__config_provider.get_config().main.thestage_auth_token,
549
- )
550
-
551
- result = IsUserHasSshPublicKeyResponse.model_validate(response) if response else None
552
- return result
553
-
554
- def add_public_ssh_key_to_instance_rented(self, instance_rented_id: int,
555
- ssh_key_pair_id: int) -> AddSshPublicKeyToInstanceResponse:
556
- request = AddSshPublicKeyToInstanceRequest(
557
- instanceRentedId=instance_rented_id,
558
- sshPublicKeyId=ssh_key_pair_id,
559
- )
560
-
561
- response = self._request(
562
- method='POST',
563
- url='/user-api/v1/ssh-key/add-public-ssh-key-to-instance-rented',
564
- data=request.model_dump(),
565
- token=self.__config_provider.get_config().main.thestage_auth_token,
566
- )
567
-
568
- result = AddSshPublicKeyToInstanceResponse.model_validate(response) if response else None
569
- return result
570
-
571
- def start_project_inference_simulator(
572
- self,
573
- project_slug: str,
574
- slug: str,
575
- commit_hash: Optional[str] = None,
576
- rented_instance_unique_id: Optional[str] = None,
577
- self_hosted_instance_unique_id: Optional[str] = None,
578
- inference_dir: Optional[str] = None,
579
- is_skip_installation: Optional[bool] = False,
580
- ) -> Optional[ProjectStartInferenceSimulatorResponse]:
581
- request = ProjectStartInferenceSimulatorRequest(
582
- projectSlug=project_slug,
583
- commitHash=commit_hash,
584
- slug=slug,
585
- instanceRentedUId=rented_instance_unique_id,
586
- selfhostedInstanceUId=self_hosted_instance_unique_id,
587
- inferenceDir=inference_dir,
588
- isSkipInstallation=is_skip_installation,
589
- )
590
-
591
- response = self._request(
592
- method='POST',
593
- url='/user-api/v1/project/inference-simulator/create',
594
- data=request.model_dump(),
595
- token=self.__config_provider.get_config().main.thestage_auth_token,
596
- )
597
-
598
- return ProjectStartInferenceSimulatorResponse.model_validate(response) if response else None
599
-
600
- def push_project_inference_simulator_model(
601
- self,
602
- slug: str,
603
- ) -> Optional[ProjectPushInferenceSimulatorModelResponse]:
604
- request = ProjectPushInferenceSimulatorModelRequest(
605
- slug=slug,
606
- )
607
-
608
- response = self._request(
609
- method='POST',
610
- url='/user-api/v1/project/inference-simulator/push-model',
611
- data=request.model_dump(),
612
- token=self.__config_provider.get_config().main.thestage_auth_token,
613
- )
614
-
615
- return ProjectPushInferenceSimulatorModelResponse.model_validate(response) if response else None
616
-
617
- def get_inference_simulator_business_status_map(self) -> Optional[Dict[str, str]]:
618
- response = self._request(
619
- method='POST',
620
- url='/user-api/v1/inference-simulator/status-localized-mapping',
621
- data=None,
622
- token=self.__config_provider.get_config().main.thestage_auth_token,
623
- )
624
-
625
- data = InferenceSimulatorStatusMapperResponse.model_validate(response) if response else None
626
-
627
- return data.inference_simulator_status_map if data else None
628
-
629
- def get_inference_simulator_model_business_status_map(self) -> Optional[Dict[str, str]]:
630
- response = self._request(
631
- method='POST',
632
- url='/user-api/v1/inference-simulator-model/status-localized-mapping',
633
- data=None,
634
- token=self.__config_provider.get_config().main.thestage_auth_token,
635
- )
636
-
637
- data = InferenceSimulatorModelStatusMapperResponse.model_validate(response) if response else None
638
-
639
- return data.inference_simulator_model_status_map if data else None
640
-
641
- @error_handler()
642
- def get_inference_simulator(
643
- self,
644
- slug: str,
645
- ) -> Optional[GetInferenceSimulatorResponse]:
646
- request = GetInferenceSimulatorRequest(
647
- slug=slug,
648
- )
649
-
650
- response = self._request(
651
- method='POST',
652
- url='/user-api/v1/inference-simulator/get',
653
- data=request.model_dump(),
654
- token=self.__config_provider.get_config().main.thestage_auth_token,
655
- )
656
- return GetInferenceSimulatorResponse.model_validate(response) if response else None
657
-
658
- @error_handler()
659
- def deploy_inference_model_to_instance(
660
- self,
661
- unique_id: str,
662
- unique_id_with_timestamp: str,
663
- rented_instance_unique_id: Optional[str] = None,
664
- self_hosted_instance_unique_id: Optional[str] = None,
665
-
666
- ) -> Optional[DeployInferenceModelToInstanceResponse]:
667
- request = DeployInferenceModelToInstanceRequest(
668
- inferenceSimulatorSlug=unique_id_with_timestamp,
669
- modelSlug=unique_id,
670
- instanceRentedSlug=rented_instance_unique_id,
671
- selfhostedInstanceSlug=self_hosted_instance_unique_id
672
- )
673
-
674
- response = self._request(
675
- method='POST',
676
- url='/user-api/v1/inference-simulator-model/deploy/instance',
677
- data=request.model_dump(),
678
- token=self.__config_provider.get_config().main.thestage_auth_token,
679
- )
680
- return DeployInferenceModelToInstanceResponse.model_validate(response) if response else None
681
-
682
- @error_handler()
683
- def deploy_inference_model_to_sagemaker(
684
- self,
685
- unique_id: str,
686
- arn: Optional[str] = None,
687
- ) -> Optional[DeployInferenceModelToSagemakerResponse]:
688
- request = DeployInferenceModelToSagemakerRequest(
689
- modelSlug=unique_id,
690
- arn=arn,
691
- )
692
-
693
- response = self._request(
694
- method='POST',
695
- url='/user-api/v1/inference-simulator-model/grant-user-arn-access',
696
- data=request.model_dump(),
697
- token=self.__config_provider.get_config().main.thestage_auth_token,
698
- )
699
- return DeployInferenceModelToSagemakerResponse.model_validate(response) if response else None
700
-
701
- def query_user_logs(self, limit: int, task_id: Optional[int] = None,
702
- inference_simulator_id: Optional[int] = None,
703
- container_id: Optional[int] = None) -> UserLogsQueryResponse:
704
- request = UserLogsQueryRequest(
705
- inferenceSimulatorId=inference_simulator_id,
706
- taskId=task_id,
707
- containerId=container_id,
708
- limit=limit,
709
- ascendingOrder=False,
710
- )
711
-
712
- response = self._request(
713
- method='POST',
714
- url='/user-api/v1/logging/query-user-logs',
715
- data=request.model_dump(),
716
- token=self.__config_provider.get_config().main.thestage_auth_token,
717
- )
718
-
719
- result = UserLogsQueryResponse.model_validate(response) if response else None
720
- return result
1
+ from typing import Optional, List, Tuple, Dict, Iterator
2
+
3
+ import httpx
4
+
5
+ from thestage.helpers.error_handler import error_handler
6
+ from thestage.services.clients.thestage_api.core.api_client_core import TheStageApiClientCore
7
+ from thestage.services.clients.thestage_api.dtos.docker_container_controller.docker_container_list_request import \
8
+ DockerContainerListRequest
9
+ from thestage.services.clients.thestage_api.dtos.docker_container_controller.docker_container_list_response import \
10
+ DockerContainerListResponse
11
+ from thestage.services.clients.thestage_api.dtos.entity_filter_request import EntityFilterRequest
12
+ from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_instance_request import \
13
+ DeployInferenceModelToInstanceRequest
14
+ from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_instance_response import \
15
+ DeployInferenceModelToInstanceResponse
16
+ from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_sagemaker_request import \
17
+ DeployInferenceModelToSagemakerRequest
18
+ from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_sagemaker_response import \
19
+ DeployInferenceModelToSagemakerResponse
20
+ from thestage.services.clients.thestage_api.dtos.inference_controller.get_inference_simulator_request import \
21
+ GetInferenceSimulatorRequest
22
+ from thestage.services.clients.thestage_api.dtos.inference_controller.get_inference_simulator_response import \
23
+ 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
28
+ from thestage.services.clients.thestage_api.dtos.inference_controller.inference_simulator_model_list_for_project_request import \
29
+ InferenceSimulatorModelListForProjectRequest
30
+ from thestage.services.clients.thestage_api.dtos.inference_controller.inference_simulator_model_list_for_project_response import \
31
+ InferenceSimulatorModelListForProjectResponse
32
+ from thestage.services.clients.thestage_api.dtos.inference_simulator_model_response import \
33
+ InferenceSimulatorModelStatusMapperResponse
34
+ from thestage.services.clients.thestage_api.dtos.inference_simulator_response import \
35
+ InferenceSimulatorStatusMapperResponse
36
+ from thestage.services.clients.thestage_api.dtos.logging_controller.log_polling_request import LogPollingRequest
37
+ from thestage.services.clients.thestage_api.dtos.logging_controller.log_polling_response import LogPollingResponse
38
+ from thestage.services.clients.thestage_api.dtos.logging_controller.user_logs_query_request import UserLogsQueryRequest
39
+ from thestage.services.clients.thestage_api.dtos.logging_controller.user_logs_query_response import \
40
+ UserLogsQueryResponse
41
+ from thestage.services.clients.thestage_api.dtos.paginated_entity_list import PaginatedEntityList
42
+ from thestage.services.clients.thestage_api.dtos.project_controller.project_get_deploy_ssh_key_request import \
43
+ ProjectGetDeploySshKeyRequest
44
+ from thestage.services.clients.thestage_api.dtos.project_controller.project_get_deploy_ssh_key_response import \
45
+ ProjectGetDeploySshKeyResponse
46
+ from thestage.services.clients.thestage_api.dtos.project_controller.project_push_inference_simulator_model_request import \
47
+ ProjectPushInferenceSimulatorModelRequest
48
+ from thestage.services.clients.thestage_api.dtos.project_controller.project_push_inference_simulator_model_response import \
49
+ ProjectPushInferenceSimulatorModelResponse
50
+ from thestage.services.clients.thestage_api.dtos.project_controller.project_run_task_request import \
51
+ ProjectRunTaskRequest
52
+ from thestage.services.clients.thestage_api.dtos.project_controller.project_run_task_response import \
53
+ ProjectRunTaskResponse
54
+ from thestage.services.clients.thestage_api.dtos.project_controller.project_start_inference_simulator_request import \
55
+ ProjectStartInferenceSimulatorRequest
56
+ from thestage.services.clients.thestage_api.dtos.project_controller.project_start_inference_simulator_response import \
57
+ ProjectStartInferenceSimulatorResponse
58
+ from thestage.services.clients.thestage_api.dtos.project_response import ProjectDto, ProjectViewResponse
59
+ from thestage.services.clients.thestage_api.dtos.selfhosted_instance_response import SelfHostedInstanceListResponse, \
60
+ SelfHostedInstanceDto, SelfHostedRentedItemResponse, SelfHostedRentedRentedBusinessStatusMapperResponse
61
+ from thestage.services.clients.thestage_api.dtos.container_param_request import DockerContainerActionRequestDto
62
+ from thestage.services.clients.thestage_api.dtos.container_response import DockerContainerDto, \
63
+ DockerContainerViewResponse, ContainerBusinessStatusMapperResponse
64
+ from thestage.entities.enums.order_direction_type import OrderDirectionType
65
+ from thestage.services.clients.thestage_api.dtos.ssh_key_controller.add_ssh_key_to_user_request import \
66
+ AddSshKeyToUserRequest
67
+ from thestage.services.clients.thestage_api.dtos.ssh_key_controller.add_ssh_key_to_user_response import \
68
+ AddSshKeyToUserResponse
69
+ from thestage.services.clients.thestage_api.dtos.ssh_key_controller.add_ssh_public_key_to_instance_request import \
70
+ AddSshPublicKeyToInstanceRequest
71
+ from thestage.services.clients.thestage_api.dtos.ssh_key_controller.add_ssh_public_key_to_instance_response import \
72
+ AddSshPublicKeyToInstanceResponse
73
+ from thestage.services.clients.thestage_api.dtos.ssh_key_controller.is_user_has_public_ssh_key_request import \
74
+ IsUserHasSshPublicKeyRequest
75
+ from thestage.services.clients.thestage_api.dtos.ssh_key_controller.is_user_has_public_ssh_key_response import \
76
+ IsUserHasSshPublicKeyResponse
77
+ from thestage.services.clients.thestage_api.dtos.task_controller.task_list_for_project_request import \
78
+ TaskListForProjectRequest
79
+ from thestage.services.clients.thestage_api.dtos.task_controller.task_list_for_project_response import \
80
+ TaskListForProjectResponse
81
+ from thestage.services.clients.thestage_api.dtos.task_controller.task_status_localized_map_response import \
82
+ TaskStatusLocalizedMapResponse
83
+ from thestage.services.clients.thestage_api.dtos.task_controller.task_view_response import TaskViewResponse
84
+ from thestage.services.clients.thestage_api.dtos.instance_rented_response import InstanceRentedListResponse, \
85
+ InstanceRentedDto, InstanceRentedItemResponse, InstanceRentedBusinessStatusMapperResponse
86
+
87
+ from thestage.services.clients.thestage_api.dtos.base_response import TheStageBaseResponse
88
+ from thestage.services.config_provider.config_provider import ConfigProvider
89
+ from thestage.services.project.dto.inference_simulator_dto import InferenceSimulatorDto
90
+ from thestage.services.project.dto.inference_simulator_model_dto import InferenceSimulatorModelDto
91
+ from thestage.services.task.dto.task_dto import TaskDto
92
+
93
+
94
+ class TheStageApiClient(TheStageApiClientCore):
95
+ __config_provider: ConfigProvider = None
96
+
97
+ def __init__(
98
+ self,
99
+ config_provider: ConfigProvider,
100
+ ):
101
+ # TODO this is super bullshit, remove all abstract classes
102
+ super().__init__(url=config_provider.get_config().main.thestage_api_url)
103
+ self.__config_provider = config_provider
104
+
105
+ def get_task(
106
+ self,
107
+ task_id: int,
108
+ ) -> Optional[TaskViewResponse]:
109
+ data = {
110
+ "taskId": task_id,
111
+ }
112
+
113
+ response = self._request(
114
+ method='POST',
115
+ url='/user-api/v1/task/view',
116
+ data=data,
117
+ token=self.__config_provider.get_config().main.thestage_auth_token,
118
+ )
119
+
120
+ result = TaskViewResponse.model_validate(response) if response else None
121
+ return result if result and result.is_success else None
122
+
123
+ def get_task_list_for_project(
124
+ self,
125
+ project_slug: str,
126
+ page: int = 1,
127
+ limit: int = 10,
128
+ ) -> Optional[PaginatedEntityList[TaskDto]]:
129
+ request = TaskListForProjectRequest(
130
+ projectSlug=project_slug,
131
+ entityFilterRequest=EntityFilterRequest(
132
+ orderByField="id",
133
+ orderByDirection=OrderDirectionType.DESC,
134
+ page=page,
135
+ limit=limit,
136
+ ),
137
+ )
138
+
139
+ response = self._request(
140
+ method='POST',
141
+ url='/user-api/v1/task/list-for-project',
142
+ data=request.model_dump(),
143
+ token=self.__config_provider.get_config().main.thestage_auth_token,
144
+ )
145
+
146
+ result = TaskListForProjectResponse.model_validate(response) if response else None
147
+ return result.tasks if result and result.is_success else None
148
+
149
+ def get_inference_simulator_list_for_project(
150
+ self,
151
+ project_slug: str,
152
+ statuses: List[str] = [],
153
+ page: int = 1,
154
+ limit: int = 10,
155
+ ) -> Optional[PaginatedEntityList[InferenceSimulatorDto]]:
156
+ request = InferenceSimulatorListForProjectRequest(
157
+ projectSlug=project_slug,
158
+ statuses=statuses,
159
+ entityFilterRequest=EntityFilterRequest(
160
+ orderByField="id",
161
+ orderByDirection=OrderDirectionType.DESC,
162
+ page=page,
163
+ limit=limit,
164
+ ),
165
+ )
166
+
167
+ response = self._request(
168
+ method='POST',
169
+ url='/user-api/v1/project/inference-simulator/list',
170
+ data=request.model_dump(),
171
+ token=self.__config_provider.get_config().main.thestage_auth_token,
172
+ )
173
+ result = InferenceSimulatorListForProjectResponse.model_validate(response) if response else None
174
+ return result.inferenceSimulators if result and result.is_success else None
175
+
176
+ def get_inference_simulator_model_list_for_project(
177
+ self,
178
+ project_slug: str,
179
+ statuses: Optional[List[str]] = None,
180
+ page: int = 1,
181
+ limit: int = 10,
182
+ ) -> Optional[PaginatedEntityList[InferenceSimulatorModelDto]]:
183
+ request = InferenceSimulatorModelListForProjectRequest(
184
+ projectSlug=project_slug,
185
+ statuses=statuses,
186
+ entityFilterRequest=EntityFilterRequest(
187
+ orderByField="id",
188
+ orderByDirection=OrderDirectionType.DESC,
189
+ page=page,
190
+ limit=limit,
191
+ ),
192
+ )
193
+
194
+ response = self._request(
195
+ method='POST',
196
+ url='/user-api/v1/project/inference-simulator-model/list',
197
+ data=request.model_dump(),
198
+ token=self.__config_provider.get_config().main.thestage_auth_token,
199
+ )
200
+ result = InferenceSimulatorModelListForProjectResponse.model_validate(response) if response else None
201
+ return result.inferenceSimulatorModels if result and result.is_success else None
202
+
203
+ def get_rented_instance_list(
204
+ self,
205
+ statuses: List[str],
206
+ query: Optional[str] = None,
207
+ page: int = 1,
208
+ limit: int = 10,
209
+ ) -> PaginatedEntityList[InstanceRentedDto]:
210
+ data = {
211
+ #"statuses": [item.value for item in statuses],
212
+ "entityFilterRequest": {
213
+ "orderByField": "id",
214
+ "orderByDirection": "DESC",
215
+ "page": page,
216
+ "limit": limit
217
+ },
218
+ "queryString": query
219
+ }
220
+
221
+ if statuses:
222
+ data['businessStatuses'] = statuses
223
+
224
+ response = self._request(
225
+ method='POST',
226
+ url='/user-api/v2/instance-rented/list',
227
+ data=data,
228
+ token=self.__config_provider.get_config().main.thestage_auth_token,
229
+ )
230
+
231
+ result = InstanceRentedListResponse.model_validate(response) if response else None
232
+ return result.paginated_list if result and result.paginated_list else ([], None)
233
+
234
+ def get_rented_business_status_map(self) -> Optional[Dict[str, str]]:
235
+ response = self._request(
236
+ method='POST',
237
+ url='/user-api/v2/instance-rented/business-status-localized-map',
238
+ data=None,
239
+ token=self.__config_provider.get_config().main.thestage_auth_token,
240
+ )
241
+
242
+ data = InstanceRentedBusinessStatusMapperResponse.model_validate(response) if response else None
243
+
244
+ return data.instance_rented_business_status_map if data else None
245
+
246
+ def get_task_localized_status_map(self) -> Optional[Dict[str, str]]:
247
+ response = self._request(
248
+ method='POST',
249
+ url='/user-api/v1/task/status-localized-mapping',
250
+ data=None,
251
+ token=self.__config_provider.get_config().main.thestage_auth_token,
252
+ )
253
+
254
+ data = TaskStatusLocalizedMapResponse.model_validate(response) if response else None
255
+
256
+ return data.taskStatusMap if data else None
257
+
258
+ def get_rented_instance(
259
+ self,
260
+ instance_slug: Optional[str] = None,
261
+ instance_id: Optional[int] = None,
262
+ ) -> Optional[InstanceRentedDto]:
263
+ if not instance_slug and not instance_id:
264
+ return None
265
+
266
+ data = {
267
+ "instanceRentedSlug": instance_slug,
268
+ }
269
+
270
+ response = self._request(
271
+ method='POST',
272
+ url='/user-api/v2/instance-rented/view-by-slug',
273
+ data=data,
274
+ token=self.__config_provider.get_config().main.thestage_auth_token,
275
+ )
276
+
277
+ return InstanceRentedItemResponse.model_validate(response).instance_rented if response else None
278
+
279
+ def get_selfhosted_instance(
280
+ self,
281
+ instance_slug: Optional[str] = None,
282
+ instance_id: Optional[int] = None,
283
+ ) -> Optional[SelfHostedInstanceDto]:
284
+ if not instance_slug and not instance_id:
285
+ return None
286
+
287
+ data = {
288
+ "selfhostedInstanceSlug": instance_slug,
289
+ }
290
+
291
+ response = self._request(
292
+ method='POST',
293
+ url='/user-api/v2/self-hosted-instance/view-by-slug',
294
+ data=data,
295
+ token=self.__config_provider.get_config().main.thestage_auth_token,
296
+ )
297
+
298
+ return SelfHostedRentedItemResponse.model_validate(response).selfhosted_instance if response else None
299
+
300
+ def get_selfhosted_instance_list(
301
+ self,
302
+ statuses: List[str],
303
+ query: Optional[str] = None,
304
+ page: int = 1,
305
+ limit: int = 10,
306
+ ) -> PaginatedEntityList[SelfHostedInstanceDto]:
307
+ data = {
308
+ #"statuses": [item.value for item in statuses] if statuses else [],
309
+ "entityFilterRequest": {
310
+ "orderByField": "id",
311
+ "orderByDirection": "DESC",
312
+ "page": page,
313
+ "limit": limit
314
+ },
315
+ "queryString": query
316
+ }
317
+
318
+ if statuses:
319
+ data['businessStatuses'] = statuses
320
+
321
+ response = self._request(
322
+ method='POST',
323
+ url='/user-api/v2/self-hosted-instance/list',
324
+ data=data,
325
+ token=self.__config_provider.get_config().main.thestage_auth_token,
326
+ )
327
+
328
+ result = SelfHostedInstanceListResponse.model_validate(response) if response else None
329
+ return result.paginated_list if result and result.paginated_list else ([], None)
330
+
331
+ def get_selfhosted_business_status_map(self) -> Optional[Dict[str, str]]:
332
+ response = self._request(
333
+ method='POST',
334
+ url='/user-api/v2/self-hosted-instance/business-status-localized-map',
335
+ data=None,
336
+ token=self.__config_provider.get_config().main.thestage_auth_token,
337
+ )
338
+
339
+ data = SelfHostedRentedRentedBusinessStatusMapperResponse.model_validate(response) if response else None
340
+ return data.selfhosted_instance_business_status_map if data else None
341
+
342
+
343
+ def cancel_task(
344
+ self,
345
+ task_id: int,
346
+ ) -> Optional[TheStageBaseResponse]:
347
+ data = {
348
+ "taskId": task_id,
349
+ }
350
+
351
+ response = self._request(
352
+ method='POST',
353
+ url='/user-api/v1/task/cancel-task',
354
+ data=data,
355
+ token=self.__config_provider.get_config().main.thestage_auth_token,
356
+ )
357
+
358
+ result = TheStageBaseResponse.model_validate(response) if response else None
359
+ return result if result else None
360
+
361
+ def get_container_list(
362
+ self,
363
+ project_id: Optional[int] = None,
364
+ statuses: List[str] = [],
365
+ page: int = 1,
366
+ limit: int = 10,
367
+ ) -> PaginatedEntityList[DockerContainerDto]:
368
+ request = DockerContainerListRequest(
369
+ statuses=statuses,
370
+ projectId=project_id,
371
+ entityFilterRequest=EntityFilterRequest(
372
+ orderByField="id",
373
+ orderByDirection=OrderDirectionType.DESC,
374
+ page=page,
375
+ limit=limit,
376
+ ),
377
+ )
378
+
379
+ response = self._request(
380
+ method='POST',
381
+ url='/user-api/v1/docker-container/list',
382
+ data=request.model_dump(),
383
+ token=self.__config_provider.get_config().main.thestage_auth_token
384
+ )
385
+
386
+ result = DockerContainerListResponse.model_validate(response) if response else None
387
+ # return result.paginatedList.entities, result.paginatedList.pagination_data.total_pages if result and result.is_success else None
388
+ return result.paginatedList if result and result.is_success else None
389
+
390
+ def get_container(
391
+ self,
392
+ container_slug: Optional[str] = None,
393
+ container_id: Optional[int] = None,
394
+ ) -> 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
+ }
406
+
407
+ response = self._request(
408
+ method='POST',
409
+ url='/user-api/v1/docker-container/view',
410
+ data=data,
411
+ token=self.__config_provider.get_config().main.thestage_auth_token,
412
+ )
413
+
414
+ return DockerContainerViewResponse.model_validate(response).docker_container if response else None
415
+
416
+ def container_action(
417
+ self,
418
+ request_param: DockerContainerActionRequestDto,
419
+ ) -> TheStageBaseResponse:
420
+
421
+ response = self._request(
422
+ method='POST',
423
+ url='/user-api/v1/docker-container/action',
424
+ data=request_param.model_dump(by_alias=True),
425
+ token=self.__config_provider.get_config().main.thestage_auth_token,
426
+ )
427
+
428
+ result = TheStageBaseResponse.model_validate(response) if response else None
429
+ return result
430
+
431
+ def get_container_business_status_map(self) -> Optional[Dict[str, str]]:
432
+ response = self._request(
433
+ method='POST',
434
+ url='/user-api/v1/docker-container/status-localized-mapping',
435
+ data=None,
436
+ token=self.__config_provider.get_config().main.thestage_auth_token,
437
+ )
438
+
439
+ data = ContainerBusinessStatusMapperResponse.model_validate(response) if response else None
440
+ return data.docker_container_status_map if data else None
441
+
442
+ def get_project_by_slug(self, slug: str) -> Optional[ProjectDto]:
443
+ data = {
444
+ "projectSlug": slug,
445
+ }
446
+
447
+ response = self._request(
448
+ method='POST',
449
+ url='/user-api/v1/project/view-by-slug',
450
+ data=data,
451
+ token=self.__config_provider.get_config().main.thestage_auth_token,
452
+ )
453
+
454
+ result = ProjectViewResponse.model_validate(response) if response else None
455
+ project = ProjectDto.model_validate(result.project) if result else None
456
+ return project if result and result.is_success else None
457
+
458
+ def get_project_deploy_ssh_key(self, slug: str) -> str:
459
+ request = ProjectGetDeploySshKeyRequest(
460
+ projectSlug=slug
461
+ )
462
+
463
+ response = self._request(
464
+ method='POST',
465
+ url='/user-api/v1/project/get-deploy-ssh-key',
466
+ data=request.model_dump(),
467
+ token=self.__config_provider.get_config().main.thestage_auth_token,
468
+ )
469
+
470
+ result = ProjectGetDeploySshKeyResponse.model_validate(response) if response else None
471
+ return result.privateKey if result and result.is_success else None
472
+
473
+ def execute_project_task(
474
+ self,
475
+ project_slug: str,
476
+ run_command: str,
477
+ task_title: str,
478
+ docker_container_slug: Optional[str] = None,
479
+ commit_hash: Optional[str] = None,
480
+ ) -> Optional[ProjectRunTaskResponse]:
481
+ request = ProjectRunTaskRequest(
482
+ projectSlug=project_slug,
483
+ dockerContainerSlug=docker_container_slug,
484
+ commitHash=commit_hash,
485
+ runCommand=run_command,
486
+ taskTitle=task_title,
487
+ )
488
+
489
+ response = self._request(
490
+ method='POST',
491
+ url='/user-api/v1/project/execute-task',
492
+ data=request.model_dump(),
493
+ token=self.__config_provider.get_config().main.thestage_auth_token,
494
+ )
495
+
496
+ return ProjectRunTaskResponse.model_validate(response) if response else None
497
+
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]:
501
+ request_headers = {'Content-Type': 'application/json'}
502
+ token = self.__config_provider.get_config().main.thestage_auth_token
503
+ if token: request_headers['Authorization'] = f"Bearer {token}"
504
+
505
+ request = LogPollingRequest(
506
+ inferenceSimulatorId=inference_simulator_id,
507
+ taskId=task_id,
508
+ dockerContainerId=docker_container_id,
509
+ lastLogTimestamp=last_log_timestamp,
510
+ lastLogId=last_log_id
511
+ )
512
+
513
+ async with httpx.AsyncClient() as client:
514
+ response = await client.post(
515
+ url=f"{self._get_host()}/user-api/v1/logging/poll",
516
+ headers=request_headers,
517
+ json=request.model_dump(),
518
+ timeout=3.5
519
+ )
520
+
521
+ return LogPollingResponse.model_validate(response.json()) if response else None
522
+
523
+ def add_public_ssh_key_to_user(self, public_key: str, note: str) -> AddSshKeyToUserResponse:
524
+ request = AddSshKeyToUserRequest(
525
+ sshKey=public_key,
526
+ note=note
527
+ )
528
+
529
+ response = self._request(
530
+ method='POST',
531
+ url='/user-api/v1/ssh-key/add-public-key-to-user',
532
+ data=request.model_dump(),
533
+ token=self.__config_provider.get_config().main.thestage_auth_token,
534
+ )
535
+
536
+ result = AddSshKeyToUserResponse.model_validate(response) if response else None
537
+ return result
538
+
539
+ def is_user_has_ssh_public_key(self, public_key: str) -> IsUserHasSshPublicKeyResponse:
540
+ request = IsUserHasSshPublicKeyRequest(
541
+ sshKey=public_key,
542
+ )
543
+
544
+ response = self._request(
545
+ method='POST',
546
+ url='/user-api/v1/ssh-key/is-user-has-public-ssh-key',
547
+ data=request.model_dump(),
548
+ token=self.__config_provider.get_config().main.thestage_auth_token,
549
+ )
550
+
551
+ result = IsUserHasSshPublicKeyResponse.model_validate(response) if response else None
552
+ return result
553
+
554
+ def add_public_ssh_key_to_instance_rented(self, instance_rented_id: int,
555
+ ssh_key_pair_id: int) -> AddSshPublicKeyToInstanceResponse:
556
+ request = AddSshPublicKeyToInstanceRequest(
557
+ instanceRentedId=instance_rented_id,
558
+ sshPublicKeyId=ssh_key_pair_id,
559
+ )
560
+
561
+ response = self._request(
562
+ method='POST',
563
+ url='/user-api/v1/ssh-key/add-public-ssh-key-to-instance-rented',
564
+ data=request.model_dump(),
565
+ token=self.__config_provider.get_config().main.thestage_auth_token,
566
+ )
567
+
568
+ result = AddSshPublicKeyToInstanceResponse.model_validate(response) if response else None
569
+ return result
570
+
571
+ def start_project_inference_simulator(
572
+ self,
573
+ project_slug: str,
574
+ commit_hash: Optional[str] = None,
575
+ rented_instance_unique_id: Optional[str] = None,
576
+ self_hosted_instance_unique_id: Optional[str] = None,
577
+ inference_dir: Optional[str] = None,
578
+ is_skip_installation: Optional[bool] = False,
579
+ ) -> Optional[ProjectStartInferenceSimulatorResponse]:
580
+ request = ProjectStartInferenceSimulatorRequest(
581
+ projectSlug=project_slug,
582
+ commitHash=commit_hash,
583
+ instanceRentedUId=rented_instance_unique_id,
584
+ selfhostedInstanceUId=self_hosted_instance_unique_id,
585
+ inferenceDir=inference_dir,
586
+ isSkipInstallation=is_skip_installation,
587
+ )
588
+
589
+ response = self._request(
590
+ method='POST',
591
+ url='/user-api/v1/project/inference-simulator/create',
592
+ data=request.model_dump(),
593
+ token=self.__config_provider.get_config().main.thestage_auth_token,
594
+ )
595
+
596
+ return ProjectStartInferenceSimulatorResponse.model_validate(response) if response else None
597
+
598
+ def push_project_inference_simulator_model(
599
+ self,
600
+ slug: str,
601
+ ) -> Optional[ProjectPushInferenceSimulatorModelResponse]:
602
+ request = ProjectPushInferenceSimulatorModelRequest(
603
+ slug=slug,
604
+ )
605
+
606
+ response = self._request(
607
+ method='POST',
608
+ url='/user-api/v1/project/inference-simulator/push-model',
609
+ data=request.model_dump(),
610
+ token=self.__config_provider.get_config().main.thestage_auth_token,
611
+ )
612
+
613
+ return ProjectPushInferenceSimulatorModelResponse.model_validate(response) if response else None
614
+
615
+ def get_inference_simulator_business_status_map(self) -> Optional[Dict[str, str]]:
616
+ response = self._request(
617
+ method='POST',
618
+ url='/user-api/v1/inference-simulator/status-localized-mapping',
619
+ data=None,
620
+ token=self.__config_provider.get_config().main.thestage_auth_token,
621
+ )
622
+
623
+ data = InferenceSimulatorStatusMapperResponse.model_validate(response) if response else None
624
+
625
+ return data.inference_simulator_status_map if data else None
626
+
627
+ def get_inference_simulator_model_business_status_map(self) -> Optional[Dict[str, str]]:
628
+ response = self._request(
629
+ method='POST',
630
+ url='/user-api/v1/inference-simulator-model/status-localized-mapping',
631
+ data=None,
632
+ token=self.__config_provider.get_config().main.thestage_auth_token,
633
+ )
634
+
635
+ data = InferenceSimulatorModelStatusMapperResponse.model_validate(response) if response else None
636
+
637
+ return data.inference_simulator_model_status_map if data else None
638
+
639
+ @error_handler()
640
+ def get_inference_simulator(
641
+ self,
642
+ slug: str,
643
+ ) -> Optional[GetInferenceSimulatorResponse]:
644
+ request = GetInferenceSimulatorRequest(
645
+ slug=slug,
646
+ )
647
+
648
+ response = self._request(
649
+ method='POST',
650
+ url='/user-api/v1/inference-simulator/get',
651
+ data=request.model_dump(),
652
+ token=self.__config_provider.get_config().main.thestage_auth_token,
653
+ )
654
+ return GetInferenceSimulatorResponse.model_validate(response) if response else None
655
+
656
+ @error_handler()
657
+ def deploy_inference_model_to_instance(
658
+ 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,
663
+
664
+ ) -> Optional[DeployInferenceModelToInstanceResponse]:
665
+ 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
670
+ )
671
+
672
+ response = self._request(
673
+ method='POST',
674
+ url='/user-api/v1/inference-simulator-model/deploy/instance',
675
+ data=request.model_dump(),
676
+ token=self.__config_provider.get_config().main.thestage_auth_token,
677
+ )
678
+ return DeployInferenceModelToInstanceResponse.model_validate(response) if response else None
679
+
680
+ @error_handler()
681
+ def deploy_inference_model_to_sagemaker(
682
+ self,
683
+ unique_id: str,
684
+ arn: Optional[str] = None,
685
+ ) -> Optional[DeployInferenceModelToSagemakerResponse]:
686
+ request = DeployInferenceModelToSagemakerRequest(
687
+ modelSlug=unique_id,
688
+ arn=arn,
689
+ )
690
+
691
+ response = self._request(
692
+ method='POST',
693
+ url='/user-api/v1/inference-simulator-model/grant-user-arn-access',
694
+ data=request.model_dump(),
695
+ token=self.__config_provider.get_config().main.thestage_auth_token,
696
+ )
697
+ return DeployInferenceModelToSagemakerResponse.model_validate(response) if response else None
698
+
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:
702
+ request = UserLogsQueryRequest(
703
+ inferenceSimulatorId=inference_simulator_id,
704
+ taskId=task_id,
705
+ containerId=container_id,
706
+ limit=limit,
707
+ ascendingOrder=False,
708
+ )
709
+
710
+ response = self._request(
711
+ method='POST',
712
+ url='/user-api/v1/logging/query-user-logs',
713
+ data=request.model_dump(),
714
+ token=self.__config_provider.get_config().main.thestage_auth_token,
715
+ )
716
+
717
+ result = UserLogsQueryResponse.model_validate(response) if response else None
718
+ return result