thestage 0.6.4__py3-none-any.whl → 0.6.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. thestage/__init__.py +1 -1
  2. thestage/color_scheme/color_scheme.py +1 -0
  3. thestage/controllers/base_controller.py +4 -3
  4. thestage/controllers/config_controller.py +16 -4
  5. thestage/controllers/container_controller.py +147 -49
  6. thestage/controllers/instance_controller.py +35 -9
  7. thestage/controllers/project_controller.py +334 -86
  8. thestage/entities/container.py +5 -3
  9. thestage/entities/project_inference_simulator.py +2 -1
  10. thestage/entities/project_inference_simulator_model.py +1 -1
  11. thestage/entities/project_task.py +2 -3
  12. thestage/entities/rented_instance.py +2 -2
  13. thestage/entities/self_hosted_instance.py +2 -2
  14. thestage/helpers/error_handler.py +3 -3
  15. thestage/services/clients/git/git_client.py +8 -12
  16. thestage/services/clients/thestage_api/api_client.py +144 -109
  17. thestage/services/clients/thestage_api/dtos/base_controller/connect_resolve_response.py +21 -0
  18. thestage/services/clients/thestage_api/dtos/container_param_request.py +1 -1
  19. thestage/services/clients/thestage_api/dtos/container_response.py +1 -21
  20. thestage/services/clients/thestage_api/dtos/docker_container_controller/docker_container_list_request.py +2 -1
  21. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_request.py +7 -1
  22. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_response.py +0 -1
  23. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_sagemaker_request.py +1 -0
  24. thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_request.py +2 -1
  25. thestage/services/clients/thestage_api/dtos/inference_controller/{inference_simulator_list_for_project_request.py → inference_simulator_list_request.py} +3 -2
  26. thestage/services/clients/thestage_api/dtos/inference_controller/{inference_simulator_list_for_project_response.py → inference_simulator_list_response.py} +1 -1
  27. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_model_list_for_project_request.py +2 -1
  28. thestage/services/clients/thestage_api/dtos/instance_rented_response.py +4 -37
  29. thestage/services/clients/thestage_api/dtos/logging_controller/log_polling_request.py +3 -3
  30. thestage/services/clients/thestage_api/dtos/logging_controller/user_logs_query_request.py +3 -11
  31. thestage/services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_request.py +1 -0
  32. thestage/services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_request.py +2 -1
  33. thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_request.py +2 -4
  34. thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_request.py +5 -3
  35. thestage/services/clients/thestage_api/dtos/project_response.py +3 -15
  36. thestage/services/clients/thestage_api/dtos/selfhosted_instance_response.py +2 -20
  37. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_key_to_user_response.py +1 -1
  38. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_public_key_to_instance_request.py +4 -2
  39. thestage/services/clients/thestage_api/dtos/ssh_key_controller/is_user_has_public_ssh_key_response.py +1 -1
  40. thestage/services/clients/thestage_api/dtos/task_controller/task_list_for_project_request.py +4 -1
  41. thestage/services/clients/thestage_api/dtos/task_controller/task_view_response.py +0 -2
  42. thestage/services/config_provider/config_provider.py +2 -2
  43. thestage/services/connect/connect_service.py +76 -73
  44. thestage/services/container/container_service.py +23 -19
  45. thestage/services/container/mapper/container_mapper.py +2 -1
  46. thestage/services/instance/instance_service.py +13 -20
  47. thestage/services/instance/mapper/instance_mapper.py +1 -3
  48. thestage/services/instance/mapper/selfhosted_mapper.py +3 -4
  49. thestage/services/logging/logging_service.py +40 -40
  50. thestage/services/project/dto/inference_simulator_dto.py +1 -10
  51. thestage/services/project/dto/inference_simulator_model_dto.py +2 -10
  52. thestage/services/project/dto/project_config.py +3 -2
  53. thestage/services/project/mapper/project_inference_simulator_mapper.py +1 -0
  54. thestage/services/project/mapper/project_inference_simulator_model_mapper.py +3 -3
  55. thestage/services/project/mapper/project_task_mapper.py +2 -3
  56. thestage/services/project/project_service.py +161 -131
  57. thestage/services/remote_server_service.py +1 -0
  58. thestage/services/task/dto/task_dto.py +3 -23
  59. {thestage-0.6.4.dist-info → thestage-0.6.6.dist-info}/METADATA +3 -2
  60. {thestage-0.6.4.dist-info → thestage-0.6.6.dist-info}/RECORD +63 -72
  61. {thestage-0.6.4.dist-info → thestage-0.6.6.dist-info}/WHEEL +1 -1
  62. thestage/services/clients/thestage_api/dtos/cloud_provider_region.py +0 -19
  63. thestage/services/clients/thestage_api/dtos/docker_container_assigned_device.py +0 -10
  64. thestage/services/clients/thestage_api/dtos/enums/currency_type.py +0 -10
  65. thestage/services/clients/thestage_api/dtos/enums/daemon_status.py +0 -9
  66. thestage/services/clients/thestage_api/dtos/enums/disk_type.py +0 -7
  67. thestage/services/clients/thestage_api/dtos/enums/drive_type.py +0 -7
  68. thestage/services/clients/thestage_api/dtos/enums/instance_type.py +0 -7
  69. thestage/services/clients/thestage_api/dtos/enums/location_region.py +0 -11
  70. thestage/services/clients/thestage_api/dtos/enums/power_status.py +0 -10
  71. thestage/services/clients/thestage_api/dtos/price_definition.py +0 -14
  72. {thestage-0.6.4.dist-info → thestage-0.6.6.dist-info}/entry_points.txt +0 -0
  73. {thestage-0.6.4.dist-info → thestage-0.6.6.dist-info/licenses}/LICENSE.txt +0 -0
