thestage 0.6.7__py3-none-any.whl → 0.7.0__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 (202) hide show
  1. thestage/__init__.py +1 -1
  2. thestage/cli_command.py +3 -0
  3. thestage/cli_command_helper.py +2 -2
  4. thestage/config/__init__.py +1 -1
  5. thestage/{services → config/business}/app_config_service.py +3 -4
  6. thestage/{services/config_provider → config/business}/config_provider.py +6 -5
  7. thestage/config/{config_storage.py → business/config_storage.py} +1 -1
  8. thestage/{services → config/business}/validation_service.py +9 -10
  9. thestage/{controllers/config_controller.py → config/communication/config_command.py} +7 -7
  10. thestage/{services/connect → connect/business}/connect_service.py +22 -19
  11. thestage/{services → connect/business}/remote_server_service.py +4 -5
  12. thestage/connect/communication/connect_api_client.py +84 -0
  13. thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_key_to_user_response.py +0 -1
  14. thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_public_key_to_instance_response.py +1 -4
  15. thestage/{services/clients/thestage_api/dtos/base_controller → connect/dto}/connect_resolve_response.py +0 -1
  16. thestage/controllers/base_controller.py +2 -2
  17. thestage/debug_main.dist.py +16 -14
  18. thestage/{services/container → docker_container/business}/container_service.py +147 -22
  19. thestage/{services/container → docker_container/business}/mapper/container_mapper.py +3 -3
  20. thestage/docker_container/business/mapper/image_mapper.py +16 -0
  21. thestage/docker_container/communication/__init__.py +0 -0
  22. thestage/{controllers/container_controller.py → docker_container/communication/docker_command.py} +192 -29
  23. thestage/docker_container/communication/docker_container_api_client.py +139 -0
  24. thestage/docker_container/communication/image_command.py +40 -0
  25. thestage/docker_container/dto/__init__.py +0 -0
  26. thestage/docker_container/dto/container_action_request.py +11 -0
  27. thestage/{services/clients/thestage_api/dtos → docker_container/dto}/container_response.py +11 -4
  28. thestage/docker_container/dto/docker_container_create_request.py +28 -0
  29. thestage/docker_container/dto/docker_container_create_response.py +11 -0
  30. thestage/{services/clients/thestage_api/dtos/docker_container_controller → docker_container/dto}/docker_container_list_response.py +3 -5
  31. thestage/docker_container/dto/docker_image_list_request.py +11 -0
  32. thestage/docker_container/dto/docker_image_list_response.py +13 -0
  33. thestage/docker_container/dto/enum/__init__.py +0 -0
  34. thestage/docker_container/dto/image_entity.py +14 -0
  35. thestage/git/__init__.py +0 -0
  36. thestage/git/business/__init__.py +0 -0
  37. thestage/git/communication/__init__.py +0 -0
  38. thestage/{services/clients/git → git/communication}/git_client.py +4 -4
  39. thestage/global_dto/__init__.py +0 -0
  40. thestage/global_dto/enums/__init__.py +0 -0
  41. thestage/helpers/error_handler.py +4 -4
  42. thestage/helpers/logger/app_logger.py +1 -3
  43. thestage/i18n/en_GB/messages.po +14 -14
  44. thestage/inference_model/__init__.py +0 -0
  45. thestage/inference_model/business/__init__.py +0 -0
  46. thestage/inference_model/business/inference_model_service.py +281 -0
  47. thestage/inference_model/business/mapper/__init__.py +0 -0
  48. thestage/{services/project/mapper/project_inference_simulator_model_mapper.py → inference_model/business/mapper/inference_model_mapper.py} +5 -5
  49. thestage/inference_model/communication/__init__.py +0 -0
  50. thestage/inference_model/communication/inference_model_api_client.py +139 -0
  51. thestage/inference_model/communication/inference_model_command.py +246 -0
  52. thestage/inference_model/dto/__init__.py +0 -0
  53. thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_instance_response.py +0 -1
  54. thestage/inference_model/dto/enum/__init__.py +0 -0
  55. thestage/{services/project/dto/inference_simulator_model_dto.py → inference_model/dto/inference_model.py} +1 -1
  56. thestage/{entities/project_inference_simulator_model.py → inference_model/dto/inference_model_entity.py} +1 -1
  57. thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/inference_simulator_model_list_for_project_response.py +2 -3
  58. thestage/{services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_request.py → inference_model/dto/push_inference_simulator_model_request.py} +1 -1
  59. thestage/{services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_response.py → inference_model/dto/push_inference_simulator_model_response.py} +1 -1
  60. thestage/inference_simulator/__init__.py +0 -0
  61. thestage/inference_simulator/business/__init__.py +0 -0
  62. thestage/inference_simulator/business/inference_simulator_service.py +338 -0
  63. thestage/inference_simulator/business/mapper/__init__.py +0 -0
  64. thestage/{services/project/mapper/project_inference_simulator_mapper.py → inference_simulator/business/mapper/inference_simulator_mapper.py} +5 -5
  65. thestage/inference_simulator/communication/__init__.py +0 -0
  66. thestage/inference_simulator/communication/inference_simulator_api_client.py +114 -0
  67. thestage/inference_simulator/communication/inference_simulator_command.py +347 -0
  68. thestage/inference_simulator/dto/__init__.py +0 -0
  69. thestage/inference_simulator/dto/enum/__init__.py +0 -0
  70. thestage/inference_simulator/dto/get_inference_simulator_response.py +12 -0
  71. thestage/{services/project/dto/inference_simulator_dto.py → inference_simulator/dto/inference_simulator.py} +1 -1
  72. thestage/{entities/project_inference_simulator.py → inference_simulator/dto/inference_simulator_entity.py} +1 -1
  73. thestage/{services/clients/thestage_api/dtos/inference_controller → inference_simulator/dto}/inference_simulator_list_response.py +2 -2
  74. thestage/{services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_request.py → inference_simulator/dto/start_inference_simulator_request.py} +1 -1
  75. thestage/inference_simulator/dto/start_inference_simulator_response.py +10 -0
  76. thestage/instance/__init__.py +0 -0
  77. thestage/instance/business/__init__.py +0 -0
  78. thestage/{services/instance → instance/business}/instance_service.py +26 -27
  79. thestage/instance/business/mapper/__init__.py +0 -0
  80. thestage/{services/instance/mapper/instance_mapper.py → instance/business/mapper/rented_instance_mapper.py} +3 -3
  81. thestage/{services/instance/mapper/selfhosted_mapper.py → instance/business/mapper/selfhosted_instance_mapper.py} +5 -7
  82. thestage/instance/communication/__init__.py +0 -0
  83. thestage/instance/communication/instance_api_client.py +150 -0
  84. thestage/{controllers/instance_controller.py → instance/communication/instance_command.py} +5 -5
  85. thestage/instance/dto/__init__.py +0 -0
  86. thestage/instance/dto/enum/__init__.py +0 -0
  87. thestage/{services/clients/thestage_api/dtos → instance/dto}/instance_detected_gpus.py +1 -2
  88. thestage/{services/clients/thestage_api/dtos → instance/dto}/instance_rented_response.py +2 -2
  89. thestage/{services/clients/thestage_api/dtos → instance/dto}/selfhosted_instance_response.py +2 -3
  90. thestage/logging/__init__.py +0 -0
  91. thestage/logging/business/__init__.py +0 -0
  92. thestage/{services/logging → logging/business}/logging_service.py +40 -28
  93. thestage/logging/communication/__init__.py +0 -0
  94. thestage/logging/communication/logging_api_client.py +63 -0
  95. thestage/logging/dto/__init__.py +0 -0
  96. thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/log_polling_response.py +2 -2
  97. thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/user_logs_query_response.py +2 -2
  98. thestage/main.py +54 -8
  99. thestage/project/__init__.py +0 -0
  100. thestage/project/business/__init__.py +0 -0
  101. thestage/project/business/project_service.py +480 -0
  102. thestage/project/communication/__init__.py +0 -0
  103. thestage/project/communication/project_api_client.py +46 -0
  104. thestage/project/communication/project_command.py +284 -0
  105. thestage/project/dto/__init__.py +0 -0
  106. thestage/services/clients/thestage_api/core/api_client_core.py +1 -1
  107. thestage/services/clients/thestage_api/dtos/entity_filter_request.py +1 -1
  108. thestage/services/clients/thestage_api/dtos/sftp_path_helper.py +1 -1
  109. thestage/services/filesystem_service.py +2 -2
  110. thestage/services/service_factory.py +130 -43
  111. thestage/task/__init__.py +0 -0
  112. thestage/task/business/__init__.py +0 -0
  113. thestage/task/business/mapper/__init__.py +0 -0
  114. thestage/{services/project/mapper/project_task_mapper.py → task/business/mapper/task_mapper.py} +5 -5
  115. thestage/task/business/task_service.py +307 -0
  116. thestage/task/communication/__init__.py +0 -0
  117. thestage/task/communication/task_api_client.py +122 -0
  118. thestage/task/communication/task_command.py +212 -0
  119. thestage/task/dto/__init__.py +0 -0
  120. thestage/task/dto/enum/__init__.py +0 -0
  121. thestage/{services/clients/thestage_api/dtos/task_controller/task_list_for_project_response.py → task/dto/list_for_project_response.py} +2 -2
  122. thestage/{services/clients/thestage_api/dtos/project_controller/project_run_task_request.py → task/dto/run_task_request.py} +1 -1
  123. thestage/task/dto/run_task_response.py +13 -0
  124. thestage/{services/task/dto/task_dto.py → task/dto/task.py} +1 -4
  125. thestage/{entities/project_task.py → task/dto/task_entity.py} +1 -1
  126. thestage/{services/clients/thestage_api/dtos/task_controller/task_view_response.py → task/dto/view_response.py} +2 -2
  127. {thestage-0.6.7.dist-info → thestage-0.7.0.dist-info}/METADATA +1 -1
  128. thestage-0.7.0.dist-info/RECORD +226 -0
  129. {thestage-0.6.7.dist-info → thestage-0.7.0.dist-info}/WHEEL +1 -1
  130. thestage/controllers/project_controller.py +0 -1056
  131. thestage/services/clients/thestage_api/api_client.py +0 -751
  132. thestage/services/clients/thestage_api/dtos/container_param_request.py +0 -11
  133. thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_response.py +0 -13
  134. thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_response.py +0 -13
  135. thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_response.py +0 -10
  136. thestage/services/clients/thestage_api/dtos/user_controller/user_profile.py +0 -12
  137. thestage/services/project/project_service.py +0 -1287
  138. thestage-0.6.7.dist-info/RECORD +0 -167
  139. /thestage/{entities → color_scheme}/__init__.py +0 -0
  140. /thestage/{entities/enums → config/business}/__init__.py +0 -0
  141. /thestage/{services/clients/git → config/communication}/__init__.py +0 -0
  142. /thestage/{services/clients/thestage_api/dtos/enums → config/dto}/__init__.py +0 -0
  143. /thestage/{services/core_files → config/dto}/config_entity.py +0 -0
  144. /thestage/{services/connect → config}/dto/remote_server_config.py +0 -0
  145. /thestage/{services/config_provider → connect}/__init__.py +0 -0
  146. /thestage/{services/container → connect/business}/__init__.py +0 -0
  147. /thestage/{services/container/mapper → connect/communication}/__init__.py +0 -0
  148. /thestage/{services/instance → connect/dto}/__init__.py +0 -0
  149. /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_key_to_user_request.py +0 -0
  150. /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_public_key_to_instance_request.py +0 -0
  151. /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/is_user_has_public_ssh_key_request.py +0 -0
  152. /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/is_user_has_public_ssh_key_response.py +0 -0
  153. /thestage/{services/instance/mapper → docker_container}/__init__.py +0 -0
  154. /thestage/{services/project → docker_container/business}/__init__.py +0 -0
  155. /thestage/{services/project → docker_container/business}/mapper/__init__.py +0 -0
  156. /thestage/{entities/container.py → docker_container/dto/container_entity.py} +0 -0
  157. /thestage/{services/clients/thestage_api/dtos/docker_container_controller → docker_container/dto}/docker_container_list_request.py +0 -0
  158. /thestage/{services/clients/thestage_api/dtos → docker_container/dto}/docker_container_mapping.py +0 -0
  159. /thestage/{services/clients/thestage_api/dtos/enums → docker_container/dto/enum}/container_pending_action.py +0 -0
  160. /thestage/{services/clients/thestage_api/dtos/enums → docker_container/dto/enum}/container_status.py +0 -0
  161. /thestage/{services/logging/exception → exceptions}/log_polling_exception.py +0 -0
  162. /thestage/git/{ProgressPrinter.py → business/ProgressPrinter.py} +0 -0
  163. /thestage/{entities → global_dto}/enums/order_direction_type.py +0 -0
  164. /thestage/{entities → global_dto}/enums/shell_type.py +0 -0
  165. /thestage/{entities → global_dto}/enums/tail_output_type.py +0 -0
  166. /thestage/{entities → global_dto}/enums/yes_no_response.py +0 -0
  167. /thestage/{entities → global_dto}/file_item.py +0 -0
  168. /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_instance_request.py +0 -0
  169. /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_sagemaker_request.py +0 -0
  170. /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_sagemaker_response.py +0 -0
  171. /thestage/{services/clients/thestage_api/dtos/enums → inference_model/dto/enum}/inference_model_status.py +0 -0
  172. /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/inference_simulator_model_list_for_project_request.py +0 -0
  173. /thestage/{services/clients/thestage_api/dtos → inference_model/dto}/inference_simulator_model_response.py +0 -0
  174. /thestage/{services/clients/thestage_api/dtos/enums → inference_simulator/dto/enum}/inference_simulator_status.py +0 -0
  175. /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_simulator/dto}/get_inference_simulator_request.py +0 -0
  176. /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_simulator/dto}/inference_simulator_list_request.py +0 -0
  177. /thestage/{services/clients/thestage_api/dtos → inference_simulator/dto}/inference_simulator_response.py +0 -0
  178. /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/cpu_type.py +0 -0
  179. /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/gpu_name.py +0 -0
  180. /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/instance_rented_status.py +0 -0
  181. /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/provider_name.py +0 -0
  182. /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/selfhosted_status.py +0 -0
  183. /thestage/{entities → instance/dto}/rented_instance.py +0 -0
  184. /thestage/{entities → instance/dto}/self_hosted_instance.py +0 -0
  185. /thestage/{services/logging → logging}/byte_print_style.py +0 -0
  186. /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/docker_container_log_stream_request.py +0 -0
  187. /thestage/{services/logging → logging}/dto/log_message.py +0 -0
  188. /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/log_polling_request.py +0 -0
  189. /thestage/{services/logging → logging}/dto/log_type.py +0 -0
  190. /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/task_log_stream_request.py +0 -0
  191. /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/user_logs_query_request.py +0 -0
  192. /thestage/{services/logging → logging}/logging_constants.py +0 -0
  193. /thestage/{services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_request.py → project/dto/get_deploy_ssh_key_request.py} +0 -0
  194. /thestage/{services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_response.py → project/dto/get_deploy_ssh_key_response.py} +0 -0
  195. /thestage/{services/project → project}/dto/project_config.py +0 -0
  196. /thestage/{services/clients/thestage_api/dtos → project/dto}/project_response.py +0 -0
  197. /thestage/{services/clients/thestage_api/dtos/enums → task/dto/enum}/task_execution_status.py +0 -0
  198. /thestage/{services/clients/thestage_api/dtos/enums → task/dto/enum}/task_status.py +0 -0
  199. /thestage/{services/clients/thestage_api/dtos/task_controller/task_list_for_project_request.py → task/dto/list_for_project_request.py} +0 -0
  200. /thestage/{services/clients/thestage_api/dtos/task_controller/task_status_localized_map_response.py → task/dto/status_localized_map_response.py} +0 -0
  201. {thestage-0.6.7.dist-info → thestage-0.7.0.dist-info}/entry_points.txt +0 -0
  202. {thestage-0.6.7.dist-info → thestage-0.7.0.dist-info}/licenses/LICENSE.txt +0 -0
