thestage 0.6.5__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 (72) 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/thestage_api/api_client.py +144 -109
  16. thestage/services/clients/thestage_api/dtos/base_controller/connect_resolve_response.py +21 -0
  17. thestage/services/clients/thestage_api/dtos/container_param_request.py +1 -1
  18. thestage/services/clients/thestage_api/dtos/container_response.py +1 -21
  19. thestage/services/clients/thestage_api/dtos/docker_container_controller/docker_container_list_request.py +2 -1
  20. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_request.py +7 -1
  21. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_response.py +0 -1
  22. thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_sagemaker_request.py +1 -0
  23. thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_request.py +2 -1
  24. thestage/services/clients/thestage_api/dtos/inference_controller/{inference_simulator_list_for_project_request.py → inference_simulator_list_request.py} +3 -2
  25. thestage/services/clients/thestage_api/dtos/inference_controller/{inference_simulator_list_for_project_response.py → inference_simulator_list_response.py} +1 -1
  26. thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_model_list_for_project_request.py +2 -1
  27. thestage/services/clients/thestage_api/dtos/instance_rented_response.py +4 -37
  28. thestage/services/clients/thestage_api/dtos/logging_controller/log_polling_request.py +3 -3
  29. thestage/services/clients/thestage_api/dtos/logging_controller/user_logs_query_request.py +3 -11
  30. thestage/services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_request.py +1 -0
  31. thestage/services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_request.py +2 -1
  32. thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_request.py +2 -4
  33. thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_request.py +5 -3
  34. thestage/services/clients/thestage_api/dtos/project_response.py +3 -15
  35. thestage/services/clients/thestage_api/dtos/selfhosted_instance_response.py +2 -20
  36. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_key_to_user_response.py +1 -1
  37. thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_public_key_to_instance_request.py +4 -2
  38. thestage/services/clients/thestage_api/dtos/ssh_key_controller/is_user_has_public_ssh_key_response.py +1 -1
  39. thestage/services/clients/thestage_api/dtos/task_controller/task_list_for_project_request.py +4 -1
  40. thestage/services/clients/thestage_api/dtos/task_controller/task_view_response.py +0 -2
  41. thestage/services/config_provider/config_provider.py +2 -2
  42. thestage/services/connect/connect_service.py +76 -73
  43. thestage/services/container/container_service.py +23 -19
  44. thestage/services/container/mapper/container_mapper.py +2 -1
  45. thestage/services/instance/instance_service.py +13 -20
  46. thestage/services/instance/mapper/instance_mapper.py +1 -3
  47. thestage/services/instance/mapper/selfhosted_mapper.py +3 -4
  48. thestage/services/logging/logging_service.py +40 -40
  49. thestage/services/project/dto/inference_simulator_dto.py +1 -10
  50. thestage/services/project/dto/inference_simulator_model_dto.py +2 -10
  51. thestage/services/project/dto/project_config.py +3 -2
  52. thestage/services/project/mapper/project_inference_simulator_mapper.py +1 -0
  53. thestage/services/project/mapper/project_inference_simulator_model_mapper.py +2 -2
  54. thestage/services/project/mapper/project_task_mapper.py +2 -3
  55. thestage/services/project/project_service.py +161 -131
  56. thestage/services/remote_server_service.py +1 -0
  57. thestage/services/task/dto/task_dto.py +3 -23
  58. {thestage-0.6.5.dist-info → thestage-0.6.6.dist-info}/METADATA +3 -2
  59. {thestage-0.6.5.dist-info → thestage-0.6.6.dist-info}/RECORD +62 -71
  60. {thestage-0.6.5.dist-info → thestage-0.6.6.dist-info}/WHEEL +1 -1
  61. thestage/services/clients/thestage_api/dtos/cloud_provider_region.py +0 -19
  62. thestage/services/clients/thestage_api/dtos/docker_container_assigned_device.py +0 -10
  63. thestage/services/clients/thestage_api/dtos/enums/currency_type.py +0 -10
  64. thestage/services/clients/thestage_api/dtos/enums/daemon_status.py +0 -9
  65. thestage/services/clients/thestage_api/dtos/enums/disk_type.py +0 -7
  66. thestage/services/clients/thestage_api/dtos/enums/drive_type.py +0 -7
  67. thestage/services/clients/thestage_api/dtos/enums/instance_type.py +0 -7
  68. thestage/services/clients/thestage_api/dtos/enums/location_region.py +0 -11
  69. thestage/services/clients/thestage_api/dtos/enums/power_status.py +0 -10
  70. thestage/services/clients/thestage_api/dtos/price_definition.py +0 -14
  71. {thestage-0.6.5.dist-info → thestage-0.6.6.dist-info}/entry_points.txt +0 -0
  72. {thestage-0.6.5.dist-info → thestage-0.6.6.dist-info/licenses}/LICENSE.txt +0 -0