@@ -3,21 +3,18 @@ import typer
3
3
 
4
4
  from thestage.cli_command import CliCommand
5
5
  from thestage.cli_command_helper import check_command_permission
6
+ from thestage.color_scheme.color_scheme import ColorScheme
6
7
  from thestage.i18n.translation import __
7
8
  from thestage.services.clients.thestage_api.core.http_client_exception import HttpClientException
8
- from thestage.services.clients.thestage_api.dtos.enums.container_status import DockerContainerStatus
9
- from thestage.services.clients.thestage_api.dtos.enums.selfhosted_status import SelfhostedBusinessStatus
10
9
  from thestage.services.clients.thestage_api.dtos.enums.instance_rented_status import InstanceRentedBusinessStatus
11
10
  from thestage.services.abstract_service import AbstractService
12
11
  from thestage.helpers.error_handler import error_handler
13
12
  from thestage.services.clients.thestage_api.api_client import TheStageApiClient
14
- from thestage.services.clients.thestage_api.dtos.enums.task_status import TaskStatus
15
13
  from thestage.services.clients.thestage_api.dtos.instance_rented_response import InstanceRentedDto
16
14
  from thestage.services.container.container_service import ContainerService
17
15
  from thestage.services.instance.instance_service import InstanceService
18
16
  from thestage.services.logging.logging_service import LoggingService
19
- from thestage.services.task.dto.task_dto import TaskDto
20
- from thestage.helpers.logger.app_logger import app_logger
17
+ from rich import print
21
18
 
22
19
 
23
20
  class ConnectService(AbstractService):
@@ -44,107 +41,113 @@ class ConnectService(AbstractService):
44
41
  @error_handler()
45
42
  def connect_to_entity(
46
43
  self,
47
- uid: str,
44
+ input_entity_identifier: str,
48
45
  username: Optional[str],
49
46
  private_key_path: Optional[str],
50
47
  ):