@@ -1,17 +1,17 @@
1
1
  from typing import Optional
2
2
 
3
- from thestage.entities.project_inference_simulator import ProjectInferenceSimulatorEntity
3
+ from thestage.inference_simulator.dto.inference_simulator_entity import InferenceSimulatorEntity
4
4
  from thestage.services.abstract_mapper import AbstractMapper
5
- from thestage.services.project.dto.inference_simulator_dto import InferenceSimulatorDto
5
+ from thestage.inference_simulator.dto.inference_simulator import InferenceSimulator
6
6
 
7
7
 
8
- class ProjectInferenceSimulatorMapper(AbstractMapper):
8
+ class InferenceSimulatorMapper(AbstractMapper):
9
9
 
10
- def build_entity(self, item: InferenceSimulatorDto) -> Optional[ProjectInferenceSimulatorEntity]:
10
+ def build_entity(self, item: InferenceSimulator) -> Optional[InferenceSimulatorEntity]:
11
11
  if not item:
12
12
  return None
13
13
 
14
- return ProjectInferenceSimulatorEntity(
14
+ return InferenceSimulatorEntity(
15
15
  public_id=item.public_id or '',
16
16
  slug=item.slug or '',
17
17
  status=item.status or '',
File without changes
@@ -0,0 +1,114 @@
1
+ from typing import Optional, List, Dict
2
+
3
+ from thestage.config.business.config_provider import ConfigProvider
4
+ from thestage.global_dto.enums.order_direction_type import OrderDirectionType
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.entity_filter_request import EntityFilterRequest
8
+ from thestage.services.clients.thestage_api.dtos.paginated_entity_list import PaginatedEntityList
9
+
10
+ from thestage.inference_simulator.dto.inference_simulator import InferenceSimulator
11
+ from thestage.inference_simulator.dto.inference_simulator_list_request import InferenceSimulatorListRequest
12
+ from thestage.inference_simulator.dto.inference_simulator_list_response import InferenceSimulatorListResponse
13
+ from thestage.inference_simulator.dto.start_inference_simulator_request import StartInferenceSimulatorRequest
14
+ from thestage.inference_simulator.dto.start_inference_simulator_response import StartInferenceSimulatorResponse
15
+ from thestage.inference_simulator.dto.inference_simulator_response import InferenceSimulatorStatusMapperResponse
16
+ from thestage.inference_simulator.dto.get_inference_simulator_request import GetInferenceSimulatorRequest
17
+ from thestage.inference_simulator.dto.get_inference_simulator_response import GetInferenceSimulatorResponse
18
+
19
+
20
+ class InferenceSimulatorApiClient(TheStageApiClientCore):
21
+ def __init__(self, config_provider: ConfigProvider):
22
+ super().__init__(url=config_provider.get_config().main.thestage_api_url)
23
+ self.__config_provider = config_provider
24
+
25
+ def get_inference_simulator_list(
26
+ self,
27
+ project_public_id: Optional[str],
28
+ project_slug: Optional[str],
29
+ statuses: List[str] = [],
30
+ page: int = 1,
31
+ limit: int = 10,
32
+ ) -> Optional[PaginatedEntityList[InferenceSimulator]]:
33
+ request = InferenceSimulatorListRequest(
34
+ projectPublicId=project_public_id,
35
+ projectSlug=project_slug,
36
+ statuses=statuses,
37
+ entityFilterRequest=EntityFilterRequest(
38
+ orderByField="createdAt",
39
+ orderByDirection=OrderDirectionType.DESC,
40
+ page=page,
41
+ limit=limit,
42
+ ),
43
+ )
44
+
45
+ response = self._request(
46
+ method='POST',
47
+ url='/user-api/v2/inference-simulator/list',
48
+ data=request.model_dump(),
49
+ token=self.__config_provider.get_config().main.thestage_auth_token,
50
+ )
51
+ result = InferenceSimulatorListResponse.model_validate(response) if response else None
52
+ return result.inferenceSimulators if result and result.is_success else None
53
+
54
+ def start_project_inference_simulator(
55
+ self,
56
+ project_public_id: str,
57
+ commit_hash: Optional[str] = None,
58
+ rented_instance_public_id: Optional[str] = None,
59
+ rented_instance_slug: Optional[str] = None,
60
+ self_hosted_instance_public_id: Optional[str] = None,
61
+ self_hosted_instance_slug: Optional[str] = None,
62
+ inference_dir: Optional[str] = None,
63
+ is_skip_installation: Optional[bool] = False,
64
+ ) -> Optional[StartInferenceSimulatorResponse]:
65
+ request = StartInferenceSimulatorRequest(
66
+ projectPublicId=project_public_id,
67
+ commitHash=commit_hash,
68
+ instanceRentedPublicId=rented_instance_public_id,
69
+ instanceRentedSlug=rented_instance_slug,
70
+ selfhostedInstancePublicId=self_hosted_instance_public_id,
71
+ selfhostedInstanceSlug=self_hosted_instance_slug,
72
+ inferenceDir=inference_dir,
73
+ isSkipInstallation=is_skip_installation,
74
+ )
75
+
76
+ response = self._request(
77
+ method='POST',
78
+ url='/user-api/v2/project/inference-simulator/create',
79
+ data=request.model_dump(),
80
+ token=self.__config_provider.get_config().main.thestage_auth_token,
81
+ )
82
+
83
+ return StartInferenceSimulatorResponse.model_validate(response) if response else None
84
+
85
+ def get_inference_simulator_business_status_map(self) -> Optional[Dict[str, str]]:
86
+ response = self._request(
87
+ method='POST',
88
+ url='/user-api/v1/inference-simulator/status-localized-mapping',
89
+ data=None,
90
+ token=self.__config_provider.get_config().main.thestage_auth_token,
91
+ )
92
+
93
+ data = InferenceSimulatorStatusMapperResponse.model_validate(response) if response else None
94
+
95
+ return data.inference_simulator_status_map if data else None
96
+
97
+ @error_handler()
98
+ def get_inference_simulator(
99
+ self,
100
+ public_id: Optional[str] = None,
101
+ slug: Optional[str] = None,
102
+ ) -> Optional[GetInferenceSimulatorResponse]:
103
+ request = GetInferenceSimulatorRequest(
104
+ publicId=public_id,
105
+ slug=slug,
106
+ )
107
+
108
+ response = self._request(
109
+ method='POST',
110
+ url='/user-api/v2/inference-simulator/get',
111
+ data=request.model_dump(),
112
+ token=self.__config_provider.get_config().main.thestage_auth_token,
113
+ )
114
+ return GetInferenceSimulatorResponse.model_validate(response) if response else None
@@ -0,0 +1,347 @@
1
+ from pathlib import Path
2
+ from typing import Optional, List
3
+
4
+ import typer
5
+
6
+ from thestage.cli_command import CliCommand
7
+ from thestage.cli_command_helper import get_command_metadata, check_command_permission
8
+ from thestage.controllers.utils_controller import validate_config_and_get_service_factory, get_current_directory
9
+ from thestage.helpers.logger.app_logger import app_logger
10
+ from thestage.i18n.translation import __
11
+ from thestage.inference_simulator.dto.get_inference_simulator_response import GetInferenceSimulatorResponse
12
+ from thestage.logging.business.logging_service import LoggingService
13
+
14
+ app = typer.Typer(no_args_is_help=True, help="Manage project inference simulators")
15
+
16
+ @app.command(name='run', no_args_is_help=True, help="Run inference simulator within the project", **get_command_metadata(CliCommand.PROJECT_INFERENCE_SIMULATOR_RUN))
17
+ def run_inference_simulator(
18
+ rented_instance_public_id: Optional[str] = typer.Option(
19
+ None,
20
+ '--rented-instance-id',
21
+ '-rid',
22
+ help=__("Rented instance ID on which the inference simulator will run"),
23
+ is_eager=False,
24
+ ),
25
+ rented_instance_slug: Optional[str] = typer.Option(
26
+ None,
27
+ '--rented-instance-name',
28
+ '-rn',
29
+ help=__("Rented instance name on which the inference simulator will run"),
30
+ is_eager=False,
31
+ ),
32
+ self_hosted_instance_public_id: Optional[str] = typer.Option(
33
+ None,
34
+ '--self-hosted-instance-id',
35
+ '-sid',
36
+ help=__("Self-hosted instance ID on which the inference simulator will run"),
37
+ is_eager=False,
38
+ ),
39
+ self_hosted_instance_slug: Optional[str] = typer.Option(
40
+ None,
41
+ '--self-hosted-instance-name',
42
+ '-sn',
43
+ help=__("Self-hosted instance name on which the inference simulator will run"),
44
+ is_eager=False,
45
+ ),
46
+ commit_hash: Optional[str] = typer.Option(
47
+ None,
48
+ '--commit-hash',
49
+ '-hash',
50
+ help=__("Commit hash to use. By default, the current HEAD commit is used."),
51
+ is_eager=False,
52
+ ),
53
+ working_directory: Optional[str] = typer.Option(
54
+ None,
55
+ "--working-directory",
56
+ "-wd",
57
+ help=__("Full path to working directory. By default, the current directory is used"),
58
+ show_default=False,
59
+ is_eager=False,
60
+ ),
61
+ enable_log_stream: Optional[bool] = typer.Option(
62
+ True,
63
+ "--no-logs",
64
+ "-nl",
65
+ help=__("Disable real-time log streaming"),
66
+ is_eager=False,
67
+ ),
68
+ is_skip_installation: Optional[bool] = typer.Option(
69
+ False,
70
+ "--skip-installation",
71
+ "-si",
72
+ help=__("Skip installing dependencies from requirements.txt and install.sh"),
73
+ is_eager=False,
74
+ ),
75
+ files_to_add: Optional[str] = typer.Option(
76
+ None,
77
+ "--files-add",
78
+ "-fa",
79
+ help=__("Files to add to the commit. You can add files by their relative path from the working directory with a comma as a separator."),
80
+ is_eager=False,
81
+ ),
82
+ is_skip_auto_commit: Optional[bool] = typer.Option(
83
+ False,
84
+ "--skip-autocommit",
85
+ "-sa",
86
+ help=__("Skip automatic commit of the changes"),
87
+ is_eager=False,
88
+ ),
89
+ ):
90
+ command_name = CliCommand.PROJECT_INFERENCE_SIMULATOR_RUN
91
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
92
+ check_command_permission(command_name)
93
+
94
+ service_factory = validate_config_and_get_service_factory(working_directory=working_directory)
95
+ config = service_factory.get_config_provider().get_config()
96
+
97
+ working_dir_path = Path(working_directory) if working_directory else Path(config.runtime.working_directory)
98
+ inference_files = list(working_dir_path.rglob("inference.py"))
99
+ if not inference_files:
100
+ typer.echo("No inference.py file found in the project directory.")
101
+ raise typer.Exit(1)
102
+ elif len(inference_files) == 1:
103
+ selected_inference = inference_files[0]
104
+ else:
105
+ choices = [str(path.relative_to(working_dir_path)) for path in inference_files]
106
+ typer.echo("Multiple inference.py files found:")
107
+ for idx, choice in enumerate(choices, start=1):
108
+ typer.echo(f"{idx}) {choice}")
109
+ choice_str = typer.prompt("Choose which inference.py to use")
110
+ try:
111
+ choice_index = int(choice_str)
112
+ except ValueError:
113
+ raise typer.BadParameter("Invalid input. Enter a number.")
114
+ if not (1 <= choice_index <= len(choices)):
115
+ raise typer.BadParameter("Choice out of range.")
116
+ selected_inference = inference_files[choice_index - 1]
117
+
118
+ relative_inference = selected_inference.relative_to(working_dir_path)
119
+ parent_dir = relative_inference.parent
120
+ if parent_dir == Path("../../controllers"):
121
+ inference_dir = "/"
122
+ else:
123
+ inference_dir = f"{parent_dir.as_posix()}/"
124
+ typer.echo(f"Selected inference file relative path: {inference_dir}")
125
+
126
+ inference_simulator_service = service_factory.get_inference_simulator_service()
127
+
128
+ inference_simulator = inference_simulator_service.project_run_inference_simulator(
129
+ commit_hash=commit_hash,
130
+ rented_instance_public_id=rented_instance_public_id,
131
+ rented_instance_slug=rented_instance_slug,
132
+ self_hosted_instance_public_id=self_hosted_instance_public_id,
133
+ self_hosted_instance_slug=self_hosted_instance_slug,
134
+ inference_dir=inference_dir,
135
+ is_skip_installation=is_skip_installation,
136
+ files_to_add=files_to_add,
137
+ is_skip_auto_commit=is_skip_auto_commit,
138
+ )
139
+
140
+ if enable_log_stream:
141
+ logging_service: LoggingService = service_factory.get_logging_service()
142
+
143
+ logging_service.stream_inference_simulator_logs_with_controls(
144
+ slug=inference_simulator.slug
145
+ )
146
+ raise typer.Exit(0)
147
+
148
+
149
+ @app.command(name='save-metadata', no_args_is_help=True, help="Save inference simulator metadata", **get_command_metadata(CliCommand.PROJECT_INFERENCE_SIMULATOR_SAVE_METADATA))
150
+ def get_and_save_inference_simulator_metadata(
151
+ inference_simulator_public_id: Optional[str] = typer.Option(
152
+ None,
153
+ '--inference-simulator-id',
154
+ '-isid',
155
+ help=__("Inference simulator ID"),
156
+ is_eager=False,
157
+ ),
158
+ inference_simulator_slug: Optional[str] = typer.Option(
159
+ None,
160
+ '--inference-simulator-name',
161
+ '-isn',
162
+ help=__("Inference simulator name"),
163
+ is_eager=False,
164
+ ),
165
+ file_path: Optional[str] = typer.Option(
166
+ None,
167
+ "--file-path",
168
+ "-fp",
169
+ help=__("Full path to a new file. By default metadata is saved to the current directory as metadata.json"),
170
+ show_default=False,
171
+ is_eager=False,
172
+ ),
173
+ ):
174
+ command_name = CliCommand.PROJECT_INFERENCE_SIMULATOR_SAVE_METADATA
175
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
176
+ check_command_permission(command_name)
177
+
178
+ if sum(v is not None for v in [inference_simulator_public_id, inference_simulator_slug]) != 1:
179
+ typer.echo("Provide a single identifier for inference simulator - ID or name.")
180
+ raise typer.Exit(1)
181
+
182
+ service_factory = validate_config_and_get_service_factory()
183
+ inference_simulator_service = service_factory.get_inference_simulator_service()
184
+
185
+ inference_simulator_service.project_get_and_save_inference_simulator_metadata(
186
+ file_path=file_path,
187
+ inference_simulator_public_id=inference_simulator_public_id,
188
+ inference_simulator_slug=inference_simulator_slug,
189
+ )
190
+
191
+ raise typer.Exit(0)
192
+
193
+
194
+ @app.command(name='push', no_args_is_help=True, help="Push inference simulator to model registry", **get_command_metadata(CliCommand.PROJECT_INFERENCE_SIMULATOR_PUSH))
195
+ def push_inference_simulator(
196
+ inference_simulator_public_id: Optional[str] = typer.Option(
197
+ None,
198
+ '--inference-simulator-id',
199
+ '-isid',
200
+ help=__("Inference simulator ID"),
201
+ is_eager=False,
202
+ ),
203
+ inference_simulator_slug: Optional[str] = typer.Option(
204
+ None,
205
+ '--inference-simulator-name',
206
+ '-isn',
207
+ help=__("Inference simulator name"),
208
+ is_eager=False,
209
+ ),
210
+ ):
211
+ command_name = CliCommand.PROJECT_INFERENCE_SIMULATOR_PUSH
212
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
213
+ check_command_permission(command_name)
214
+
215
+ if sum(v is not None for v in [inference_simulator_public_id, inference_simulator_slug]) != 1:
216
+ typer.echo("Provide a single identifier for inference simulator - ID or name.")
217
+ raise typer.Exit(1)
218
+
219
+ service_factory = validate_config_and_get_service_factory()
220
+ inference_simulator_service = service_factory.get_inference_simulator_service()
221
+
222
+ inference_simulator_service.project_push_inference_simulator(
223
+ public_id=inference_simulator_public_id,
224
+ slug=inference_simulator_slug,
225
+ )
226
+
227
+ raise typer.Exit(0)
228
+
229
+
230
+ @app.command("ls", help=__("List inference simulators"), **get_command_metadata(CliCommand.PROJECT_INFERENCE_SIMULATOR_LS))
231
+ def list_inference_simulators(
232
+ project_public_id: Optional[str] = typer.Option(
233
+ None,
234
+ '--project-id',
235
+ '-pid',
236
+ help=__("Project ID. By default, project info is taken from the current directory"),
237
+ is_eager=False,
238
+ ),
239
+ project_slug: Optional[str] = typer.Option(
240
+ None,
241
+ '--project-name',
242
+ '-pn',
243
+ help=__("Project name. By default, project info is taken from the current directory"),
244
+ is_eager=False,
245
+ ),
246
+ row: int = typer.Option(
247
+ 5,
248
+ '--row',
249
+ '-r',
250
+ help=__("Set number of rows displayed per page"),
251
+ is_eager=False,
252
+ ),
253
+ page: int = typer.Option(
254
+ 1,
255
+ '--page',
256
+ '-p',
257
+ help=__("Set starting page for displaying output"),
258
+ is_eager=False,
259
+ ),
260
+ statuses: List[str] = typer.Option(
261
+ None,
262
+ '--status',
263
+ '-s',
264
+ help=__("Filter by status, use --status all to list all inference simulators"),
265
+ is_eager=False,
266
+ ),
267
+ ):
268
+ command_name = CliCommand.PROJECT_INFERENCE_SIMULATOR_LS
269
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
270
+ check_command_permission(command_name)
271
+
272
+ if sum(v is not None for v in [project_public_id, project_slug]) > 1:
273
+ typer.echo("Provide a single identifier for project - ID or name.")
274
+ raise typer.Exit(1)
275
+
276
+ service_factory = validate_config_and_get_service_factory()
277
+ inference_simulator_service = service_factory.get_inference_simulator_service()
278
+
279
+ inference_simulator_service.print_inference_simulator_list(
280
+ project_public_id=project_public_id,
281
+ project_slug=project_slug,
282
+ statuses=statuses,
283
+ row=row,
284
+ page=page
285
+ )
286
+
287
+ typer.echo(__("Inference simulators listing complete"))
288
+ raise typer.Exit(0)
289
+
290
+ @app.command(name="logs", no_args_is_help=True, help=__("Stream real-time inference simulator logs or view last logs for an inference simulator"), **get_command_metadata(CliCommand.PROJECT_INFERENCE_SIMULATOR_LOGS))
291
+ def inference_simulator_logs(
292
+ #TODO doesn't work with public_id
293
+ public_id: Optional[str] = typer.Option(
294
+ None,
295
+ '--inference-simulator-id',
296
+ '-isid',
297
+ help="Inference simulator ID",
298
+ is_eager=False,
299
+ ),
300
+ slug: Optional[str] = typer.Option(
301
+ None,
302
+ '--inference-simulator-name',
303
+ '-isn',
304
+ help="Inference simulator name",
305
+ is_eager=False,
306
+ ),
307
+ logs_number: Optional[int] = typer.Option(
308
+ None,
309
+ '--number',
310
+ '-n',
311
+ help=__("Display a number of latest log entries. No real-time stream if provided."),
312
+ is_eager=False,
313
+ ),
314
+ ):
315
+ command_name = CliCommand.PROJECT_INFERENCE_SIMULATOR_LOGS
316
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
317
+ check_command_permission(command_name)
318
+
319
+ if sum(v is not None for v in [public_id, slug]) != 1:
320
+ typer.echo("Provide a single identifier for inference simulator - ID or name.")
321
+ raise typer.Exit(1)
322
+
323
+ service_factory = validate_config_and_get_service_factory()
324
+ logging_service: LoggingService = service_factory.get_logging_service()
325
+
326
+ if logs_number is None:
327
+ logging_service.stream_inference_simulator_logs_with_controls(
328
+ public_id=public_id,
329
+ slug=slug,
330
+ )
331
+ else:
332
+ inference_simulator_api_client = service_factory.get_inference_simulator_api_client()
333
+
334
+ get_inference_simulator_response: Optional[
335
+ GetInferenceSimulatorResponse] = inference_simulator_api_client.get_inference_simulator(
336
+ public_id=public_id,
337
+ slug=slug,
338
+ )
339
+ if not get_inference_simulator_response:
340
+ typer.echo("Inference simulator not found")
341
+ raise typer.Exit(1)
342
+ else:
343
+ inference_simulator_public_id = get_inference_simulator_response.inferenceSimulator.public_id
344
+ logging_service.print_last_inference_simulator_logs(inference_simulator_public_id=inference_simulator_public_id, logs_number=logs_number)
345
+
346
+ app_logger.info(f'Inference simulator log streaming completed')
347
+ raise typer.Exit(0)
File without changes
File without changes
@@ -0,0 +1,12 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import Field, ConfigDict, BaseModel
4
+
5
+ from thestage.inference_simulator.dto.inference_simulator import InferenceSimulator
6
+
7
+
8
+ class GetInferenceSimulatorResponse(BaseModel):
9
+ model_config = ConfigDict(use_enum_values=True)
10
+ inferenceSimulator: Optional[InferenceSimulator] = Field(None, alias='inferenceSimulator')
11
+
12
+
@@ -1,7 +1,7 @@
1
1
  from typing import Optional, Any, Dict
2
2
  from pydantic import BaseModel, ConfigDict, Field
3
3
 
4
- class InferenceSimulatorDto(BaseModel):
4
+ class InferenceSimulator(BaseModel):
5
5
  model_config = ConfigDict(use_enum_values=True)
6
6
 
7
7
  public_id: Optional[str] = Field(None, alias="publicId")
@@ -3,7 +3,7 @@ from typing import Optional
3
3
  from pydantic import BaseModel, ConfigDict, Field
4
4
 
5
5
 
6
- class ProjectInferenceSimulatorEntity(BaseModel):
6
+ class InferenceSimulatorEntity(BaseModel):
7
7
 
8
8
  model_config = ConfigDict(
9
9
  populate_by_name=True,
@@ -3,10 +3,10 @@ from pydantic import Field, ConfigDict
3
3
 
4
4
  from thestage.services.clients.thestage_api.dtos.base_response import TheStageBaseResponse
5
5
  from thestage.services.clients.thestage_api.dtos.paginated_entity_list import PaginatedEntityList
6
- from thestage.services.project.dto.inference_simulator_dto import InferenceSimulatorDto
6
+ from thestage.inference_simulator.dto.inference_simulator import InferenceSimulator
7
7
 
8
8
 
9
9
  class InferenceSimulatorListResponse(TheStageBaseResponse):
10
10
  model_config = ConfigDict(use_enum_values=True)
11
11
 
12
- inferenceSimulators: PaginatedEntityList[InferenceSimulatorDto] = Field(None, alias='inferenceSimulators')
12
+ inferenceSimulators: PaginatedEntityList[InferenceSimulator] = Field(None, alias='inferenceSimulators')
@@ -3,7 +3,7 @@ from typing import Optional
3
3
  from pydantic import Field, ConfigDict, BaseModel
4
4
 
5
5
 
6
- class ProjectStartInferenceSimulatorRequest(BaseModel):
6
+ class StartInferenceSimulatorRequest(BaseModel):
7
7
  model_config = ConfigDict(use_enum_values=True)
8
8
 
9
9
  projectPublicId: str = Field(None, alias='projectPublicId')
@@ -0,0 +1,10 @@
1
+ from pydantic import Field, ConfigDict
2
+
3
+ from thestage.services.clients.thestage_api.dtos.base_response import TheStageBaseResponse
4
+ from thestage.inference_simulator.dto.inference_simulator import InferenceSimulator
5
+
6
+
7
+ class StartInferenceSimulatorResponse(TheStageBaseResponse):
8
+ model_config = ConfigDict(use_enum_values=True)
9
+
10
+ inferenceSimulator: InferenceSimulator = Field(None, alias='inferenceSimulator')
File without changes
File without changes