thestage 0.6.6__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 +25 -22
- 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 +1 -1
- thestage/controllers/base_controller.py +2 -2
- thestage/debug_main.dist.py +16 -14
- thestage/{services/container → docker_container/business}/container_service.py +120 -40
- 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} +27 -86
- 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 +5 -5
- thestage/global_dto/__init__.py +0 -0
- thestage/global_dto/enums/__init__.py +0 -0
- thestage/helpers/error_handler.py +5 -5
- 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_request.py +0 -2
- thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_instance_response.py +2 -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} +2 -2
- 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/{services/clients/thestage_api/dtos/inference_controller → inference_simulator/dto}/get_inference_simulator_request.py +1 -1
- 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} +9 -9
- 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 +45 -36
- 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 +48 -9
- 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/project → project}/dto/project_config.py +1 -2
- 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.6.dist-info → thestage-0.6.8.dist-info}/METADATA +2 -1
- thestage-0.6.8.dist-info/RECORD +219 -0
- {thestage-0.6.6.dist-info → thestage-0.6.8.dist-info}/WHEEL +1 -1
- thestage/controllers/project_controller.py +0 -1058
- thestage/services/clients/thestage_api/api_client.py +0 -753
- 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 -10
- 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 -1283
- thestage-0.6.6.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_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}/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/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.6.dist-info → thestage-0.6.8.dist-info}/entry_points.txt +0 -0
- {thestage-0.6.6.dist-info → thestage-0.6.8.dist-info}/licenses/LICENSE.txt +0 -0
|
@@ -12,9 +12,9 @@ from gitdb.exc import BadName
|
|
|
12
12
|
from rich import print
|
|
13
13
|
|
|
14
14
|
from thestage.color_scheme.color_scheme import ColorScheme
|
|
15
|
-
from thestage.config import THESTAGE_CONFIG_DIR
|
|
15
|
+
from thestage.config.env_base import THESTAGE_CONFIG_DIR
|
|
16
16
|
from thestage.exceptions.git_access_exception import GitAccessException
|
|
17
|
-
from thestage.git.ProgressPrinter import ProgressPrinter
|
|
17
|
+
from thestage.git.business.ProgressPrinter import ProgressPrinter
|
|
18
18
|
from thestage.services.filesystem_service import FileSystemService
|
|
19
19
|
|
|
20
20
|
|
|
@@ -33,7 +33,7 @@ class GitLocalClient:
|
|
|
33
33
|
):
|
|
34
34
|
self.__file_system_service = file_system_service
|
|
35
35
|
|
|
36
|
-
# todo delete this
|
|
36
|
+
# todo delete this
|
|
37
37
|
def __get_repo(self, path: str) -> Repo:
|
|
38
38
|
return git.Repo(path)
|
|
39
39
|
|
|
@@ -196,7 +196,7 @@ class GitLocalClient:
|
|
|
196
196
|
) -> Optional[str]:
|
|
197
197
|
repo = self.__get_repo(path=path)
|
|
198
198
|
if repo.head.is_detached:
|
|
199
|
-
line_color = ColorScheme.GIT_HEADLESS
|
|
199
|
+
line_color = ColorScheme.GIT_HEADLESS.value
|
|
200
200
|
print(f'[{line_color}]Committing in detached head state at {repo.head.commit.hexsha}[/{line_color}]')
|
|
201
201
|
commit_name = name if name else f"Auto commit {str(datetime.datetime.now().date())}"
|
|
202
202
|
commit = repo.git.commit('--allow-empty', '-m', commit_name, )
|
|
@@ -392,7 +392,7 @@ class GitLocalClient:
|
|
|
392
392
|
repo.git.reset('--hard', f'origin/{repo.active_branch.name}')
|
|
393
393
|
typer.echo(f'Branch "{repo.active_branch.name}" is now synced to its remote counterpart')
|
|
394
394
|
else:
|
|
395
|
-
typer.echo('
|
|
395
|
+
typer.echo('Simple branch reset is not implemented')
|
|
396
396
|
|
|
397
397
|
# refers to a "headless commit" where something was committed while in detached head state and head is pointing at that commit
|
|
398
398
|
def is_head_committed_in_headless_state(self, path: str) -> bool:
|
|
File without changes
|
|
File without changes
|
|
@@ -7,7 +7,7 @@ from click.exceptions import Exit, Abort
|
|
|
7
7
|
from git import GitCommandError
|
|
8
8
|
from paramiko.ssh_exception import PasswordRequiredException
|
|
9
9
|
|
|
10
|
-
from thestage.config import THESTAGE_API_URL
|
|
10
|
+
from thestage.config.env_base import THESTAGE_API_URL
|
|
11
11
|
from thestage.exceptions.file_system_exception import FileSystemException
|
|
12
12
|
from thestage.exceptions.remote_server_exception import RemoteServerException
|
|
13
13
|
from thestage.i18n.translation import __
|
|
@@ -26,7 +26,7 @@ def error_handler() -> Callable:
|
|
|
26
26
|
result = f(*args, **kwargs)
|
|
27
27
|
return result
|
|
28
28
|
except AuthException as e1:
|
|
29
|
-
typer.echo(__('Authentication failed: update
|
|
29
|
+
typer.echo(__('Authentication failed: update access token'))
|
|
30
30
|
app_logger.error(f'{traceback.format_exc()}')
|
|
31
31
|
raise typer.Exit(1)
|
|
32
32
|
except BusinessLogicException as e2:
|
|
@@ -98,7 +98,7 @@ def error_handler() -> Callable:
|
|
|
98
98
|
raise typer.Exit(1)
|
|
99
99
|
except PasswordRequiredException as e11:
|
|
100
100
|
# technically we can use encrypted keys but dealing with passwords is big bs
|
|
101
|
-
typer.echo("Provided key requires password.
|
|
101
|
+
typer.echo("Provided key requires password. Use non-encrypted key.")
|
|
102
102
|
app_logger.error(f'{traceback.format_exc()}')
|
|
103
103
|
raise typer.Exit(1)
|
|
104
104
|
except Exception as e100:
|
|
@@ -106,8 +106,8 @@ def error_handler() -> Callable:
|
|
|
106
106
|
raise e100
|
|
107
107
|
else:
|
|
108
108
|
typer.echo(__('Undefined error occurred'))
|
|
109
|
-
typer.echo(e100.__class__.__name__)
|
|
110
|
-
print(traceback.format_exc())
|
|
109
|
+
# typer.echo(e100.__class__.__name__)
|
|
110
|
+
# print(traceback.format_exc())
|
|
111
111
|
# TODO send all exceptions to backend?
|
|
112
112
|
app_logger.error(f'{traceback.format_exc()}')
|
|
113
113
|
raise typer.Exit(1)
|
|
@@ -3,10 +3,8 @@ import platform
|
|
|
3
3
|
from logging.handlers import RotatingFileHandler
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
from thestage import __app_name__, __version__
|
|
6
|
+
from thestage.config.env_base import THESTAGE_CONFIG_DIR, THESTAGE_LOGGING_FILE
|
|
6
7
|
|
|
7
|
-
from thestage.config import THESTAGE_CONFIG_DIR
|
|
8
|
-
|
|
9
|
-
from thestage.config import THESTAGE_LOGGING_FILE
|
|
10
8
|
from thestage.exceptions.file_system_exception import FileSystemException
|
|
11
9
|
|
|
12
10
|
|
thestage/i18n/en_GB/messages.po
CHANGED
|
@@ -161,7 +161,7 @@ msgstr "Add URL to your own repository"
|
|
|
161
161
|
|
|
162
162
|
# Branch: feature/add_new_method_for_containers
|
|
163
163
|
#: tsr/controllers/sketch_controller.py
|
|
164
|
-
msgid "This folder is not empty, we
|
|
164
|
+
msgid "This folder is not empty, we cannot clone here"
|
|
165
165
|
msgstr "Cannot clone: the folder is not empty"
|
|
166
166
|
|
|
167
167
|
# Branch: feature/add_new_method_for_containers
|
|
@@ -362,7 +362,7 @@ msgstr "Task title is required: please type or select to auto-generate"
|
|
|
362
362
|
|
|
363
363
|
# Branch: feature/add_new_method_for_containers
|
|
364
364
|
#: tsr/services/sketch/sketch_service.py
|
|
365
|
-
msgid "Task title
|
|
365
|
+
msgid "Task title cannot be empty"
|
|
366
366
|
msgstr "Task title is required"
|
|
367
367
|
|
|
368
368
|
# Branch: feature/add_new_method_for_containers
|
|
@@ -427,7 +427,7 @@ msgstr "Incorrect slug specified: sketch not found"
|
|
|
427
427
|
|
|
428
428
|
# Branch: feature/add_new_method_for_containers
|
|
429
429
|
#: tsr/services/sketch/sketch_service.py
|
|
430
|
-
msgid "You have local repo with remote, we
|
|
430
|
+
msgid "You have local repo with remote, we cannot work with this"
|
|
431
431
|
msgstr "Your local repository is linked to a remote: this configuration is not supported for the current operation"
|
|
432
432
|
|
|
433
433
|
# Branch: feature/add_new_method_for_containers
|
|
@@ -442,12 +442,12 @@ msgstr "Your local repo has been modified and is not empty, please create an emp
|
|
|
442
442
|
|
|
443
443
|
# Branch: feature/add_new_method_for_containers
|
|
444
444
|
#: tsr/services/sketch/sketch_service.py
|
|
445
|
-
msgid "We
|
|
445
|
+
msgid "We cannot add remote, something wrong"
|
|
446
446
|
msgstr "Cannot add remote, something wrong"
|
|
447
447
|
|
|
448
448
|
# Branch: feature/add_new_method_for_containers
|
|
449
449
|
#: tsr/services/sketch/sketch_service.py
|
|
450
|
-
msgid "You have local repo, we
|
|
450
|
+
msgid "You have local repo, we cannot work with this"
|
|
451
451
|
msgstr "Local repository in use: not supported for current operation"
|
|
452
452
|
|
|
453
453
|
# Branch: feature/add_new_method_for_containers
|
|
@@ -517,12 +517,12 @@ msgstr "Path not found"
|
|
|
517
517
|
|
|
518
518
|
# Branch: feature/add_new_method_for_containers
|
|
519
519
|
#: tsr/services/filesystem_service.py
|
|
520
|
-
msgid "We
|
|
520
|
+
msgid "We cannot make dir"
|
|
521
521
|
msgstr "Failed to create directory"
|
|
522
522
|
|
|
523
523
|
# Branch: feature/add_new_method_for_containers
|
|
524
524
|
#: tsr/services/filesystem_service.py
|
|
525
|
-
msgid "We
|
|
525
|
+
msgid "We cannot make file"
|
|
526
526
|
msgstr "Failed to create file"
|
|
527
527
|
|
|
528
528
|
# Branch: feature/add_new_method_for_containers
|
|
@@ -692,12 +692,12 @@ msgstr "Cannot connect to rented or self-hosted instance"
|
|
|
692
692
|
|
|
693
693
|
# Branch: feature/add_new_method_for_containers
|
|
694
694
|
#: tsr/services/container/container_service.py
|
|
695
|
-
msgid "Container name not present,
|
|
695
|
+
msgid "Container name not present, cannot connect to container"
|
|
696
696
|
msgstr "Cannot connect to container: please specify container slug"
|
|
697
697
|
|
|
698
698
|
# Branch: feature/add_new_method_for_containers
|
|
699
699
|
#: tsr/services/container/container_service.py
|
|
700
|
-
msgid "We
|
|
700
|
+
msgid "We cannot get shell on container (bash, shell), please use standard shell"
|
|
701
701
|
msgstr "Unable to access the requested shell (bash, shell) in the container: please use the default shell available in the container"
|
|
702
702
|
|
|
703
703
|
# Branch: feature/add_new_method_for_containers
|
|
@@ -722,7 +722,7 @@ msgstr "Specify username to connect to server instance"
|
|
|
722
722
|
|
|
723
723
|
# Branch: feature/add_new_method_for_containers
|
|
724
724
|
#: tsr/services/container/container_service.py
|
|
725
|
-
msgid "Container is running,
|
|
725
|
+
msgid "Container is running, cannot start working server"
|
|
726
726
|
msgstr "Container is running: cannot start running container"
|
|
727
727
|
|
|
728
728
|
# Branch: feature/add_new_method_for_containers
|
|
@@ -797,7 +797,7 @@ msgstr "Server instance slug not found"
|
|
|
797
797
|
|
|
798
798
|
# Branch: feature/add_new_method_for_containers
|
|
799
799
|
#: tsr/services/sketch/sketch_service.py
|
|
800
|
-
msgid "Slug
|
|
800
|
+
msgid "Slug cannot be empty"
|
|
801
801
|
msgstr "Specify slug"
|
|
802
802
|
|
|
803
803
|
# Branch: main
|
|
@@ -928,17 +928,17 @@ msgstr ""
|
|
|
928
928
|
|
|
929
929
|
# Branch: main
|
|
930
930
|
#: tsr/services/container/container_service.py
|
|
931
|
-
msgid "Error,
|
|
931
|
+
msgid "Error, cannot find mapping folders"
|
|
932
932
|
msgstr ""
|
|
933
933
|
|
|
934
934
|
# Branch: main
|
|
935
935
|
#: tsr/services/container/container_service.py
|
|
936
|
-
msgid "Error,
|
|
936
|
+
msgid "Error, cannot find mapping for /public folder"
|
|
937
937
|
msgstr ""
|
|
938
938
|
|
|
939
939
|
# Branch: main
|
|
940
940
|
#: tsr/services/remote_server_service.py
|
|
941
|
-
msgid "
|
|
941
|
+
msgid "cannot find mapping folders"
|
|
942
942
|
msgstr ""
|
|
943
943
|
|
|
944
944
|
# Branch: main
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
import time
|
|
2
|
+
from datetime import datetime
|
|
3
|
+
from typing import Optional, List
|
|
4
|
+
|
|
5
|
+
import boto3
|
|
6
|
+
import typer
|
|
7
|
+
|
|
8
|
+
from thestage.config.business.config_provider import ConfigProvider
|
|
9
|
+
from thestage.helpers.error_handler import error_handler
|
|
10
|
+
from thestage.i18n.translation import __
|
|
11
|
+
from thestage.inference_model.business.mapper.inference_model_mapper import InferenceModelMapper
|
|
12
|
+
from thestage.inference_model.communication.inference_model_api_client import InferenceModelApiClient
|
|
13
|
+
from thestage.inference_model.dto.deploy_inference_model_to_instance_response import \
|
|
14
|
+
DeployInferenceModelToInstanceResponse
|
|
15
|
+
from thestage.inference_model.dto.deploy_inference_model_to_sagemaker_response import \
|
|
16
|
+
DeployInferenceModelToSagemakerResponse
|
|
17
|
+
from thestage.inference_model.dto.enum.inference_model_status import InferenceModelStatus
|
|
18
|
+
from thestage.inference_model.dto.inference_model import InferenceModel
|
|
19
|
+
from thestage.inference_model.dto.inference_model_entity import InferenceModelEntity
|
|
20
|
+
from thestage.project.business.project_service import ProjectService
|
|
21
|
+
from thestage.project.dto.project_config import ProjectConfig
|
|
22
|
+
from thestage.services.abstract_service import AbstractService
|
|
23
|
+
from thestage.services.clients.thestage_api.dtos.paginated_entity_list import PaginatedEntityList
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class InferenceModelService(AbstractService):
|
|
27
|
+
def __init__(
|
|
28
|
+
self,
|
|
29
|
+
inference_model_api_client: InferenceModelApiClient,
|
|
30
|
+
config_provider: ConfigProvider,
|
|
31
|
+
project_service: ProjectService,
|
|
32
|
+
):
|
|
33
|
+
self.__inference_model_api_client = inference_model_api_client
|
|
34
|
+
self.__config_provider = config_provider
|
|
35
|
+
self.__project_service = project_service
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
@error_handler()
|
|
39
|
+
def get_project_inference_simulator_model_list(
|
|
40
|
+
self,
|
|
41
|
+
project_public_id: Optional[str],
|
|
42
|
+
project_slug: Optional[str],
|
|
43
|
+
statuses: List[str],
|
|
44
|
+
row: int = 5,
|
|
45
|
+
page: int = 1,
|
|
46
|
+
) -> PaginatedEntityList[InferenceModel]:
|
|
47
|
+
data: Optional[
|
|
48
|
+
PaginatedEntityList[InferenceModel]] = self.__inference_model_api_client.get_inference_simulator_model_list_for_project(
|
|
49
|
+
statuses=statuses,
|
|
50
|
+
project_public_id=project_public_id,
|
|
51
|
+
project_slug=project_slug,
|
|
52
|
+
page=page,
|
|
53
|
+
limit=row,
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
return data
|
|
57
|
+
|
|
58
|
+
@error_handler()
|
|
59
|
+
def project_deploy_inference_simulator_model_to_instance(
|
|
60
|
+
self,
|
|
61
|
+
model_public_id: Optional[str] = None,
|
|
62
|
+
model_slug: Optional[str] = None,
|
|
63
|
+
rented_instance_public_id: Optional[str] = None,
|
|
64
|
+
rented_instance_slug: Optional[str] = None,
|
|
65
|
+
self_hosted_instance_public_id: Optional[str] = None,
|
|
66
|
+
self_hosted_instance_slug: Optional[str] = None,
|
|
67
|
+
) -> str:
|
|
68
|
+
config = self.__config_provider.get_config()
|
|
69
|
+
project_config: ProjectConfig = self.__project_service.get_fixed_project_config()
|
|
70
|
+
if not project_config:
|
|
71
|
+
typer.echo(
|
|
72
|
+
__("No project found at the path: %path%. Please initialize or clone a project first. Or provide path to project using --working-directory option.",
|
|
73
|
+
{"path": config.runtime.working_directory}))
|
|
74
|
+
raise typer.Exit(1)
|
|
75
|
+
|
|
76
|
+
instance_args_count = sum(v is not None for v in
|
|
77
|
+
[rented_instance_public_id, rented_instance_slug, self_hosted_instance_public_id,
|
|
78
|
+
self_hosted_instance_slug])
|
|
79
|
+
if instance_args_count != 1:
|
|
80
|
+
typer.echo("Please provide a single instance (rented or self-hosted) identifier - name or ID.")
|
|
81
|
+
raise typer.Exit(1)
|
|
82
|
+
|
|
83
|
+
model_args_count = sum(v is not None for v in [model_public_id, model_slug])
|
|
84
|
+
if model_args_count != 1:
|
|
85
|
+
typer.echo("Please provide a single model identifier - name or ID.")
|
|
86
|
+
raise typer.Exit(1)
|
|
87
|
+
|
|
88
|
+
typer.echo(f"Creating inference simulator")
|
|
89
|
+
deploy_model_to_instance_response: DeployInferenceModelToInstanceResponse = self.__inference_model_api_client.deploy_inference_model_to_instance(
|
|
90
|
+
model_public_id=model_public_id,
|
|
91
|
+
model_slug=model_slug,
|
|
92
|
+
rented_instance_public_id=rented_instance_public_id,
|
|
93
|
+
rented_instance_slug=rented_instance_slug,
|
|
94
|
+
self_hosted_instance_public_id=self_hosted_instance_public_id,
|
|
95
|
+
self_hosted_instance_slug=self_hosted_instance_slug,
|
|
96
|
+
)
|
|
97
|
+
if deploy_model_to_instance_response:
|
|
98
|
+
if deploy_model_to_instance_response.message:
|
|
99
|
+
typer.echo(deploy_model_to_instance_response.message)
|
|
100
|
+
if deploy_model_to_instance_response.is_success:
|
|
101
|
+
typer.echo("Inference simulator has been scheduled to run successfully.")
|
|
102
|
+
else:
|
|
103
|
+
typer.echo(__(
|
|
104
|
+
'Failed to start inference simulator: %server_massage%',
|
|
105
|
+
{'server_massage': deploy_model_to_instance_response.message or ""}
|
|
106
|
+
))
|
|
107
|
+
raise typer.Exit(1)
|
|
108
|
+
else:
|
|
109
|
+
typer.echo(__("Failed to start inference simulator"))
|
|
110
|
+
raise typer.Exit(1)
|
|
111
|
+
|
|
112
|
+
return deploy_model_to_instance_response.inferenceSimulatorPublicId
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@error_handler()
|
|
116
|
+
def project_deploy_inference_simulator_model_to_sagemaker(
|
|
117
|
+
self,
|
|
118
|
+
model_public_id: Optional[str] = None,
|
|
119
|
+
model_slug: Optional[str] = None,
|
|
120
|
+
arn: Optional[str] = None,
|
|
121
|
+
instance_type: Optional[str] = None,
|
|
122
|
+
initial_variant_weight: Optional[float] = 1.0,
|
|
123
|
+
initial_instance_count: Optional[int] = None,
|
|
124
|
+
) -> None:
|
|
125
|
+
config = self.__config_provider.get_config()
|
|
126
|
+
project_config: ProjectConfig = self.__project_service.get_fixed_project_config()
|
|
127
|
+
if not project_config:
|
|
128
|
+
typer.echo(
|
|
129
|
+
__("No project found at the path: %path%. Please initialize or clone a project first. Or provide path to project using --working-directory option.",
|
|
130
|
+
{"path": config.runtime.working_directory}))
|
|
131
|
+
raise typer.Exit(1)
|
|
132
|
+
|
|
133
|
+
if not instance_type:
|
|
134
|
+
typer.echo(__("Error: Instance type is required."))
|
|
135
|
+
raise typer.Exit(1)
|
|
136
|
+
|
|
137
|
+
if not initial_instance_count:
|
|
138
|
+
typer.echo(__("Error: Initial instance count is required."))
|
|
139
|
+
raise typer.Exit(1)
|
|
140
|
+
|
|
141
|
+
if not arn:
|
|
142
|
+
typer.echo(__("Error: ARN is required."))
|
|
143
|
+
raise typer.Exit(1)
|
|
144
|
+
|
|
145
|
+
project_config: ProjectConfig = self.__config_provider.read_project_config()
|
|
146
|
+
if not project_config:
|
|
147
|
+
typer.echo(__("No project found at the path: %path%. Please initialize or clone a project first.",
|
|
148
|
+
{"path": config.runtime.working_directory}))
|
|
149
|
+
raise typer.Exit(1)
|
|
150
|
+
|
|
151
|
+
deploy_model_to_sagemaker_response: DeployInferenceModelToSagemakerResponse = self.__inference_model_api_client.deploy_inference_model_to_sagemaker(
|
|
152
|
+
model_public_id=model_public_id,
|
|
153
|
+
model_slug=model_slug,
|
|
154
|
+
arn=arn,
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
if not deploy_model_to_sagemaker_response.is_success:
|
|
158
|
+
typer.echo(__(
|
|
159
|
+
'Model deployment preparation failed: %server_massage%',
|
|
160
|
+
{'server_massage': deploy_model_to_sagemaker_response.message or ""}
|
|
161
|
+
))
|
|
162
|
+
raise typer.Exit(1)
|
|
163
|
+
|
|
164
|
+
model_id = deploy_model_to_sagemaker_response.modelId
|
|
165
|
+
image_uri = deploy_model_to_sagemaker_response.ecrImageUrl
|
|
166
|
+
model_uri = deploy_model_to_sagemaker_response.s3ArtifactsUrl
|
|
167
|
+
region = "us-east-1"
|
|
168
|
+
sm_client = boto3.client('sagemaker', region_name=region)
|
|
169
|
+
|
|
170
|
+
try:
|
|
171
|
+
container = {
|
|
172
|
+
"Image": image_uri,
|
|
173
|
+
"ModelDataUrl": model_uri,
|
|
174
|
+
"Environment": {
|
|
175
|
+
"SAGEMAKER_TRITON_DEFAULT_MODEL_NAME": model_id,
|
|
176
|
+
"THESTAGE_API_URL": config.main.thestage_api_url,
|
|
177
|
+
"THESTAGE_AUTH_TOKEN": config.main.thestage_auth_token
|
|
178
|
+
},
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
sm_model_name = f"{model_slug}-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
|
|
182
|
+
create_model_response = sm_client.create_model(
|
|
183
|
+
ModelName=sm_model_name,
|
|
184
|
+
ExecutionRoleArn=arn,
|
|
185
|
+
PrimaryContainer=container,
|
|
186
|
+
)
|
|
187
|
+
typer.echo(f"Model created successfully. Model ARN: {create_model_response['ModelArn']}")
|
|
188
|
+
|
|
189
|
+
endpoint_config_name = f"{model_slug}-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
|
|
190
|
+
create_endpoint_config_response = sm_client.create_endpoint_config(
|
|
191
|
+
EndpointConfigName=endpoint_config_name,
|
|
192
|
+
ProductionVariants=[
|
|
193
|
+
{
|
|
194
|
+
"InstanceType": instance_type,
|
|
195
|
+
"InitialVariantWeight": initial_variant_weight,
|
|
196
|
+
"InitialInstanceCount": initial_instance_count,
|
|
197
|
+
"ModelName": sm_model_name,
|
|
198
|
+
"VariantName": "AllTraffic",
|
|
199
|
+
}
|
|
200
|
+
],
|
|
201
|
+
)
|
|
202
|
+
typer.echo(
|
|
203
|
+
f"Endpoint configuration created successfully. Endpoint Config ARN: {create_endpoint_config_response['EndpointConfigArn']}")
|
|
204
|
+
|
|
205
|
+
endpoint_name = f"{model_slug}-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
|
|
206
|
+
create_endpoint_response = sm_client.create_endpoint(
|
|
207
|
+
EndpointName=endpoint_name,
|
|
208
|
+
EndpointConfigName=endpoint_config_name,
|
|
209
|
+
)
|
|
210
|
+
typer.echo(f"Endpoint created successfully. Endpoint ARN: {create_endpoint_response['EndpointArn']}")
|
|
211
|
+
|
|
212
|
+
typer.echo("Waiting for the endpoint to become active...")
|
|
213
|
+
while True:
|
|
214
|
+
resp = sm_client.describe_endpoint(EndpointName=endpoint_name)
|
|
215
|
+
status = resp["EndpointStatus"]
|
|
216
|
+
typer.echo(f"Status: {status}")
|
|
217
|
+
if status == "InService":
|
|
218
|
+
break
|
|
219
|
+
elif status == "Failed":
|
|
220
|
+
typer.echo(f"Endpoint creation failed. Reason: {resp.get('FailureReason', 'Unknown')}")
|
|
221
|
+
raise typer.Exit(1)
|
|
222
|
+
time.sleep(60)
|
|
223
|
+
|
|
224
|
+
typer.echo(f"Endpoint is ready. ARN: {resp['EndpointArn']} Status: {status}")
|
|
225
|
+
|
|
226
|
+
except Exception as e:
|
|
227
|
+
typer.echo(__("Failed to deploy the inference simulator model to SageMaker: %error%", {"error": str(e)}))
|
|
228
|
+
raise typer.Exit(1)
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
@error_handler()
|
|
232
|
+
def print_inference_simulator_model_list(self, project_public_id, project_slug, statuses, row, page):
|
|
233
|
+
if not project_public_id and not project_slug:
|
|
234
|
+
project_config: ProjectConfig = self.__config_provider.read_project_config()
|
|
235
|
+
if not project_config:
|
|
236
|
+
typer.echo(__("Provide the project unique ID or run this command from within an initialized project directory"))
|
|
237
|
+
raise typer.Exit(1)
|
|
238
|
+
project_public_id = project_config.public_id
|
|
239
|
+
|
|
240
|
+
inference_simulator_model_status_map = self.__inference_model_api_client.get_inference_simulator_model_business_status_map()
|
|
241
|
+
|
|
242
|
+
if not statuses:
|
|
243
|
+
statuses = ({key: inference_simulator_model_status_map[key] for key in [
|
|
244
|
+
InferenceModelStatus.SCHEDULED,
|
|
245
|
+
InferenceModelStatus.PROCESSING,
|
|
246
|
+
InferenceModelStatus.PUSH_SUCCEED,
|
|
247
|
+
]}).values()
|
|
248
|
+
|
|
249
|
+
if "all" in statuses:
|
|
250
|
+
statuses = inference_simulator_model_status_map.values()
|
|
251
|
+
|
|
252
|
+
for input_status_item in statuses:
|
|
253
|
+
if input_status_item not in inference_simulator_model_status_map.values():
|
|
254
|
+
typer.echo(__("'%invalid_status%' is not one of %valid_statuses%", {
|
|
255
|
+
'invalid_status': input_status_item,
|
|
256
|
+
'valid_statuses': str(list(inference_simulator_model_status_map.values()))
|
|
257
|
+
}))
|
|
258
|
+
raise typer.Exit(1)
|
|
259
|
+
|
|
260
|
+
typer.echo(__(
|
|
261
|
+
"Listing inference simulator models with the following statuses: %statuses%, to view all inference simulator models, use --status all",
|
|
262
|
+
placeholders={
|
|
263
|
+
'statuses': ', '.join([status_item for status_item in statuses])
|
|
264
|
+
}))
|
|
265
|
+
|
|
266
|
+
backend_statuses: List[str] = [key for key, value in inference_simulator_model_status_map.items() if value in statuses]
|
|
267
|
+
|
|
268
|
+
self.print(
|
|
269
|
+
func_get_data=self.get_project_inference_simulator_model_list,
|
|
270
|
+
func_special_params={
|
|
271
|
+
'project_public_id': project_public_id,
|
|
272
|
+
'project_slug': project_slug,
|
|
273
|
+
'statuses': backend_statuses,
|
|
274
|
+
},
|
|
275
|
+
mapper=InferenceModelMapper(),
|
|
276
|
+
headers=list(map(lambda x: x.alias, InferenceModelEntity.model_fields.values())),
|
|
277
|
+
row=row,
|
|
278
|
+
page=page,
|
|
279
|
+
max_col_width=[100, 100, 100, 100, 25],
|
|
280
|
+
show_index="never",
|
|
281
|
+
)
|
|
File without changes
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
from typing import Optional
|
|
2
2
|
|
|
3
|
-
from thestage.
|
|
3
|
+
from thestage.inference_model.dto.inference_model_entity import InferenceModelEntity
|
|
4
4
|
from thestage.services.abstract_mapper import AbstractMapper
|
|
5
|
-
from thestage.
|
|
5
|
+
from thestage.inference_model.dto.inference_model import InferenceModel
|
|
6
6
|
|
|
7
7
|
|
|
8
|
-
class
|
|
9
|
-
def build_entity(self, item:
|
|
8
|
+
class InferenceModelMapper(AbstractMapper):
|
|
9
|
+
def build_entity(self, item: InferenceModel) -> Optional[InferenceModelEntity]:
|
|
10
10
|
if not item:
|
|
11
11
|
return None
|
|
12
12
|
|
|
13
|
-
return
|
|
13
|
+
return InferenceModelEntity(
|
|
14
14
|
public_id=item.public_id,
|
|
15
15
|
slug=item.slug,
|
|
16
16
|
status=item.status or '',
|
|
File without changes
|
|
@@ -0,0 +1,139 @@
|
|
|
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_model.dto.inference_model import InferenceModel
|
|
11
|
+
from thestage.inference_model.dto.inference_simulator_model_list_for_project_request import InferenceSimulatorModelListForProjectRequest
|
|
12
|
+
from thestage.inference_model.dto.inference_simulator_model_list_for_project_response import InferenceSimulatorModelListForProjectResponse
|
|
13
|
+
from thestage.inference_model.dto.push_inference_simulator_model_request import PushInferenceSimulatorModelRequest
|
|
14
|
+
from thestage.inference_model.dto.push_inference_simulator_model_response import PushInferenceSimulatorModelResponse
|
|
15
|
+
from thestage.inference_model.dto.inference_simulator_model_response import InferenceSimulatorModelStatusMapperResponse
|
|
16
|
+
from thestage.inference_model.dto.deploy_inference_model_to_instance_request import DeployInferenceModelToInstanceRequest
|
|
17
|
+
from thestage.inference_model.dto.deploy_inference_model_to_instance_response import DeployInferenceModelToInstanceResponse
|
|
18
|
+
from thestage.inference_model.dto.deploy_inference_model_to_sagemaker_request import DeployInferenceModelToSagemakerRequest
|
|
19
|
+
from thestage.inference_model.dto.deploy_inference_model_to_sagemaker_response import DeployInferenceModelToSagemakerResponse
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class InferenceModelApiClient(TheStageApiClientCore):
|
|
23
|
+
def __init__(self, config_provider: ConfigProvider):
|
|
24
|
+
super().__init__(url=config_provider.get_config().main.thestage_api_url)
|
|
25
|
+
self.__config_provider = config_provider
|
|
26
|
+
|
|
27
|
+
def get_inference_simulator_model_list_for_project(
|
|
28
|
+
self,
|
|
29
|
+
project_public_id: Optional[str],
|
|
30
|
+
project_slug: Optional[str],
|
|
31
|
+
statuses: Optional[List[str]] = None,
|
|
32
|
+
page: int = 1,
|
|
33
|
+
limit: int = 10,
|
|
34
|
+
) -> Optional[PaginatedEntityList[InferenceModel]]:
|
|
35
|
+
request = InferenceSimulatorModelListForProjectRequest(
|
|
36
|
+
projectPublicId=project_public_id,
|
|
37
|
+
projectSlug=project_slug,
|
|
38
|
+
statuses=statuses,
|
|
39
|
+
entityFilterRequest=EntityFilterRequest(
|
|
40
|
+
orderByField="createdAt",
|
|
41
|
+
orderByDirection=OrderDirectionType.DESC,
|
|
42
|
+
page=page,
|
|
43
|
+
limit=limit,
|
|
44
|
+
),
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
response = self._request(
|
|
48
|
+
method='POST',
|
|
49
|
+
url='/user-api/v2/inference-simulator-model/list',
|
|
50
|
+
data=request.model_dump(),
|
|
51
|
+
token=self.__config_provider.get_config().main.thestage_auth_token,
|
|
52
|
+
)
|
|
53
|
+
result = InferenceSimulatorModelListForProjectResponse.model_validate(response) if response else None
|
|
54
|
+
return result.inferenceSimulatorModels if result and result.is_success else None
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def push_project_inference_simulator_model(
|
|
58
|
+
self,
|
|
59
|
+
public_id: Optional[str],
|
|
60
|
+
slug: Optional[str],
|
|
61
|
+
) -> Optional[PushInferenceSimulatorModelResponse]:
|
|
62
|
+
request = PushInferenceSimulatorModelRequest(
|
|
63
|
+
inferenceSimulatorPublicId=public_id,
|
|
64
|
+
inferenceSimulatorSlug=slug,
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
response = self._request(
|
|
68
|
+
method='POST',
|
|
69
|
+
url='/user-api/v2/inference-simulator/push-model',
|
|
70
|
+
data=request.model_dump(),
|
|
71
|
+
token=self.__config_provider.get_config().main.thestage_auth_token,
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
return PushInferenceSimulatorModelResponse.model_validate(response) if response else None
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def get_inference_simulator_model_business_status_map(self) -> Optional[Dict[str, str]]:
|
|
78
|
+
response = self._request(
|
|
79
|
+
method='POST',
|
|
80
|
+
url='/user-api/v1/inference-simulator-model/status-localized-mapping',
|
|
81
|
+
data=None,
|
|
82
|
+
token=self.__config_provider.get_config().main.thestage_auth_token,
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
data = InferenceSimulatorModelStatusMapperResponse.model_validate(response) if response else None
|
|
86
|
+
|
|
87
|
+
return data.inference_simulator_model_status_map if data else None
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
@error_handler()
|
|
91
|
+
def deploy_inference_model_to_instance(
|
|
92
|
+
self,
|
|
93
|
+
model_public_id: str,
|
|
94
|
+
model_slug: str,
|
|
95
|
+
new_inference_simulator_slug: str,
|
|
96
|
+
rented_instance_public_id: Optional[str] = None,
|
|
97
|
+
rented_instance_slug: Optional[str] = None,
|
|
98
|
+
self_hosted_instance_public_id: Optional[str] = None,
|
|
99
|
+
self_hosted_instance_slug: Optional[str] = None,
|
|
100
|
+
|
|
101
|
+
) -> Optional[DeployInferenceModelToInstanceResponse]:
|
|
102
|
+
request = DeployInferenceModelToInstanceRequest(
|
|
103
|
+
modelPublicId=model_public_id,
|
|
104
|
+
modelSlug=model_slug,
|
|
105
|
+
instanceRentedPublicId=rented_instance_public_id,
|
|
106
|
+
instanceRentedSlug=rented_instance_slug,
|
|
107
|
+
selfhostedInstancePublicId=self_hosted_instance_public_id,
|
|
108
|
+
selfhostedInstanceSlug=self_hosted_instance_slug
|
|
109
|
+
)
|
|
110
|
+
|
|
111
|
+
response = self._request(
|
|
112
|
+
method='POST',
|
|
113
|
+
url='/user-api/v2/inference-simulator-model/deploy/instance',
|
|
114
|
+
data=request.model_dump(),
|
|
115
|
+
token=self.__config_provider.get_config().main.thestage_auth_token,
|
|
116
|
+
)
|
|
117
|
+
return DeployInferenceModelToInstanceResponse.model_validate(response) if response else None
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@error_handler()
|
|
121
|
+
def deploy_inference_model_to_sagemaker(
|
|
122
|
+
self,
|
|
123
|
+
model_public_id: Optional[str],
|
|
124
|
+
model_slug: Optional[str],
|
|
125
|
+
arn: Optional[str] = None,
|
|
126
|
+
) -> Optional[DeployInferenceModelToSagemakerResponse]:
|
|
127
|
+
request = DeployInferenceModelToSagemakerRequest(
|
|
128
|
+
modelPublicId=model_public_id,
|
|
129
|
+
modelSlug=model_slug,
|
|
130
|
+
arn=arn,
|
|
131
|
+
)
|
|
132
|
+
|
|
133
|
+
response = self._request(
|
|
134
|
+
method='POST',
|
|
135
|
+
url='/user-api/v1/inference-simulator-model/grant-user-arn-access',
|
|
136
|
+
data=request.model_dump(),
|
|
137
|
+
token=self.__config_provider.get_config().main.thestage_auth_token,
|
|
138
|
+
)
|
|
139
|
+
return DeployInferenceModelToSagemakerResponse.model_validate(response) if response else None
|