51
- try:
52
- instance_selfhosted = self.__thestage_api_client.get_selfhosted_instance(instance_slug=uid)
53
- except HttpClientException as e:
54
- app_logger.warn(f"get_selfhosted_instance: code {e.get_status_code()}")
55
- instance_selfhosted = None
56
-
57
- try:
58
- instance_rented = self.__thestage_api_client.get_rented_instance(instance_slug=uid)
59
- except HttpClientException as e:
60
- app_logger.warn(f"get_rented_instance: code {e.get_status_code()}")
61
- instance_rented = None
62
-
63
- try:
64
- container = self.__thestage_api_client.get_container(container_slug=uid,)
65
- except HttpClientException as e:
66
- app_logger.warn(f"get_container: code {e.get_status_code()}")
67
- container = None
68
-
69
- task: Optional[TaskDto] = None
70
- if uid.isdigit():
71
- try:
72
- task_view_response = self.__thestage_api_client.get_task(task_id=int(uid))
73
- except HttpClientException as e:
74
- app_logger.warn(f"get_task error: code {e.get_status_code()}")
75
- task_view_response = None
76
- if task_view_response and task_view_response.task:
77
- task = task_view_response.task
78
-
79
- rented_exists = int(instance_rented is not None and instance_rented.frontend_status.status_key == InstanceRentedBusinessStatus.ONLINE)
80
- selfhosted_exists = int(instance_selfhosted is not None)
81
- container_exists = int(container is not None)
82
- task_exists = int(task is not None)
83
-
84
- rented_presence = int(rented_exists and instance_rented.frontend_status.status_key == InstanceRentedBusinessStatus.ONLINE)
85
- selfhosted_presence = int(selfhosted_exists and instance_selfhosted.frontend_status.status_key == SelfhostedBusinessStatus.RUNNING)
86
- container_presence = int(container_exists and (container.frontend_status.status_key == DockerContainerStatus.RUNNING or container.frontend_status.status_key == DockerContainerStatus.BUSY))
87
- task_presence = int(task_exists and task.frontend_status.status_key in [TaskStatus.RUNNING, TaskStatus.SCHEDULED])
88
-
89
- if rented_exists:
90
- typer.echo(__("Found a rented instance with the provided UID in status: '%rented_status%'", {"rented_status": instance_rented.frontend_status.status_translation}))
91
-
92
- if selfhosted_exists:
93
- typer.echo(__("Found a self-hosted instance with the provided UID in status: '%selfhosted_status%'", {"selfhosted_status": instance_selfhosted.frontend_status.status_translation}))
94
-
95
- if container_exists:
96
- typer.echo(__("Found a docker container with the provided UID in status: '%container_status%'", {"container_status": container.frontend_status.status_translation}))
97
-
98
- if task_exists:
99
- typer.echo(__("Found a task with the provided ID in status: '%task_status%'", {"task_status": task.frontend_status.status_translation}))
100
-
101
- if (rented_presence + selfhosted_presence + container_presence + task_presence) > 1:
48
+ resolved_options = self.__thestage_api_client.resolve_connect_options(entity_identifier=input_entity_identifier)
49
+ entities_available_for_connect_count = 0
50
+ task_presence = False
51
+ container_presence = False
52
+ rented_presence = False
53
+ selfhosted_presence = False
54
+ resolved_entity_public_id = None
55
+
56
+ if resolved_options.taskMatchData:
57
+ for task_item in resolved_options.taskMatchData:
58
+ message = f"Found a task with with matching {task_item.matchedField} in status: '{task_item.frontendStatus.status_translation}' (ID: {task_item.publicId})"
59
+ line_color = ColorScheme.SUCCESS if task_item.canConnect else 'default'
60
+ print(f"[{line_color}]{message}[{line_color}]")
61
+ if task_item.canConnect:
62
+ task_presence = True
63
+ resolved_entity_public_id = task_item.publicId
64
+ entities_available_for_connect_count += 1
65
+
66
+ if resolved_options.dockerContainerMatchData:
67
+ for container_item in resolved_options.dockerContainerMatchData:
68
+ message = f"Found a container with matching {container_item.matchedField} in status: '{container_item.frontendStatus.status_translation}' (ID: {container_item.publicId})"
69
+ line_color = ColorScheme.SUCCESS if container_item.canConnect else 'default'
70
+ print(f"[{line_color}]{message}[{line_color}]")
71
+ if container_item.canConnect:
72
+ container_presence = True
73
+ resolved_entity_public_id = container_item.publicId
74
+ entities_available_for_connect_count += 1
75
+
76
+ if resolved_options.instanceRentedMatchData:
77
+ for instance_rented_item in resolved_options.instanceRentedMatchData:
78
+ message = f"Found a rented instance with matching {instance_rented_item.matchedField} in status: '{instance_rented_item.frontendStatus.status_translation}' (ID: {instance_rented_item.publicId})"
79
+ line_color = ColorScheme.SUCCESS if instance_rented_item.canConnect else 'default'
80
+ print(f"[{line_color}]{message}[{line_color}]")
81
+
82
+ if instance_rented_item.canConnect:
83
+ rented_presence = True
84
+ resolved_entity_public_id = instance_rented_item.publicId
85
+ entities_available_for_connect_count += 1
86
+
87
+ if resolved_options.selfhostedInstanceMatchData:
88
+ for selfhosted_item in resolved_options.selfhostedInstanceMatchData:
89
+ message = f"Found a self-hosted instance with matching {selfhosted_item.matchedField} in status: '{selfhosted_item.frontendStatus.status_translation}' (ID: {selfhosted_item.publicId})"
90
+ line_color = ColorScheme.SUCCESS if selfhosted_item.canConnect else 'default'
91
+ print(f"[{line_color}]{message}[{line_color}]")
92
+
93
+ if selfhosted_item.canConnect:
94
+ selfhosted_presence = True
95
+ resolved_entity_public_id = selfhosted_item.publicId
96
+ entities_available_for_connect_count += 1
97
+
98
+ if entities_available_for_connect_count > 1:
102
99
  typer.echo("Provided identifier caused ambiguity")