thestage/__init__.py CHANGED
@@ -1,3 +1,3 @@
1
1
  from . import *
2
2
  __app_name__ = "thestage"
3
- __version__ = "0.6.5"
3
+ __version__ = "0.6.6"
@@ -5,3 +5,4 @@ class ColorScheme(str, Enum):
5
5
  GIT_HEADLESS = "orange_red1"
6
6
  WARNING = "orange_red1"
7
7
  USEFUL_INFO = "deep_sky_blue1"
8
+ SUCCESS = "green"
@@ -27,8 +27,9 @@ def version():
27
27
 
28
28
  @app.command(name="connect", no_args_is_help=True, help=__("Connect to server instance or container or task"), **get_command_metadata(CliCommand.CONNECT))
29
29
  def connect(
30
- uid: Optional[str] = typer.Argument(
31
- help=__("Unique ID of server instance or container or task ID"), ),
30
+ entity_identifier: Optional[str] = typer.Argument(
31
+ help="Name or ID of server instance or container or task",
32
+ ),
32
33
  username: Optional[str] = typer.Option(
33
34
  None,
34
35
  '--username',
@@ -57,7 +58,7 @@ def connect(
57
58
  connect_service: ConnectService = service_factory.get_connect_service()
58
59
 
59
60
  connect_service.connect_to_entity(
60
- uid=uid,
61
+ input_entity_identifier=entity_identifier,
61
62
  username=username,
62
63
  private_key_path=private_ssh_key_path
63
64
  )
@@ -85,13 +85,20 @@ def config_clear():
85
85
  @app.command(name='upload-ssh-key', no_args_is_help=True, help=__("Send your public SSH key to the platform and / or rented server instance"), **get_command_metadata(CliCommand.CONFIG_UPLOAD_SSH_KEY))
86
86
  def upload_ssh_key(
87
87
  ssh_public_key: str = typer.Argument(
88
- help=__("Path to your public SSH key file or your public SSH key contents"),
88
+ help=__("Path to your public SSH key file or your public SSH key contents. OpenSSH key format is required."),
89
+ ),
90
+ instance_rented_public_id: str = typer.Option(
91
+ None,
92
+ "--instance-rented-id",
93
+ "-rid",
94
+ help=__("ID of your rented instance to add the key to (optional)"),
95
+ is_eager=False,
89
96
  ),
90
97
  instance_rented_slug: str = typer.Option(
91
98
  None,
92
- "--instance-uid",
93
- "-uid",
94
- help=__("Unique ID of your rented instance to add the key to (optional)"),
99
+ "--instance-rented-name",
100
+ "-rn",
101
+ help=__("Name of your rented instance to add the key to (optional)"),
95
102
  is_eager=False,
96
103
  )
97
104
  ):
@@ -99,6 +106,10 @@ def upload_ssh_key(
99
106
  app_logger.info(f'Running {command_name} from {get_current_directory()}')
100
107
  check_command_permission(command_name)
101
108
 
109
+ if sum(v is not None for v in [instance_rented_public_id, instance_rented_slug]) > 1:
110
+ typer.echo("Please provide a single identifier for rented instance - ID or name.")
111
+ raise typer.Exit(1)
112
+
102
113
  service_factory = ServiceFactory()
103
114
  connect_service: ConnectService = service_factory.get_connect_service()
104
115
 
@@ -131,6 +142,7 @@ def upload_ssh_key(
131
142
 
132
143
  connect_service.upload_ssh_key(
133
144
  public_key_contents=ssh_key_contents,
145
+ instance_public_id=instance_rented_public_id,
134
146
  instance_slug=instance_rented_slug,
135
147
  )
136
148
 
@@ -35,11 +35,18 @@ def list_containers(
35
35
  help=__("Set starting page for displaying output"),
36
36
  is_eager=False,
37
37
  ),
38
- project_uid: str = typer.Option(
38
+ project_public_id: str = typer.Option(
39
39
  None,
40
- '--project-uid',
41
- '-puid',
42
- help=__("Filter containers by project unique ID"),
40
+ '--project-id',
41
+ '-pid',
42
+ help=__("Filter containers by project, using the project's ID"),
43
+ is_eager=False,
44
+ ),
45
+ project_slug: str = typer.Option(
46
+ None,
47
+ '--project-name',
48
+ '-pn',
49
+ help=__("Filter containers by project, using the project's name"),
43
50
  is_eager=False,
44
51
  ),
45
52
  statuses: List[str] = typer.Option(
@@ -54,12 +61,17 @@ def list_containers(
54
61
  app_logger.info(f'Running {command_name}')
55
62
  check_command_permission(command_name)
56
63
 
64
+ if sum(v is not None for v in [project_public_id, project_slug]) > 1:
65
+ typer.echo("Please provide a single identifier for project - ID or name.")
66
+ raise typer.Exit(1)
67
+
57
68
  service_factory = validate_config_and_get_service_factory()
58
69
  container_service: ContainerService = service_factory.get_container_service()
59
70
  container_service.print_container_list(
60
71
  row=row,
61
72
  page=page,
62
- project_uid=project_uid,
73
+ project_public_id=project_public_id,
74
+ project_slug=project_slug,
63
75
  statuses=statuses,
64
76
  )
65
77
 
@@ -69,45 +81,61 @@ def list_containers(
69
81
 
70
82
  @app.command(name="info", no_args_is_help=True, help=__("Get container info"), **get_command_metadata(CliCommand.CONTAINER_INFO))
71
83
  def container_info(
72
- container_uid: Optional[str] = typer.Argument(hidden=False, help=__("Container unique ID")),
84
+ container_public_id: str = typer.Option(
85
+ None,
86
+ '--container-id',
87
+ '-cid',
88
+ help=__("Container ID"),
89
+ is_eager=False,
90
+ ),
91
+ container_slug: str = typer.Option(
92
+ None,
93
+ '--container-name',
94
+ '-cn',
95
+ help=__("Container name"),
96
+ is_eager=False,
97
+ ),
73
98
  ):
74
99
  command_name = CliCommand.CONTAINER_INFO
75
100
  app_logger.info(f'Running {command_name} from {get_current_directory()}')
76
101
  check_command_permission(command_name)
77
102
 
78
- if not container_uid:
79
- typer.echo(__('Container unique ID is required'))
103
+ if sum(v is not None for v in [container_public_id, container_slug]) != 1:
104
+ typer.echo("Please provide a single identifier for container - ID or name.")
80
105
  raise typer.Exit(1)
81
106
 
82
107
  service_factory = validate_config_and_get_service_factory()
83
108
  container_service: ContainerService = service_factory.get_container_service()
84
109
 
85
110
  container: Optional[DockerContainerDto] = container_service.get_container(
86
- container_slug=container_uid,
111
+ container_public_id=container_public_id,
112
+ container_slug=container_slug,
87
113
  )
88
114
 
89
115
  if not container:
90
- typer.echo(__("Container not found: %container_item%", {'container_item': str(container_uid) if container_uid else ''}))
116
+ typer.echo("Container not found")
91
117
  raise typer.Exit(1)
92
118
 
93
119
  typer.echo(__("STATUS: %status%", {'status': str(container.frontend_status.status_translation if container and container.frontend_status else 'UNKNOWN')}))
94
- typer.echo(__("UNIQUE ID: %slug%", {'slug': str(container.slug)}))
95
- typer.echo(__("TITLE: %title%", {'title': str(container.title)}))
120
+ typer.echo(__("ID: %slug%", {'slug': str(container.public_id)}))
121
+ typer.echo(__("NAME: %title%", {'title': str(container.slug)}))
96
122
  typer.echo(__("IMAGE: %image%", {'image': str(container.docker_image)}))
97
123
 
124
+ typer.echo(f"CONTAINER INSTANCE:")
125
+
98
126
  if container.instance_rented:
127
+ typer.echo(f" TYPE: RENTED")
128
+ typer.echo(f" ID: {container.instance_rented.public_id}")
129
+ typer.echo(f" NAME: {container.instance_rented.slug}")
99
130
  typer.echo(
100
- __("RENTED SERVER INSTANCE UNIQUE ID: %instance_slug%", {'instance_slug': str(container.instance_rented.slug)})
101
- )
102
- typer.echo(
103
- __("RENTED SERVER INSTANCE STATUS: %instance_status%",
131
+ __("RENTED INSTANCE STATUS: %instance_status%",
104
132
  {'instance_status': str(container.instance_rented.frontend_status.status_translation if container.instance_rented.frontend_status else 'UNKNOWN')})
105
133
  )
106
134
 
107
135
  if container.selfhosted_instance:
108
- typer.echo(
109
- __("SELF-HOSTED INSTANCE UNIQUE ID: %instance_slug%", {'instance_slug': str(container.selfhosted_instance.slug)})
110
- )
136
+ typer.echo(f" TYPE: SELF-HOSTED")
137
+ typer.echo(f" ID: {container.selfhosted_instance.public_id}")
138
+ typer.echo(f" NAME: {container.selfhosted_instance.slug}")
111
139
  typer.echo(
112
140
  __("SELF-HOSTED INSTANCE STATUS: %instance_status%",
113
141
  {'instance_status': str(container.selfhosted_instance.frontend_status.status_translation if container.selfhosted_instance.frontend_status else 'UNKNOWN')})
@@ -129,7 +157,20 @@ def container_info(
129
157
 
130
158
  @app.command(name="connect", no_args_is_help=True, help=__("Connect to container"), **get_command_metadata(CliCommand.CONTAINER_CONNECT))
131
159
  def container_connect(
132
- container_uid: Optional[str] = typer.Argument(help=__("Container unique ID"),),
160
+ container_public_id: str = typer.Option(
161
+ None,
162
+ '--container-id',
163
+ '-cid',
164
+ help=__("Container ID"),
165
+ is_eager=False,
166
+ ),
167
+ container_slug: str = typer.Option(
168
+ None,
169
+ '--container-name',
170
+ '-cn',
171
+ help=__("Container name"),
172
+ is_eager=False,
173
+ ),
133
174
  username: Optional[str] = typer.Option(
134
175
  None,
135
176
  '--username',
@@ -149,8 +190,8 @@ def container_connect(
149
190
  app_logger.info(f'Running {command_name} from {get_current_directory()}')
150
191
  check_command_permission(command_name)
151
192
 
152
- if not container_uid:
153
- typer.echo(__('Container unique ID is required'))
193
+ if sum(v is not None for v in [container_public_id, container_slug]) != 1:
194
+ typer.echo("Please provide a single identifier for container - ID or name.")
154
195
  raise typer.Exit(1)
155
196
 
156
197
  if private_ssh_key_path and not Path(private_ssh_key_path).is_file():
@@ -161,7 +202,8 @@ def container_connect(
161
202
  container_service: ContainerService = service_factory.get_container_service()
162
203
 
163
204
  container_service.connect_to_container(
164
- container_uid=container_uid,
205
+ container_public_id=container_public_id,
206
+ container_slug=container_slug,
165
207
  username=username,
166
208
  input_ssh_key_path=private_ssh_key_path,
167
209
  )
@@ -173,7 +215,7 @@ def container_connect(
173
215
  @app.command(name="upload", no_args_is_help=True, help=__("Upload file to container"), **get_command_metadata(CliCommand.CONTAINER_UPLOAD))
174
216
  def upload_file(
175
217
  source_path: str = typer.Argument(help=__("Source file path"),),
176
- destination: Optional[str] = typer.Argument(help=__("Destination directory path in container. Format: container_uid:/path/to/file"),),
218
+ destination: Optional[str] = typer.Argument(help=__("Destination directory path in container. Format: container_name:/path/to/file"),),
177
219
  username: Optional[str] = typer.Option(
178
220
  None,
179
221
  '--username',
@@ -189,14 +231,14 @@ def upload_file(
189
231
  container_args = re.match(r"^([\w\W]+?):([\w\W]+)$", destination)
190
232
 
191
233
  if container_args is None:
192
- typer.echo(__('Container unique ID and source file path are required as the second argument'))
234
+ typer.echo(__('Container name and source file path are required as the second argument'))
193
235
  typer.echo(__('Example: container_uid:/path/to/file'))
194
236
  raise typer.Exit(1)
195
237
  container_slug = container_args.groups()[0]
196
238
  destination_path = container_args.groups()[1].rstrip("/")
197
239
 
198
240
  if not container_slug:
199
- typer.echo(__('Container unique ID is required'))
241
+ typer.echo(__('Container name is required'))
200
242
  raise typer.Exit(1)
201
243
 
202
244
  service_factory = validate_config_and_get_service_factory()
@@ -211,7 +253,7 @@ def upload_file(
211
253
  container=container
212
254
  )
213
255
 
214
- typer.echo(__("Uploading file(s) to container '%container-slug%'", {'container-slug': container_slug}))
256
+ typer.echo(f"Uploading file(s) to container '{container_slug}'")
215
257
 
216
258
  container_service.put_file_to_container(
217
259
  container=container,
@@ -229,7 +271,7 @@ def upload_file(
229
271
 
230
272
  @app.command(name="download", no_args_is_help=True, help=__("Download file from container"), **get_command_metadata(CliCommand.CONTAINER_DOWNLOAD))
231
273
  def download_file(
232
- source_path: str = typer.Argument(help=__("Source file path in container. Format: container_uid:/path/to/file"),),
274
+ source_path: str = typer.Argument(help=__("Source file path in container. Format: container_name:/path/to/file"),),
233
275
  destination_path: str = typer.Argument(help=__("Destination directory path on local machine"),),
234
276
  username: Optional[str] = typer.Option(
235
277
  None,
@@ -246,14 +288,14 @@ def download_file(
246
288
  container_args = re.match(r"^([\w\W]+?):([\w\W]+)$", source_path)
247
289
 
248
290
  if container_args is None:
249
- typer.echo(__('Container unique ID and source directory path are required as the first argument'))
291
+ typer.echo(__('Container name and source directory path are required as the first argument'))
250
292
  typer.echo(__('Example: container-uid:/path/to/file'))
251
293
  raise typer.Exit(1)
252
294
  container_slug = container_args.groups()[0]
253
295
  source_path = container_args.groups()[1]
254
296
 
255
297
  if not container_slug:
256
- typer.echo(__('Container unique ID is required'))
298
+ typer.echo(__('Container name is required'))
257
299
  raise typer.Exit(1)
258
300
 
259
301
  service_factory = validate_config_and_get_service_factory()
@@ -268,7 +310,7 @@ def download_file(
268
310
  container=container
269
311
  )
270
312
 
271
- typer.echo(__("Downloading files from container: '%container-slug%'", {'container-slug': container_slug}))
313
+ typer.echo(f"Downloading files from container: '{container_slug}'")
272
314
 
273
315
  container_service.get_file_from_container(
274
316
  container=container,
@@ -278,7 +320,7 @@ def download_file(
278
320
  copy_only_folder_contents=source_path.endswith("/"),
279
321
  )
280
322
  else:
281
- typer.echo(__("Container not found: %container_item%", {'container_item': container_slug}))
323
+ typer.echo(f"Container not found: {container_slug}")
282
324
 
283
325
  app_logger.info(f'End download files from container')
284
326
  raise typer.Exit(0)
@@ -286,21 +328,35 @@ def download_file(
286
328
 
287
329
  @app.command(name="start", no_args_is_help=True, help=__("Start container"), **get_command_metadata(CliCommand.CONTAINER_START))
288
330
  def start_container(
289
- container_uid: Optional[str] = typer.Argument(help=__("Container unique ID"), ),
331
+ container_public_id: str = typer.Option(
332
+ None,
333
+ '--container-id',
334
+ '-cid',
335
+ help=__("Container ID"),
336
+ is_eager=False,
337
+ ),
338
+ container_slug: str = typer.Option(
339
+ None,
340
+ '--container-name',
341
+ '-cn',
342
+ help=__("Container name"),
343
+ is_eager=False,
344
+ ),
290
345
  ):
291
346
  command_name = CliCommand.CONTAINER_START
292
347
  app_logger.info(f'Running {command_name} from {get_current_directory()}')
293
348
  check_command_permission(command_name)
294
349
 
295
- if not container_uid:
296
- typer.echo(__('Container unique ID is required'))
350
+ if sum(v is not None for v in [container_public_id, container_slug]) != 1:
351
+ typer.echo("Please provide a single identifier for container - ID or name.")
297
352
  raise typer.Exit(1)
298
353
 
299
354
  service_factory = validate_config_and_get_service_factory()
300
355
  container_service: ContainerService = service_factory.get_container_service()
301
356
 
302
357
  container_service.request_docker_container_action(
303
- container_uid=container_uid,
358
+ container_public_id=container_public_id,
359
+ container_slug=container_slug,
304
360
  action=DockerContainerAction.START
305
361
  )
306
362
 
@@ -310,21 +366,35 @@ def start_container(
310
366
 
311
367
  @app.command(name="stop", no_args_is_help=True, help=__("Stop container"), **get_command_metadata(CliCommand.CONTAINER_STOP))
312
368
  def stop_container(
313
- container_uid: Optional[str] = typer.Argument(help=__("Container unique ID"), ),
369
+ container_public_id: str = typer.Option(
370
+ None,
371
+ '--container-id',
372
+ '-cid',
373
+ help=__("Container ID"),
374
+ is_eager=False,
375
+ ),
376
+ container_slug: str = typer.Option(
377
+ None,
378
+ '--container-name',
379
+ '-cn',
380
+ help=__("Container name"),
381
+ is_eager=False,
382
+ ),
314
383
  ):
315
384
  command_name = CliCommand.CONTAINER_STOP
316
385
  app_logger.info(f'Running {command_name} from {get_current_directory()}')
317
386
  check_command_permission(command_name)
318
387
 
319
- if not container_uid:
320
- typer.echo(__('Container unique ID is required'))
388
+ if sum(v is not None for v in [container_public_id, container_slug]) != 1:
389
+ typer.echo("Please provide a single identifier for container - ID or name.")
321
390
  raise typer.Exit(1)
322
391
 
323
392
  service_factory = validate_config_and_get_service_factory()
324
393
  container_service: ContainerService = service_factory.get_container_service()
325
394
 
326
395
  container_service.request_docker_container_action(
327
- container_uid=container_uid,
396
+ container_public_id=container_public_id,
397
+ container_slug=container_slug,
328
398
  action=DockerContainerAction.STOP
329
399
  )
330
400
 
@@ -334,21 +404,35 @@ def stop_container(
334
404
 
335
405
  @app.command(name="restart", no_args_is_help=True, help=__("Restart container"), **get_command_metadata(CliCommand.CONTAINER_RESTART))
336
406
  def restart_container(
337
- container_uid: Optional[str] = typer.Argument(help=__("Container unique ID"), ),
407
+ container_public_id: str = typer.Option(
408
+ None,
409
+ '--container-id',
410
+ '-cid',
411
+ help=__("Container ID"),
412
+ is_eager=False,
413
+ ),
414
+ container_slug: str = typer.Option(
415
+ None,
416
+ '--container-name',
417
+ '-cn',
418
+ help=__("Container name"),
419
+ is_eager=False,
420
+ ),
338
421
  ):
339
422
  command_name = CliCommand.CONTAINER_RESTART
340
423
  app_logger.info(f'Running {command_name} from {get_current_directory()}')
341
424
  check_command_permission(command_name)
342
425
 
343
- if not container_uid:
344
- typer.echo(__('Container unique ID is required'))
426
+ if sum(v is not None for v in [container_public_id, container_slug]) != 1:
427
+ typer.echo("Please provide a single identifier for container - ID or name.")
345
428
  raise typer.Exit(1)
346
429
 
347
430
  service_factory = validate_config_and_get_service_factory()
348
431
  container_service: ContainerService = service_factory.get_container_service()
349
432
 
350
433
  container_service.request_docker_container_action(
351
- container_uid=container_uid,
434
+ container_public_id=container_public_id,
435
+ container_slug=container_slug,
352
436
  action=DockerContainerAction.RESTART
353
437
  )
354
438
 
@@ -358,7 +442,20 @@ def restart_container(
358
442
 
359
443
  @app.command(name="logs", no_args_is_help=True, help=__("Stream real-time Docker container logs or view last logs for a container"), **get_command_metadata(CliCommand.CONTAINER_LOGS))
360
444
  def container_logs(
361
- container_uid: Optional[str] = typer.Argument(help=__("Container unique id")),
445
+ container_public_id: str = typer.Option(
446
+ None,
447
+ '--container-id',
448
+ '-cid',
449
+ help=__("Container ID"),
450
+ is_eager=False,
451
+ ),
452
+ container_slug: str = typer.Option(
453
+ None,
454
+ '--container-name',
455
+ '-cn',
456
+ help=__("Container name"),
457
+ is_eager=False,
458
+ ),
362
459
  logs_number: Optional[int] = typer.Option(
363
460
  None,
364
461
  '--number',
@@ -371,8 +468,8 @@ def container_logs(
371
468
  app_logger.info(f'Running {command_name} from {get_current_directory()}')
372
469
  check_command_permission(command_name)
373
470
 
374
- if not container_uid:
375
- typer.echo(__('Container unique ID is required'))
471
+ if sum(v is not None for v in [container_public_id, container_slug]) != 1:
472
+ typer.echo("Please provide a single identifier for container - ID or name.")
376
473
  raise typer.Exit(1)
377
474
 
378
475
  service_factory = validate_config_and_get_service_factory()
@@ -380,10 +477,11 @@ def container_logs(
380
477
 
381
478
  if logs_number is None:
382
479
  logging_service.stream_container_logs_with_controls(
383
- container_uid=container_uid
480
+ container_public_id=container_public_id,
481
+ container_slug=container_slug,
384
482
  )
385
483
  else:
386
- logging_service.print_last_container_logs(container_uid=container_uid, logs_number=logs_number)
484
+ logging_service.print_last_container_logs(container_public_id=container_public_id, container_slug=container_slug, logs_number=logs_number)
387
485
 
388
486
  app_logger.info(f'Container logs - end')
389
487
  raise typer.Exit(0)
@@ -64,8 +64,19 @@ def rented_list(
64
64
 
65
65
  @rented.command(name="connect", no_args_is_help=True, help=__("Connect to rented server instance"), **get_command_metadata(CliCommand.INSTANCE_RENTED_CONNECT))
66
66
  def instance_connect(
67
- instance_uid: Optional[str] = typer.Argument(
68
- help=__("Rented server instance unique ID"),
67
+ public_id: Optional[str] = typer.Option(
68
+ None,
69
+ '--id',
70
+ '-rid',
71
+ help="Rented instance ID",
72
+ is_eager=False,
73
+ ),
74
+ slug: Optional[str] = typer.Option(
75
+ None,
76
+ '--name',
77
+ '-rn',
78
+ help="Rented instance name",
79
+ is_eager=False,
69
80
  ),
70
81
  private_ssh_key_path: str = typer.Option(
71
82
  None,
@@ -79,8 +90,8 @@ def instance_connect(
79
90
  app_logger.info(f'Running {command_name} from {get_current_directory()}')
80
91
  check_command_permission(command_name)
81
92
 
82
- if not instance_uid:
83
- typer.echo(__('Rented server instance unique ID is required'))
93
+ if sum(v is not None for v in [public_id, slug]) != 1:
94
+ typer.echo("Please provide a single identifier for rented instance - ID or name.")
84
95
  raise typer.Exit(1)
85
96
 
86
97
  if private_ssh_key_path and not Path(private_ssh_key_path).is_file():
@@ -91,7 +102,8 @@ def instance_connect(
91
102
  instance_service: InstanceService = service_factory.get_instance_service()
92
103
 
93
104
  instance_service.connect_to_rented_instance(
94
- instance_rented_slug=instance_uid,
105
+ instance_rented_public_id=public_id,
106
+ instance_rented_slug=slug,
95
107
  input_ssh_key_path=private_ssh_key_path
96
108
  )
97
109
 
@@ -142,7 +154,20 @@ def self_hosted_list(
142
154
 
143
155
  @self_hosted.command(name="connect", no_args_is_help=True, help=__("Connect to self-hosted instance"), **get_command_metadata(CliCommand.INSTANCE_SELF_HOSTED_CONNECT))
144
156
  def self_hosted_connect(
145
- instance_slug: Optional[str] = typer.Argument(help=__("Self-hosted instance unique ID"),),
157
+ public_id: Optional[str] = typer.Option(
158
+ None,
159
+ '--id',
160
+ '-sid',
161
+ help="Self-hosted instance ID",
162
+ is_eager=False,
163
+ ),
164
+ slug: Optional[str] = typer.Option(
165
+ None,
166
+ '--name',
167
+ '-sn',
168
+ help="Self-hosted instance name",
169
+ is_eager=False,
170
+ ),
146
171
  username: Optional[str] = typer.Option(
147
172
  None,
148
173
  '--username',
@@ -162,8 +187,8 @@ def self_hosted_connect(
162
187
  app_logger.info(f'Running {command_name} from {get_current_directory()}')
163
188
  check_command_permission(command_name)
164
189
 
165
- if not instance_slug:
166
- typer.echo(__('Self-hosted instance unique ID is required'))
190
+ if sum(v is not None for v in [public_id, slug]) != 1:
191
+ typer.echo("Please provide a single identifier for self-hosted instance - ID or name.")
167
192
  raise typer.Exit(1)
168
193
 
169
194
  if private_ssh_key_path and not Path(private_ssh_key_path).is_file():
@@ -174,7 +199,8 @@ def self_hosted_connect(
174
199
  instance_service: InstanceService = service_factory.get_instance_service()
175
200
 
176
201
  instance_service.connect_to_selfhosted_instance(
177
- selfhosted_instance_slug=instance_slug,
202
+ selfhosted_instance_public_id=public_id,
203
+ selfhosted_instance_slug=slug,
178
204
  username=username,
179
205
  input_ssh_key_path=private_ssh_key_path
180
206
  )