thestage 0.6.7__py3-none-any.whl → 0.6.8__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.
- thestage/__init__.py +1 -1
- thestage/cli_command_helper.py +2 -2
- thestage/config/__init__.py +1 -1
- thestage/{services → config/business}/app_config_service.py +3 -4
- thestage/{services/config_provider → config/business}/config_provider.py +6 -5
- thestage/config/{config_storage.py → business/config_storage.py} +1 -1
- thestage/{services → config/business}/validation_service.py +9 -10
- thestage/{controllers/config_controller.py → config/communication/config_command.py} +7 -7
- thestage/{services/connect → connect/business}/connect_service.py +22 -19
- thestage/{services → connect/business}/remote_server_service.py +4 -5
- thestage/connect/communication/connect_api_client.py +84 -0
- thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_key_to_user_response.py +0 -1
- thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_public_key_to_instance_response.py +1 -4
- thestage/{services/clients/thestage_api/dtos/base_controller → connect/dto}/connect_resolve_response.py +0 -1
- thestage/controllers/base_controller.py +2 -2
- thestage/debug_main.dist.py +16 -14
- thestage/{services/container → docker_container/business}/container_service.py +27 -22
- thestage/{services/container → docker_container/business}/mapper/container_mapper.py +3 -3
- thestage/docker_container/communication/__init__.py +0 -0
- thestage/{controllers/container_controller.py → docker_container/communication/docker_command.py} +17 -23
- thestage/docker_container/communication/docker_container_api_client.py +99 -0
- thestage/docker_container/dto/__init__.py +0 -0
- thestage/docker_container/dto/container_action_request.py +11 -0
- thestage/{services/clients/thestage_api/dtos → docker_container/dto}/container_response.py +4 -4
- thestage/{services/clients/thestage_api/dtos/docker_container_controller → docker_container/dto}/docker_container_list_response.py +3 -5
- thestage/docker_container/dto/enum/__init__.py +0 -0
- thestage/git/__init__.py +0 -0
- thestage/git/business/__init__.py +0 -0
- thestage/git/communication/__init__.py +0 -0
- thestage/{services/clients/git → git/communication}/git_client.py +4 -4
- thestage/global_dto/__init__.py +0 -0
- thestage/global_dto/enums/__init__.py +0 -0
- thestage/helpers/error_handler.py +3 -3
- thestage/helpers/logger/app_logger.py +1 -3
- thestage/i18n/en_GB/messages.po +14 -14
- thestage/inference_model/__init__.py +0 -0
- thestage/inference_model/business/__init__.py +0 -0
- thestage/inference_model/business/inference_model_service.py +281 -0
- thestage/inference_model/business/mapper/__init__.py +0 -0
- thestage/{services/project/mapper/project_inference_simulator_model_mapper.py → inference_model/business/mapper/inference_model_mapper.py} +5 -5
- thestage/inference_model/communication/__init__.py +0 -0
- thestage/inference_model/communication/inference_model_api_client.py +139 -0
- thestage/inference_model/communication/inference_model_command.py +246 -0
- thestage/inference_model/dto/__init__.py +0 -0
- thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_instance_response.py +0 -1
- thestage/inference_model/dto/enum/__init__.py +0 -0
- thestage/{services/project/dto/inference_simulator_model_dto.py → inference_model/dto/inference_model.py} +1 -1
- thestage/{entities/project_inference_simulator_model.py → inference_model/dto/inference_model_entity.py} +1 -1
- thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/inference_simulator_model_list_for_project_response.py +2 -3
- 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
- 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
- thestage/inference_simulator/__init__.py +0 -0
- thestage/inference_simulator/business/__init__.py +0 -0
- thestage/inference_simulator/business/inference_simulator_service.py +338 -0
- thestage/inference_simulator/business/mapper/__init__.py +0 -0
- thestage/{services/project/mapper/project_inference_simulator_mapper.py → inference_simulator/business/mapper/inference_simulator_mapper.py} +5 -5
- thestage/inference_simulator/communication/__init__.py +0 -0
- thestage/inference_simulator/communication/inference_simulator_api_client.py +114 -0
- thestage/inference_simulator/communication/inference_simulator_command.py +347 -0
- thestage/inference_simulator/dto/__init__.py +0 -0
- thestage/inference_simulator/dto/enum/__init__.py +0 -0
- thestage/inference_simulator/dto/get_inference_simulator_response.py +12 -0
- thestage/{services/project/dto/inference_simulator_dto.py → inference_simulator/dto/inference_simulator.py} +1 -1
- thestage/{entities/project_inference_simulator.py → inference_simulator/dto/inference_simulator_entity.py} +1 -1
- thestage/{services/clients/thestage_api/dtos/inference_controller → inference_simulator/dto}/inference_simulator_list_response.py +2 -2
- thestage/{services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_request.py → inference_simulator/dto/start_inference_simulator_request.py} +1 -1
- thestage/inference_simulator/dto/start_inference_simulator_response.py +10 -0
- thestage/instance/__init__.py +0 -0
- thestage/instance/business/__init__.py +0 -0
- thestage/{services/instance → instance/business}/instance_service.py +26 -27
- thestage/instance/business/mapper/__init__.py +0 -0
- thestage/{services/instance/mapper/instance_mapper.py → instance/business/mapper/rented_instance_mapper.py} +3 -3
- thestage/{services/instance/mapper/selfhosted_mapper.py → instance/business/mapper/selfhosted_instance_mapper.py} +5 -7
- thestage/instance/communication/__init__.py +0 -0
- thestage/instance/communication/instance_api_client.py +150 -0
- thestage/{controllers/instance_controller.py → instance/communication/instance_command.py} +5 -5
- thestage/instance/dto/__init__.py +0 -0
- thestage/instance/dto/enum/__init__.py +0 -0
- thestage/{services/clients/thestage_api/dtos → instance/dto}/instance_detected_gpus.py +1 -2
- thestage/{services/clients/thestage_api/dtos → instance/dto}/instance_rented_response.py +2 -2
- thestage/{services/clients/thestage_api/dtos → instance/dto}/selfhosted_instance_response.py +2 -3
- thestage/logging/__init__.py +0 -0
- thestage/logging/business/__init__.py +0 -0
- thestage/{services/logging → logging/business}/logging_service.py +40 -28
- thestage/logging/communication/__init__.py +0 -0
- thestage/logging/communication/logging_api_client.py +63 -0
- thestage/logging/dto/__init__.py +0 -0
- thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/log_polling_response.py +2 -2
- thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/user_logs_query_response.py +2 -2
- thestage/main.py +47 -8
- thestage/project/__init__.py +0 -0
- thestage/project/business/__init__.py +0 -0
- thestage/project/business/project_service.py +480 -0
- thestage/project/communication/__init__.py +0 -0
- thestage/project/communication/project_api_client.py +46 -0
- thestage/project/communication/project_command.py +284 -0
- thestage/project/dto/__init__.py +0 -0
- thestage/services/clients/thestage_api/core/api_client_core.py +1 -1
- thestage/services/clients/thestage_api/dtos/entity_filter_request.py +1 -1
- thestage/services/clients/thestage_api/dtos/sftp_path_helper.py +1 -1
- thestage/services/filesystem_service.py +2 -2
- thestage/services/service_factory.py +130 -43
- thestage/task/__init__.py +0 -0
- thestage/task/business/__init__.py +0 -0
- thestage/task/business/mapper/__init__.py +0 -0
- thestage/{services/project/mapper/project_task_mapper.py → task/business/mapper/task_mapper.py} +5 -5
- thestage/task/business/task_service.py +304 -0
- thestage/task/communication/__init__.py +0 -0
- thestage/task/communication/task_api_client.py +122 -0
- thestage/task/communication/task_command.py +212 -0
- thestage/task/dto/__init__.py +0 -0
- thestage/task/dto/enum/__init__.py +0 -0
- thestage/{services/clients/thestage_api/dtos/task_controller/task_list_for_project_response.py → task/dto/list_for_project_response.py} +2 -2
- thestage/{services/clients/thestage_api/dtos/project_controller/project_run_task_request.py → task/dto/run_task_request.py} +1 -1
- thestage/task/dto/run_task_response.py +13 -0
- thestage/{services/task/dto/task_dto.py → task/dto/task.py} +1 -4
- thestage/{entities/project_task.py → task/dto/task_entity.py} +1 -1
- thestage/{services/clients/thestage_api/dtos/task_controller/task_view_response.py → task/dto/view_response.py} +2 -2
- {thestage-0.6.7.dist-info → thestage-0.6.8.dist-info}/METADATA +1 -1
- thestage-0.6.8.dist-info/RECORD +219 -0
- {thestage-0.6.7.dist-info → thestage-0.6.8.dist-info}/WHEEL +1 -1
- thestage/controllers/project_controller.py +0 -1056
- thestage/services/clients/thestage_api/api_client.py +0 -751
- thestage/services/clients/thestage_api/dtos/container_param_request.py +0 -11
- thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_response.py +0 -13
- thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_response.py +0 -13
- thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_response.py +0 -10
- thestage/services/clients/thestage_api/dtos/user_controller/user_profile.py +0 -12
- thestage/services/project/project_service.py +0 -1287
- thestage-0.6.7.dist-info/RECORD +0 -167
- /thestage/{entities → color_scheme}/__init__.py +0 -0
- /thestage/{entities/enums → config/business}/__init__.py +0 -0
- /thestage/{services/clients/git → config/communication}/__init__.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → config/dto}/__init__.py +0 -0
- /thestage/{services/core_files → config/dto}/config_entity.py +0 -0
- /thestage/{services/connect → config}/dto/remote_server_config.py +0 -0
- /thestage/{services/config_provider → connect}/__init__.py +0 -0
- /thestage/{services/container → connect/business}/__init__.py +0 -0
- /thestage/{services/container/mapper → connect/communication}/__init__.py +0 -0
- /thestage/{services/instance → connect/dto}/__init__.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_key_to_user_request.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_public_key_to_instance_request.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/is_user_has_public_ssh_key_request.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/is_user_has_public_ssh_key_response.py +0 -0
- /thestage/{services/instance/mapper → docker_container}/__init__.py +0 -0
- /thestage/{services/project → docker_container/business}/__init__.py +0 -0
- /thestage/{services/project → docker_container/business}/mapper/__init__.py +0 -0
- /thestage/{entities/container.py → docker_container/dto/container_entity.py} +0 -0
- /thestage/{services/clients/thestage_api/dtos/docker_container_controller → docker_container/dto}/docker_container_list_request.py +0 -0
- /thestage/{services/clients/thestage_api/dtos → docker_container/dto}/docker_container_mapping.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → docker_container/dto/enum}/container_pending_action.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → docker_container/dto/enum}/container_status.py +0 -0
- /thestage/{services/logging/exception → exceptions}/log_polling_exception.py +0 -0
- /thestage/git/{ProgressPrinter.py → business/ProgressPrinter.py} +0 -0
- /thestage/{entities → global_dto}/enums/order_direction_type.py +0 -0
- /thestage/{entities → global_dto}/enums/shell_type.py +0 -0
- /thestage/{entities → global_dto}/enums/tail_output_type.py +0 -0
- /thestage/{entities → global_dto}/enums/yes_no_response.py +0 -0
- /thestage/{entities → global_dto}/file_item.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_instance_request.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_sagemaker_request.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_sagemaker_response.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → inference_model/dto/enum}/inference_model_status.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/inference_simulator_model_list_for_project_request.py +0 -0
- /thestage/{services/clients/thestage_api/dtos → inference_model/dto}/inference_simulator_model_response.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → inference_simulator/dto/enum}/inference_simulator_status.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_simulator/dto}/get_inference_simulator_request.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_simulator/dto}/inference_simulator_list_request.py +0 -0
- /thestage/{services/clients/thestage_api/dtos → inference_simulator/dto}/inference_simulator_response.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/cpu_type.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/gpu_name.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/instance_rented_status.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/provider_name.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/selfhosted_status.py +0 -0
- /thestage/{entities → instance/dto}/rented_instance.py +0 -0
- /thestage/{entities → instance/dto}/self_hosted_instance.py +0 -0
- /thestage/{services/logging → logging}/byte_print_style.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/docker_container_log_stream_request.py +0 -0
- /thestage/{services/logging → logging}/dto/log_message.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/log_polling_request.py +0 -0
- /thestage/{services/logging → logging}/dto/log_type.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/task_log_stream_request.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/user_logs_query_request.py +0 -0
- /thestage/{services/logging → logging}/logging_constants.py +0 -0
- /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
- /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
- /thestage/{services/project → project}/dto/project_config.py +0 -0
- /thestage/{services/clients/thestage_api/dtos → project/dto}/project_response.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → task/dto/enum}/task_execution_status.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/enums → task/dto/enum}/task_status.py +0 -0
- /thestage/{services/clients/thestage_api/dtos/task_controller/task_list_for_project_request.py → task/dto/list_for_project_request.py} +0 -0
- /thestage/{services/clients/thestage_api/dtos/task_controller/task_status_localized_map_response.py → task/dto/status_localized_map_response.py} +0 -0
- {thestage-0.6.7.dist-info → thestage-0.6.8.dist-info}/entry_points.txt +0 -0
- {thestage-0.6.7.dist-info → thestage-0.6.8.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
|
-
from thestage.
|
|
3
|
+
from thestage.inference_simulator.dto.inference_simulator_entity import InferenceSimulatorEntity
|
|
4
4
|
from thestage.services.abstract_mapper import AbstractMapper
|
|
5
|
-
from thestage.
|
|
5
|
+
from thestage.inference_simulator.dto.inference_simulator import InferenceSimulator
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class
|
|
8
|
+
class InferenceSimulatorMapper(AbstractMapper):
|
|
9
9
|
|
|
10
|
-
def build_entity(self, item:
|
|
10
|
+
def build_entity(self, item: InferenceSimulator) -> Optional[InferenceSimulatorEntity]:
|
|
11
11
|
if not item:
|
|
12
12
|
return None
|
|
13
13
|
|
|
14
|
-
return
|
|
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
|
|
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,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.
|
|
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[
|
|
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
|
|
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
|