103
100
  typer.echo("Consider running a dedicated command to connect to the entity you need")
104
101
  raise typer.Exit(code=1)
105
102
 
106
- if (rented_presence + selfhosted_presence + container_presence + task_presence) == 0:
103
+ if entities_available_for_connect_count == 0:
107
104
  typer.echo("There is nothing to connect to with the provided identifier")
108
105
  raise typer.Exit(code=1)
109
106
 
110
107
  if rented_presence:
111
108
  check_command_permission(CliCommand.INSTANCE_RENTED_CONNECT)
112
- typer.echo("Connecting to rented instance...")
109
+ typer.echo(f"Connecting to rented instance '{resolved_entity_public_id}'...")
113
110
  self.__instance_service.connect_to_rented_instance(
114
- instance_rented_slug=uid,
111
+ instance_rented_public_id=resolved_entity_public_id,
112
+ instance_rented_slug=None,
115
113
  input_ssh_key_path=private_key_path
116
114
  )
117
115
 
118
116
  if container_presence:
119
117
  check_command_permission(CliCommand.CONTAINER_CONNECT)
120
- typer.echo("Connecting to docker container...")
118
+ typer.echo(f"Connecting to docker container '{resolved_entity_public_id}'...")
121
119
  self.__container_service.connect_to_container(
122
- container_uid=uid,
120
+ container_public_id=resolved_entity_public_id,
121
+ container_slug=None,
123
122
  username=username,
124
123
  input_ssh_key_path=private_key_path
125
124
  )
126
125
 
127
126
  if selfhosted_presence:
128
127
  check_command_permission(CliCommand.INSTANCE_SELF_HOSTED_CONNECT)
129
- typer.echo("Connecting to self-hosted instance...")
128
+ typer.echo(f"Connecting to self-hosted instance '{resolved_entity_public_id}'...")
130
129
 
131
130
  self.__instance_service.connect_to_selfhosted_instance(
132
- selfhosted_instance_slug=uid,
131
+ selfhosted_instance_public_id=resolved_entity_public_id,
132
+ selfhosted_instance_slug=None,
133
133
  username=username,
134
134
  input_ssh_key_path=private_key_path
135
135
  )
136
136
 
137
137
  if task_presence:
138
- typer.echo(__("Connecting to task..."))
139
- self.__logging_service.stream_task_logs_with_controls(task_id=int(uid))
138
+ typer.echo(f"Connecting to task '{resolved_entity_public_id}'...")
139
+ self.__logging_service.stream_task_logs_with_controls(task_public_id=resolved_entity_public_id)
140
140
 
141
141
 
142
142
  @error_handler()
143
- def upload_ssh_key(self, public_key_contents: str, instance_slug: Optional[str]):
143
+ def upload_ssh_key(self, public_key_contents: str, instance_public_id: Optional[str], instance_slug: Optional[str]):
144
144
  instance_rented: Optional[InstanceRentedDto] = None
145
- if instance_slug:
145
+ if instance_slug or instance_public_id:
146
146
  try:
147
- instance_rented = self.__thestage_api_client.get_rented_instance(instance_slug=instance_slug)
147
+ instance_rented = self.__thestage_api_client.get_rented_instance(
148
+ instance_public_id=instance_public_id,
149
+ instance_slug=instance_slug
150
+ )
148
151
  except HttpClientException as e:
149
152
  instance_rented = None
150
153
 
@@ -159,7 +162,7 @@ class ConnectService(AbstractService):
159
162
  public_key=public_key_contents
160
163
  )
161
164
 
162
- ssh_key_pair_id = is_user_already_has_key_response.sshKeyPairId
165
+ ssh_key_pair_public_id = is_user_already_has_key_response.sshKeyPairPublicId
163
166
  is_adding_key_to_user = not is_user_already_has_key_response.isUserHasPublicKey
164
167
 
165
168
  if is_adding_key_to_user and not note_to_send:
@@ -179,12 +182,12 @@ class ConnectService(AbstractService):
179
182
  note=note_to_send
180
183
  )
181
184
  typer.echo(f"Public key '{note_to_send}' added to your profile")
182
- ssh_key_pair_id = add_ssh_key_to_user_response.sshKeyPairId
185
+ ssh_key_pair_public_id = add_ssh_key_to_user_response.sshKeyPairPublicId
183
186
 
184
187
  if instance_rented:
185
188
  self.__thestage_api_client.add_public_ssh_key_to_instance_rented(
186
- instance_rented_id=instance_rented.id,
187
- ssh_key_pair_id=ssh_key_pair_id
189
+ instance_rented_public_id=instance_rented.public_id,
190
+ ssh_key_pair_public_id=ssh_key_pair_public_id
188
191
  )
189
192
 
190
193
  if instance_rented.frontend_status.status_key != InstanceRentedBusinessStatus.ONLINE:
@@ -42,7 +42,8 @@ class ContainerService(AbstractService):
42
42
  self,
43
43
  row: int,
44
44
  page: int,
45
- project_uid: Optional[str],
45
+ project_public_id: Optional[str],
46
+ project_slug: Optional[str],
46
47
  statuses: List[str],
47
48
  ):
48
49
  container_status_map = self.__thestage_api_client.get_container_business_status_map()
@@ -72,22 +73,18 @@ class ContainerService(AbstractService):
72
73
 
73
74
  backend_statuses: List[str] = [key for key, value in container_status_map.items() if value in statuses]
74
75
 
75
- project_id: Optional[int] = None
76
- if project_uid:
77
- project = self.__thestage_api_client.get_project_by_slug(slug=project_uid)
78
- project_id = project.id
79
-
80
76
  self.print(
81
77
  func_get_data=self.get_list,
82
78
  func_special_params={
83
79
  'statuses': backend_statuses,
84
- 'project_id': project_id,
80
+ 'project_slug': project_slug,
81
+ 'project_public_id': project_public_id,
85
82
  },
86
83
  mapper=ContainerMapper(),
87
84
  headers=list(map(lambda x: x.alias, DockerContainerEntity.model_fields.values())),
88
85
  row=row,
89
86
  page=page,
90
- max_col_width=[15, 20, 25],
87
+ max_col_width=[35, 20, 25],
91
88
  show_index="never",
92
89
  )
93
90
 
@@ -98,26 +95,29 @@ class ContainerService(AbstractService):
98
95
  statuses: List[str],
99
96
  row: int = 5,
100
97
  page: int = 1,
101
- project_id: Optional[int] = None,
98
+ project_public_id: Optional[str] = None,
99
+ project_slug: Optional[str] = None,
102
100
  ) -> PaginatedEntityList[DockerContainerDto]:
103
101
 
104
102
  list = self.__thestage_api_client.get_container_list(
105
103
  statuses=statuses,
106
104
  page=page,
107
105
  limit=row,
108
- project_id=project_id,
106
+ project_public_id=project_public_id,
107
+ project_slug=project_slug
109
108
  )
110
109
 
111
110
  return list
112
111
 
112
+ # TODO delete this proxy method
113
113
  @error_handler()
114
114
  def get_container(
115
115
  self,
116
- container_id: Optional[int] = None,
116
+ container_public_id: Optional[str] = None,
117
117
  container_slug: Optional[str] = None,
118
118
  ) -> Optional[DockerContainerDto]:
119
119
  return self.__thestage_api_client.get_container(
120
- container_id=container_id,
120
+ container_public_id=container_public_id,
121
121
  container_slug=container_slug,
122
122
  )
123
123
 
@@ -160,16 +160,18 @@ class ContainerService(AbstractService):
160
160
  @error_handler()
161
161
  def connect_to_container(
162
162
  self,
163
- container_uid: str,
163
+ container_public_id: Optional[str],
164
+ container_slug: Optional[str],
164
165
  username: Optional[str],
165
166
  input_ssh_key_path: Optional[str],
166
167
  ):
167
168
  container: Optional[DockerContainerDto] = self.get_container(
168
- container_slug=container_uid,
169
+ container_public_id=container_public_id,
170
+ container_slug=container_slug,
169
171
  )
170
172
 
171
173
  if not container:
172
- typer.echo(f"Container with UID '{container_uid}' not found")
174
+ typer.echo(f"Container not found")
173
175
  raise typer.Exit(1)
174
176
 
175
177
  self.check_if_container_running(
@@ -346,14 +348,16 @@ class ContainerService(AbstractService):
346
348
  @error_handler()
347
349
  def request_docker_container_action(
348
350
  self,
349
- container_uid: str,
351
+ container_public_id: Optional[str],
352
+ container_slug: Optional[str],
350
353
  action: DockerContainerAction,
351
354
  ):
352
355
  container: Optional[DockerContainerDto] = self.get_container(
353
- container_slug=container_uid,
356
+ container_public_id=container_public_id,
357
+ container_slug=container_slug,
354
358
  )
355
359
  if not container:
356
- typer.echo(f"Container with unique ID '{container_uid}' not found")
360
+ typer.echo(f"Container not found")
357
361
  raise typer.Exit(1)
358
362
 
359
363
  if action == DockerContainerAction.START:
@@ -363,7 +367,7 @@ class ContainerService(AbstractService):
363
367
  self.check_if_container_running(container=container)
364
368
 
365
369
  request_params = DockerContainerActionRequestDto(
366
- dockerContainerId=container.id,
370
+ dockerContainerPublicId=container.public_id,
367
371
  action=action,
368
372
  )
369
373
  result = self.__thestage_api_client.container_action(
@@ -22,8 +22,9 @@ class ContainerMapper(AbstractMapper):
22
22
 
23
23
  return DockerContainerEntity(
24
24
  status=item.frontend_status.status_translation if item.frontend_status else '',
25
+ public_id=item.public_id or '',
25
26
  slug=item.slug or '',
26
- title=item.title or '',
27
+ project_slug=item.project.slug if item.project else '',
27
28
  instance_type=instance_type,
28
29
  instance_slug=instance_slug,
29
30
  docker_image=item.docker_image or '',
@@ -35,21 +35,6 @@ class InstanceService(AbstractService):
35
35
  self.__remote_server_service = remote_server_service
36
36
  self.__config_provider = config_provider
37
37
 
38
- def get_rented_instance(
39
- self,
40
- instance_slug: str,
41
- ) -> Optional[InstanceRentedDto]:
42
- return self.__thestage_api_client.get_rented_instance(
43
- instance_slug=instance_slug,
44
- )
45
-
46
- def get_self_hosted_instance(
47
- self,
48
- instance_slug: str,
49
- ) -> Optional[SelfHostedInstanceDto]:
50
- return self.__thestage_api_client.get_selfhosted_instance(
51
- instance_slug=instance_slug,
52
- )
53
38
 
54
39
  @error_handler()
55
40
  def check_instance_status_to_connect(
@@ -116,10 +101,14 @@ class InstanceService(AbstractService):
116
101
  @error_handler()
117
102
  def connect_to_rented_instance(
118
103
  self,
119
- instance_rented_slug: str,
104
+ instance_rented_public_id: Optional[str],
105
+ instance_rented_slug: Optional[str],
120
106
  input_ssh_key_path: Optional[str]
121
107
  ):
122
- instance = self.get_rented_instance(instance_slug=instance_rented_slug)
108
+ instance = self.__thestage_api_client.get_rented_instance(
109
+ instance_public_id=instance_rented_public_id,
110
+ instance_slug=instance_rented_slug,
111
+ )
123
112
 
124
113
  if instance:
125
114
  self.check_instance_status_to_connect(
@@ -151,7 +140,8 @@ class InstanceService(AbstractService):
151
140
  @error_handler()
152
141
  def connect_to_selfhosted_instance(
153
142
  self,
154
- selfhosted_instance_slug: str,
143
+ selfhosted_instance_public_id: Optional[str],
144
+ selfhosted_instance_slug: Optional[str],
155
145
  username: str,
156
146
  input_ssh_key_path: Optional[str],
157
147
  ):
@@ -159,7 +149,10 @@ class InstanceService(AbstractService):
159
149
  username = 'root'
160
150
  typer.echo(__("No remote server username provided, using 'root' as username"))
161
151
 
162
- instance = self.get_self_hosted_instance(instance_slug=selfhosted_instance_slug)
152
+ instance = self.__thestage_api_client.get_selfhosted_instance(
153
+ instance_public_id=selfhosted_instance_public_id,
154
+ instance_slug=selfhosted_instance_slug,
155
+ )
163
156
 
164
157
  if instance:
165
158
  self.check_selfhosted_status_to_connect(
@@ -184,7 +177,7 @@ class InstanceService(AbstractService):
184
177
  if input_ssh_key_path:
185
178
  self.__config_provider.update_remote_server_config_entry(ip_address=instance.ip_address, ssh_key_path=Path(input_ssh_key_path))
186
179
  else:
187
- typer.echo(__("Server instance not found: %instance_item%", {'instance_item': selfhosted_instance_slug}))
180
+ typer.echo("Self-hosted instance not found")
188
181
 
189
182
 
190
183
  @error_handler()
@@ -13,12 +13,10 @@ class InstanceMapper(AbstractMapper):
13
13
 
14
14
  return RentedInstanceEntity(
15
15
  slug=item.slug if item.slug else '',
16
- title=item.title if item.title else '',
16
+ public_id=item.public_id if item.public_id else '',
17
17
  cpu_type=item.cpu_type if item.cpu_type else '',
18
18
  gpu_type=item.gpu_type if item.gpu_type else '',
19
19
  cpu_cores=str(item.cpu_cores) if item.cpu_cores else '',
20
20
  ip_address=item.ip_address if item.ip_address else '',
21
21
  status=item.frontend_status.status_translation if item.frontend_status else '',
22
- created_at=str(item.created_at.strftime("%Y-%m-%d %H:%M:%S")) if item.created_at else '',
23
- updated_at=str(item.updated_at.strftime("%Y-%m-%d %H:%M:%S")) if item.updated_at else '',
24
22
  )
@@ -3,6 +3,7 @@ from typing import Optional, Any, Tuple
3
3
 
4
4
  from thestage.entities.rented_instance import RentedInstanceEntity
5
5
  from thestage.entities.self_hosted_instance import SelfHostedInstanceEntity
6
+ from thestage.services.clients.thestage_api.dtos.enums.gpu_name import InstanceGpuType
6
7
  from thestage.services.clients.thestage_api.dtos.selfhosted_instance_response import SelfHostedInstanceDto
7
8
  from thestage.services.abstract_mapper import AbstractMapper
8
9
 
@@ -18,16 +19,14 @@ class SelfHostedMapper(AbstractMapper):
18
19
  gpus = [item.type.value for item in item.detected_gpus.gpus]
19
20
 
20
21
  if len(gpus) == 0:
21
- gpus = ['NO_GPU']
22
+ gpus = [InstanceGpuType.NO_GPU]
22
23
 
23
24
  return SelfHostedInstanceEntity(
24
25
  slug=item.slug,
25
- title=item.title,
26
+ public_id=item.public_id,
26
27
  cpu_type=item.cpu_type,
27
28
  cpu_cores=item.cpu_cores,
28
29
  gpu_type=', '.join(gpus),
29
30
  ip_address=item.ip_address,
30
31
  status=item.frontend_status.status_translation if item.frontend_status else None,
31
- created_at=item.created_at.strftime("%Y-%m-%d %H:%M:%S") if item.created_at else '',
32
- updated_at=item.updated_at.strftime("%Y-%m-%d %H:%M:%S") if item.updated_at else '',
33
32
  )