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.
Files changed (194) hide show
  1. thestage/__init__.py +1 -1
  2. thestage/cli_command_helper.py +2 -2
  3. thestage/config/__init__.py +1 -1
  4. thestage/{services → config/business}/app_config_service.py +3 -4
  5. thestage/{services/config_provider → config/business}/config_provider.py +6 -5
  6. thestage/config/{config_storage.py → business/config_storage.py} +1 -1
  7. thestage/{services → config/business}/validation_service.py +9 -10
  8. thestage/{controllers/config_controller.py → config/communication/config_command.py} +7 -7
  9. thestage/{services/connect → connect/business}/connect_service.py +25 -22
  10. thestage/{services → connect/business}/remote_server_service.py +4 -5
  11. thestage/connect/communication/connect_api_client.py +84 -0
  12. thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_key_to_user_response.py +0 -1
  13. thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_public_key_to_instance_response.py +1 -4
  14. thestage/{services/clients/thestage_api/dtos/base_controller → connect/dto}/connect_resolve_response.py +1 -1
  15. thestage/controllers/base_controller.py +2 -2
  16. thestage/debug_main.dist.py +16 -14
  17. thestage/{services/container → docker_container/business}/container_service.py +120 -40
  18. thestage/{services/container → docker_container/business}/mapper/container_mapper.py +3 -3
  19. thestage/docker_container/communication/__init__.py +0 -0
  20. thestage/{controllers/container_controller.py → docker_container/communication/docker_command.py} +27 -86
  21. thestage/docker_container/communication/docker_container_api_client.py +99 -0
  22. thestage/docker_container/dto/__init__.py +0 -0
  23. thestage/docker_container/dto/container_action_request.py +11 -0
  24. thestage/{services/clients/thestage_api/dtos → docker_container/dto}/container_response.py +4 -4
  25. thestage/{services/clients/thestage_api/dtos/docker_container_controller → docker_container/dto}/docker_container_list_response.py +3 -5
  26. thestage/docker_container/dto/enum/__init__.py +0 -0
  27. thestage/git/__init__.py +0 -0
  28. thestage/git/business/__init__.py +0 -0
  29. thestage/git/communication/__init__.py +0 -0
  30. thestage/{services/clients/git → git/communication}/git_client.py +5 -5
  31. thestage/global_dto/__init__.py +0 -0
  32. thestage/global_dto/enums/__init__.py +0 -0
  33. thestage/helpers/error_handler.py +5 -5
  34. thestage/helpers/logger/app_logger.py +1 -3
  35. thestage/i18n/en_GB/messages.po +14 -14
  36. thestage/inference_model/__init__.py +0 -0
  37. thestage/inference_model/business/__init__.py +0 -0
  38. thestage/inference_model/business/inference_model_service.py +281 -0
  39. thestage/inference_model/business/mapper/__init__.py +0 -0
  40. thestage/{services/project/mapper/project_inference_simulator_model_mapper.py → inference_model/business/mapper/inference_model_mapper.py} +5 -5
  41. thestage/inference_model/communication/__init__.py +0 -0
  42. thestage/inference_model/communication/inference_model_api_client.py +139 -0
  43. thestage/inference_model/communication/inference_model_command.py +246 -0
  44. thestage/inference_model/dto/__init__.py +0 -0
  45. thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_instance_request.py +0 -2
  46. thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_instance_response.py +2 -1
  47. thestage/inference_model/dto/enum/__init__.py +0 -0
  48. thestage/{services/project/dto/inference_simulator_model_dto.py → inference_model/dto/inference_model.py} +1 -1
  49. thestage/{entities/project_inference_simulator_model.py → inference_model/dto/inference_model_entity.py} +2 -2
  50. thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/inference_simulator_model_list_for_project_response.py +2 -3
  51. 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
  52. 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
  53. thestage/inference_simulator/__init__.py +0 -0
  54. thestage/inference_simulator/business/__init__.py +0 -0
  55. thestage/inference_simulator/business/inference_simulator_service.py +338 -0
  56. thestage/inference_simulator/business/mapper/__init__.py +0 -0
  57. thestage/{services/project/mapper/project_inference_simulator_mapper.py → inference_simulator/business/mapper/inference_simulator_mapper.py} +5 -5
  58. thestage/inference_simulator/communication/__init__.py +0 -0
  59. thestage/inference_simulator/communication/inference_simulator_api_client.py +114 -0
  60. thestage/inference_simulator/communication/inference_simulator_command.py +347 -0
  61. thestage/inference_simulator/dto/__init__.py +0 -0
  62. thestage/inference_simulator/dto/enum/__init__.py +0 -0
  63. thestage/{services/clients/thestage_api/dtos/inference_controller → inference_simulator/dto}/get_inference_simulator_request.py +1 -1
  64. thestage/inference_simulator/dto/get_inference_simulator_response.py +12 -0
  65. thestage/{services/project/dto/inference_simulator_dto.py → inference_simulator/dto/inference_simulator.py} +1 -1
  66. thestage/{entities/project_inference_simulator.py → inference_simulator/dto/inference_simulator_entity.py} +1 -1
  67. thestage/{services/clients/thestage_api/dtos/inference_controller → inference_simulator/dto}/inference_simulator_list_response.py +2 -2
  68. thestage/{services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_request.py → inference_simulator/dto/start_inference_simulator_request.py} +1 -1
  69. thestage/inference_simulator/dto/start_inference_simulator_response.py +10 -0
  70. thestage/instance/__init__.py +0 -0
  71. thestage/instance/business/__init__.py +0 -0
  72. thestage/{services/instance → instance/business}/instance_service.py +26 -27
  73. thestage/instance/business/mapper/__init__.py +0 -0
  74. thestage/{services/instance/mapper/instance_mapper.py → instance/business/mapper/rented_instance_mapper.py} +3 -3
  75. thestage/{services/instance/mapper/selfhosted_mapper.py → instance/business/mapper/selfhosted_instance_mapper.py} +5 -7
  76. thestage/instance/communication/__init__.py +0 -0
  77. thestage/instance/communication/instance_api_client.py +150 -0
  78. thestage/{controllers/instance_controller.py → instance/communication/instance_command.py} +9 -9
  79. thestage/instance/dto/__init__.py +0 -0
  80. thestage/instance/dto/enum/__init__.py +0 -0
  81. thestage/{services/clients/thestage_api/dtos → instance/dto}/instance_detected_gpus.py +1 -2
  82. thestage/{services/clients/thestage_api/dtos → instance/dto}/instance_rented_response.py +2 -2
  83. thestage/{services/clients/thestage_api/dtos → instance/dto}/selfhosted_instance_response.py +2 -3
  84. thestage/logging/__init__.py +0 -0
  85. thestage/logging/business/__init__.py +0 -0
  86. thestage/{services/logging → logging/business}/logging_service.py +45 -36
  87. thestage/logging/communication/__init__.py +0 -0
  88. thestage/logging/communication/logging_api_client.py +63 -0
  89. thestage/logging/dto/__init__.py +0 -0
  90. thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/log_polling_response.py +2 -2
  91. thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/user_logs_query_response.py +2 -2
  92. thestage/main.py +48 -9
  93. thestage/project/__init__.py +0 -0
  94. thestage/project/business/__init__.py +0 -0
  95. thestage/project/business/project_service.py +480 -0
  96. thestage/project/communication/__init__.py +0 -0
  97. thestage/project/communication/project_api_client.py +46 -0
  98. thestage/project/communication/project_command.py +284 -0
  99. thestage/project/dto/__init__.py +0 -0
  100. thestage/{services/project → project}/dto/project_config.py +1 -2
  101. thestage/services/clients/thestage_api/core/api_client_core.py +1 -1
  102. thestage/services/clients/thestage_api/dtos/entity_filter_request.py +1 -1
  103. thestage/services/clients/thestage_api/dtos/sftp_path_helper.py +1 -1
  104. thestage/services/filesystem_service.py +2 -2
  105. thestage/services/service_factory.py +130 -43
  106. thestage/task/__init__.py +0 -0
  107. thestage/task/business/__init__.py +0 -0
  108. thestage/task/business/mapper/__init__.py +0 -0
  109. thestage/{services/project/mapper/project_task_mapper.py → task/business/mapper/task_mapper.py} +5 -5
  110. thestage/task/business/task_service.py +304 -0
  111. thestage/task/communication/__init__.py +0 -0
  112. thestage/task/communication/task_api_client.py +122 -0
  113. thestage/task/communication/task_command.py +212 -0
  114. thestage/task/dto/__init__.py +0 -0
  115. thestage/task/dto/enum/__init__.py +0 -0
  116. thestage/{services/clients/thestage_api/dtos/task_controller/task_list_for_project_response.py → task/dto/list_for_project_response.py} +2 -2
  117. thestage/{services/clients/thestage_api/dtos/project_controller/project_run_task_request.py → task/dto/run_task_request.py} +1 -1
  118. thestage/task/dto/run_task_response.py +13 -0
  119. thestage/{services/task/dto/task_dto.py → task/dto/task.py} +1 -4
  120. thestage/{entities/project_task.py → task/dto/task_entity.py} +1 -1
  121. thestage/{services/clients/thestage_api/dtos/task_controller/task_view_response.py → task/dto/view_response.py} +2 -2
  122. {thestage-0.6.6.dist-info → thestage-0.6.8.dist-info}/METADATA +2 -1
  123. thestage-0.6.8.dist-info/RECORD +219 -0
  124. {thestage-0.6.6.dist-info → thestage-0.6.8.dist-info}/WHEEL +1 -1
  125. thestage/controllers/project_controller.py +0 -1058
  126. thestage/services/clients/thestage_api/api_client.py +0 -753
  127. thestage/services/clients/thestage_api/dtos/container_param_request.py +0 -11
  128. thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_response.py +0 -13
  129. thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_response.py +0 -10
  130. thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_response.py +0 -10
  131. thestage/services/clients/thestage_api/dtos/user_controller/user_profile.py +0 -12
  132. thestage/services/project/project_service.py +0 -1283
  133. thestage-0.6.6.dist-info/RECORD +0 -167
  134. /thestage/{entities → color_scheme}/__init__.py +0 -0
  135. /thestage/{entities/enums → config/business}/__init__.py +0 -0
  136. /thestage/{services/clients/git → config/communication}/__init__.py +0 -0
  137. /thestage/{services/clients/thestage_api/dtos/enums → config/dto}/__init__.py +0 -0
  138. /thestage/{services/core_files → config/dto}/config_entity.py +0 -0
  139. /thestage/{services/connect → config}/dto/remote_server_config.py +0 -0
  140. /thestage/{services/config_provider → connect}/__init__.py +0 -0
  141. /thestage/{services/container → connect/business}/__init__.py +0 -0
  142. /thestage/{services/container/mapper → connect/communication}/__init__.py +0 -0
  143. /thestage/{services/instance → connect/dto}/__init__.py +0 -0
  144. /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_key_to_user_request.py +0 -0
  145. /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/add_ssh_public_key_to_instance_request.py +0 -0
  146. /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/is_user_has_public_ssh_key_request.py +0 -0
  147. /thestage/{services/clients/thestage_api/dtos/ssh_key_controller → connect/dto}/is_user_has_public_ssh_key_response.py +0 -0
  148. /thestage/{services/instance/mapper → docker_container}/__init__.py +0 -0
  149. /thestage/{services/project → docker_container/business}/__init__.py +0 -0
  150. /thestage/{services/project → docker_container/business}/mapper/__init__.py +0 -0
  151. /thestage/{entities/container.py → docker_container/dto/container_entity.py} +0 -0
  152. /thestage/{services/clients/thestage_api/dtos/docker_container_controller → docker_container/dto}/docker_container_list_request.py +0 -0
  153. /thestage/{services/clients/thestage_api/dtos → docker_container/dto}/docker_container_mapping.py +0 -0
  154. /thestage/{services/clients/thestage_api/dtos/enums → docker_container/dto/enum}/container_pending_action.py +0 -0
  155. /thestage/{services/clients/thestage_api/dtos/enums → docker_container/dto/enum}/container_status.py +0 -0
  156. /thestage/{services/logging/exception → exceptions}/log_polling_exception.py +0 -0
  157. /thestage/git/{ProgressPrinter.py → business/ProgressPrinter.py} +0 -0
  158. /thestage/{entities → global_dto}/enums/order_direction_type.py +0 -0
  159. /thestage/{entities → global_dto}/enums/shell_type.py +0 -0
  160. /thestage/{entities → global_dto}/enums/tail_output_type.py +0 -0
  161. /thestage/{entities → global_dto}/enums/yes_no_response.py +0 -0
  162. /thestage/{entities → global_dto}/file_item.py +0 -0
  163. /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_sagemaker_request.py +0 -0
  164. /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/deploy_inference_model_to_sagemaker_response.py +0 -0
  165. /thestage/{services/clients/thestage_api/dtos/enums → inference_model/dto/enum}/inference_model_status.py +0 -0
  166. /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_model/dto}/inference_simulator_model_list_for_project_request.py +0 -0
  167. /thestage/{services/clients/thestage_api/dtos → inference_model/dto}/inference_simulator_model_response.py +0 -0
  168. /thestage/{services/clients/thestage_api/dtos/enums → inference_simulator/dto/enum}/inference_simulator_status.py +0 -0
  169. /thestage/{services/clients/thestage_api/dtos/inference_controller → inference_simulator/dto}/inference_simulator_list_request.py +0 -0
  170. /thestage/{services/clients/thestage_api/dtos → inference_simulator/dto}/inference_simulator_response.py +0 -0
  171. /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/cpu_type.py +0 -0
  172. /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/gpu_name.py +0 -0
  173. /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/instance_rented_status.py +0 -0
  174. /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/provider_name.py +0 -0
  175. /thestage/{services/clients/thestage_api/dtos/enums → instance/dto/enum}/selfhosted_status.py +0 -0
  176. /thestage/{entities → instance/dto}/rented_instance.py +0 -0
  177. /thestage/{entities → instance/dto}/self_hosted_instance.py +0 -0
  178. /thestage/{services/logging → logging}/byte_print_style.py +0 -0
  179. /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/docker_container_log_stream_request.py +0 -0
  180. /thestage/{services/logging → logging}/dto/log_message.py +0 -0
  181. /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/log_polling_request.py +0 -0
  182. /thestage/{services/logging → logging}/dto/log_type.py +0 -0
  183. /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/task_log_stream_request.py +0 -0
  184. /thestage/{services/clients/thestage_api/dtos/logging_controller → logging/dto}/user_logs_query_request.py +0 -0
  185. /thestage/{services/logging → logging}/logging_constants.py +0 -0
  186. /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
  187. /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
  188. /thestage/{services/clients/thestage_api/dtos → project/dto}/project_response.py +0 -0
  189. /thestage/{services/clients/thestage_api/dtos/enums → task/dto/enum}/task_execution_status.py +0 -0
  190. /thestage/{services/clients/thestage_api/dtos/enums → task/dto/enum}/task_status.py +0 -0
  191. /thestage/{services/clients/thestage_api/dtos/task_controller/task_list_for_project_request.py → task/dto/list_for_project_request.py} +0 -0
  192. /thestage/{services/clients/thestage_api/dtos/task_controller/task_status_localized_map_response.py → task/dto/status_localized_map_response.py} +0 -0
  193. {thestage-0.6.6.dist-info → thestage-0.6.8.dist-info}/entry_points.txt +0 -0
  194. {thestage-0.6.6.dist-info → thestage-0.6.8.dist-info}/licenses/LICENSE.txt +0 -0
@@ -0,0 +1,46 @@
1
+ from typing import Optional
2
+
3
+ from thestage.config.business.config_provider import ConfigProvider
4
+ from thestage.services.clients.thestage_api.core.api_client_core import TheStageApiClientCore
5
+
6
+ from thestage.project.dto.project_response import ProjectDto, ProjectViewResponse
7
+ from thestage.project.dto.get_deploy_ssh_key_request import ProjectGetDeploySshKeyRequest
8
+ from thestage.project.dto.get_deploy_ssh_key_response import ProjectGetDeploySshKeyResponse
9
+
10
+
11
+ class ProjectApiClient(TheStageApiClientCore):
12
+ def __init__(self, config_provider: ConfigProvider):
13
+ super().__init__(url=config_provider.get_config().main.thestage_api_url)
14
+ self.__config_provider = config_provider
15
+
16
+ def get_project(self, slug: Optional[str], public_id: Optional[str]) -> Optional[ProjectDto]:
17
+ data = {
18
+ "projectSlug": slug,
19
+ "projectPublicId": public_id,
20
+ }
21
+
22
+ response = self._request(
23
+ method='POST',
24
+ url='/user-api/v2/project/view',
25
+ data=data,
26
+ token=self.__config_provider.get_config().main.thestage_auth_token,
27
+ )
28
+
29
+ result = ProjectViewResponse.model_validate(response) if response else None
30
+ project = ProjectDto.model_validate(result.project) if result else None
31
+ return project if result and result.is_success else None
32
+
33
+ def get_project_deploy_ssh_key(self, public_id: str) -> str:
34
+ request = ProjectGetDeploySshKeyRequest(
35
+ projectPublicId=public_id,
36
+ )
37
+
38
+ response = self._request(
39
+ method='POST',
40
+ url='/user-api/v1/project/get-deploy-ssh-key',
41
+ data=request.model_dump(),
42
+ token=self.__config_provider.get_config().main.thestage_auth_token,
43
+ )
44
+
45
+ result = ProjectGetDeploySshKeyResponse.model_validate(response) if response else None
46
+ return result.privateKey if result and result.is_success else None
@@ -0,0 +1,284 @@
1
+ from typing import Optional
2
+
3
+ import typer
4
+
5
+ from thestage.task.communication import task_command
6
+ from thestage.cli_command import CliCommand
7
+ from thestage.cli_command_helper import get_command_metadata, check_command_permission, get_command_group_help_panel
8
+ from thestage.controllers.utils_controller import validate_config_and_get_service_factory, get_current_directory
9
+ from thestage.helpers.logger.app_logger import app_logger
10
+ from thestage.i18n.translation import __
11
+
12
+ app = typer.Typer(no_args_is_help=True, help=__("Manage projects"))
13
+ config_app = typer.Typer(no_args_is_help=True, help=__("Manage project config"))
14
+ app.add_typer(config_app, name="config", rich_help_panel=get_command_group_help_panel())
15
+ app.add_typer(task_command.runner_app, name="")
16
+
17
+
18
+ @app.command(name='clone', no_args_is_help=True, help=__("Clone project repository to empty directory"), **get_command_metadata(CliCommand.PROJECT_CLONE))
19
+ def clone(
20
+ project_public_id: Optional[str] = typer.Option(
21
+ None,
22
+ "--project-id",
23
+ "-pid",
24
+ help=__("Project ID. ID or name is required"),
25
+ is_eager=False,
26
+ ),
27
+ project_slug: Optional[str] = typer.Option(
28
+ None,
29
+ "--project-name",
30
+ "-pn",
31
+ help=__("Project name. ID or name is required."),
32
+ is_eager=False,
33
+ ),
34
+ working_directory: Optional[str] = typer.Option(
35
+ None,
36
+ "--working-directory",
37
+ "-wd",
38
+ help=__("Full path to the working directory: current directory used by default"),
39
+ is_eager=False,
40
+ ),
41
+ ):
42
+ command_name = CliCommand.PROJECT_CLONE
43
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
44
+ check_command_permission(command_name)
45
+
46
+ if sum(v is not None for v in [project_public_id, project_slug]) != 1:
47
+ typer.echo("Provide a single identifier for the project - name or ID.")
48
+ raise typer.Exit(1)
49
+
50
+ if not working_directory:
51
+ project_dir_name = project_public_id if project_slug is None else project_slug
52
+ working_directory = get_current_directory().joinpath(project_dir_name)
53
+
54
+ service_factory = validate_config_and_get_service_factory(working_directory=working_directory)
55
+ project_service = service_factory.get_project_service()
56
+
57
+ project_service.clone_project(
58
+ project_slug=project_slug,
59
+ project_public_id=project_public_id,
60
+ )
61
+
62
+ raise typer.Exit(0)
63
+
64
+
65
+ @app.command(name='init', no_args_is_help=True, help=__("Initialize project repository with existing files"), **get_command_metadata(CliCommand.PROJECT_INIT))
66
+ def init(
67
+ project_public_id: Optional[str] = typer.Option(
68
+ None,
69
+ "--project-id",
70
+ "-pid",
71
+ help=__("Project ID. ID or name is required"),
72
+ is_eager=False,
73
+ ),
74
+ project_slug: Optional[str] = typer.Option(
75
+ None,
76
+ "--project-name",
77
+ "-pn",
78
+ help=__("Project name. ID or name is required."),
79
+ is_eager=False,
80
+ ),
81
+ working_directory: Optional[str] = typer.Option(
82
+ None,
83
+ "--working-directory",
84
+ "-wd",
85
+ help=__("Full path to working directory"),
86
+ is_eager=False,
87
+ ),
88
+ ):
89
+ command_name = CliCommand.PROJECT_INIT
90
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
91
+ check_command_permission(command_name)
92
+
93
+ if sum(v is not None for v in [project_public_id, project_slug]) != 1:
94
+ typer.echo("Provide a single identifier for the project - name or ID.")
95
+ raise typer.Exit(1)
96
+
97
+ service_factory = validate_config_and_get_service_factory(working_directory=working_directory)
98
+ project_service = service_factory.get_project_service()
99
+ project_config = service_factory.get_config_provider().read_project_config()
100
+
101
+ if project_config:
102
+ typer.echo(__("Directory is initialized and already contains working project"))
103
+ raise typer.Exit(1)
104
+
105
+ project_service.init_project(
106
+ project_slug=project_slug,
107
+ project_public_id=project_public_id,
108
+ )
109
+
110
+ raise typer.Exit(0)
111
+
112
+
113
+
114
+ @app.command(name='checkout', no_args_is_help=True, help=__("Checkout project repository to a specific reference"), **get_command_metadata(CliCommand.PROJECT_CHECKOUT))
115
+ def checkout_project(
116
+ task_public_id: Optional[str] = typer.Option(
117
+ None,
118
+ "--task-id",
119
+ "-tid",
120
+ help="Task ID to checkout",
121
+ is_eager=False,
122
+ ),
123
+ branch_name: Optional[str] = typer.Option(
124
+ None,
125
+ "--branch",
126
+ "-b",
127
+ help="Branch name to checkout. Use '/' value to checkout to the main branch.",
128
+ is_eager=False,
129
+ ),
130
+ working_directory: Optional[str] = typer.Option(
131
+ None,
132
+ "--working-directory",
133
+ "-wd",
134
+ help=__("Full path to working directory"),
135
+ is_eager=False,
136
+ ),
137
+ ):
138
+ command_name = CliCommand.PROJECT_CHECKOUT
139
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
140
+ check_command_permission(command_name)
141
+
142
+ if sum(v is not None for v in [branch_name, task_public_id]) != 1:
143
+ typer.echo("Provide a single identifier for checkout - task ID or branch name.")
144
+ raise typer.Exit(1)
145
+
146
+ service_factory = validate_config_and_get_service_factory(working_directory=working_directory)
147
+ project_service = service_factory.get_project_service()
148
+
149
+ final_branch_name = branch_name
150
+ if branch_name == "/":
151
+ final_branch_name = None
152
+
153
+ project_service.checkout_project(
154
+ task_public_id=task_public_id,
155
+ branch_name=final_branch_name,
156
+ )
157
+
158
+ raise typer.Exit(0)
159
+
160
+
161
+ @app.command(name='pull', help=__("Pulls the changes from the remote project repository. Equivalent to 'git pull'."), **get_command_metadata(CliCommand.PROJECT_PULL))
162
+ def pull_project(
163
+ working_directory: Optional[str] = typer.Option(
164
+ None,
165
+ "--working-directory",
166
+ "-wd",
167
+ help=__("Full path to working directory"),
168
+ is_eager=False,
169
+ ),
170
+ ):
171
+ command_name = CliCommand.PROJECT_PULL
172
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
173
+ check_command_permission(command_name)
174
+
175
+ service_factory = validate_config_and_get_service_factory(working_directory=working_directory)
176
+ project_service = service_factory.get_project_service()
177
+
178
+ project_service.pull_project()
179
+
180
+ raise typer.Exit(0)
181
+
182
+
183
+ @app.command(name='reset', help=__("Resets the current project branch to remote counterpart. All working tree changes will be lost. Equivalent to 'git fetch && git reset --hard origin/{ref}'."), **get_command_metadata(CliCommand.PROJECT_RESET))
184
+ def reset_project(
185
+ working_directory: Optional[str] = typer.Option(
186
+ None,
187
+ "--working-directory",
188
+ "-wd",
189
+ help=__("Full path to working directory"),
190
+ is_eager=False,
191
+ ),
192
+ ):
193
+ command_name = CliCommand.PROJECT_RESET
194
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
195
+ check_command_permission(command_name)
196
+
197
+ service_factory = validate_config_and_get_service_factory(working_directory=working_directory)
198
+ project_service = service_factory.get_project_service()
199
+
200
+ project_service.reset_project()
201
+
202
+ raise typer.Exit(0)
203
+
204
+
205
+ @config_app.command(name='set-default-container', no_args_is_help=True, help=__("Set default docker container for a project installation"), **get_command_metadata(CliCommand.PROJECT_CONFIG_SET_DEFAULT_CONTAINER))
206
+ def set_default_container(
207
+ docker_container_public_id: Optional[str] = typer.Option(
208
+ None,
209
+ '--container-id',
210
+ '-cid',
211
+ help=__("Docker container ID"),
212
+ is_eager=False,
213
+ ),
214
+ docker_container_slug: Optional[str] = typer.Option(
215
+ None,
216
+ '--container-name',
217
+ '-cn',
218
+ help=__("Docker container name"),
219
+ is_eager=False,
220
+ ),
221
+ unset_default_container: Optional[bool] = typer.Option(
222
+ False,
223
+ "--unset",
224
+ "-u",
225
+ help=__("Unsets the default docker container"),
226
+ is_eager=False,
227
+ ),
228
+ working_directory: Optional[str] = typer.Option(
229
+ None,
230
+ "--working-directory",
231
+ "-wd",
232
+ help=__("Full path to working directory"),
233
+ is_eager=False,
234
+ ),
235
+ ):
236
+ command_name = CliCommand.PROJECT_CONFIG_SET_DEFAULT_CONTAINER
237
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
238
+ check_command_permission(command_name)
239
+
240
+ container_args_count = sum(v is not None for v in [docker_container_public_id, docker_container_slug])
241
+ if container_args_count > 1:
242
+ typer.echo("Provide a single identifier for the container - name or ID.")
243
+ raise typer.Exit(1)
244
+
245
+ service_factory = validate_config_and_get_service_factory(working_directory=working_directory)
246
+
247
+ if unset_default_container and container_args_count > 0:
248
+ typer.echo("Cannot provide container identifier and '--unset' flag simultaneously")
249
+ raise typer.Exit(1)
250
+
251
+ if not unset_default_container and container_args_count != 1:
252
+ typer.echo("Provide container identifier or use '--unset' flag")
253
+ raise typer.Exit(1)
254
+
255
+ project_service = service_factory.get_project_service()
256
+
257
+ project_service.set_default_container(
258
+ container_public_id=docker_container_public_id,
259
+ container_slug=docker_container_slug,
260
+ )
261
+
262
+ raise typer.Exit(0)
263
+
264
+
265
+ @config_app.command(name='get', no_args_is_help=False, help=__("View config for a local project installation"), **get_command_metadata(CliCommand.PROJECT_CONFIG_GET))
266
+ def get_project_config(
267
+ working_directory: Optional[str] = typer.Option(
268
+ None,
269
+ "--working-directory",
270
+ "-wd",
271
+ help=__("Full path to working directory"),
272
+ is_eager=False,
273
+ ),
274
+ ):
275
+ command_name = CliCommand.PROJECT_CONFIG_GET
276
+ app_logger.info(f'Running {command_name} from {get_current_directory()}')
277
+ check_command_permission(command_name)
278
+
279
+ service_factory = validate_config_and_get_service_factory(working_directory=working_directory)
280
+ project_service = service_factory.get_project_service()
281
+
282
+ project_service.print_project_config()
283
+
284
+ raise typer.Exit(0)
File without changes
@@ -10,6 +10,5 @@ class ProjectConfig(BaseModel):
10
10
  public_id: str = Field(None, alias='public_id')
11
11
  git_repository_url: str = Field(None, alias='git_repository_url')
12
12
  deploy_key_path: str = Field(None, alias='deploy_key_path')
13
- default_container_uid: Optional[str] = Field(None, alias='default_container_uid') # TODO delete
14
- default_container_public_id: Optional[str] = Field(None, alias='default_container_public_id') # TODO use
13
+ default_container_public_id: Optional[str] = Field(None, alias='default_container_public_id')
15
14
  prompt_for_default_container: bool = Field(True, alias='prompt_for_default_container')
@@ -3,7 +3,7 @@ from typing import Optional
3
3
 
4
4
  import requests
5
5
 
6
- from thestage.config import THESTAGE_API_URL
6
+ from thestage.config.env_base import THESTAGE_API_URL
7
7
  from thestage.exceptions.auth_exception import AuthException
8
8
  from thestage import __version__
9
9
  from thestage.services.clients.thestage_api.core.http_client_exception import HttpClientException
@@ -2,7 +2,7 @@ from typing import Optional
2
2
 
3
3
  from pydantic import ConfigDict, BaseModel, Field
4
4
 
5
- from thestage.entities.enums.order_direction_type import OrderDirectionType
5
+ from thestage.global_dto.enums.order_direction_type import OrderDirectionType
6
6
 
7
7
 
8
8
  class EntityFilterRequest(BaseModel):
@@ -2,7 +2,7 @@ from typing import Optional, List
2
2
 
3
3
  from pydantic import Field
4
4
 
5
- from thestage.entities.file_item import FileItemEntity
5
+ from thestage.global_dto.file_item import FileItemEntity
6
6
 
7
7
 
8
8
  class SftpFileItemEntity(FileItemEntity):
@@ -5,7 +5,7 @@ from json import JSONDecodeError
5
5
  from pathlib import Path
6
6
  from typing import Optional, List, Dict, Any
7
7
 
8
- from thestage.entities.file_item import FileItemEntity
8
+ from thestage.global_dto.file_item import FileItemEntity
9
9
  from thestage.exceptions.file_system_exception import FileSystemException
10
10
 
11
11
 
@@ -85,7 +85,7 @@ class FileSystemService:
85
85
  file.write(new_line)
86
86
  file.write('\n')
87
87
 
88
- # TODO remove this fucking useless shit
88
+ # TODO remove this
89
89
  def check_if_path_exist(self, file: str) -> bool:
90
90
  path = self.get_path(file, auto_create=False)
91
91
  if path.exists():
@@ -1,50 +1,71 @@
1
1
  from typing import Optional
2
2
 
3
- from thestage.services.config_provider.config_provider import ConfigProvider
4
- from thestage.services.connect.connect_service import ConnectService
3
+ from thestage.config.business.app_config_service import AppConfigService
4
+ from thestage.config.business.config_provider import ConfigProvider
5
+ from thestage.config.business.validation_service import ValidationService
6
+ from thestage.connect.business.connect_service import ConnectService
7
+ from thestage.connect.business.remote_server_service import RemoteServerService
8
+ from thestage.connect.communication.connect_api_client import ConnectApiClient
9
+ from thestage.docker_container.business.container_service import ContainerService
10
+ from thestage.docker_container.communication.docker_container_api_client import DockerContainerApiClient
11
+ from thestage.git.communication.git_client import GitLocalClient
12
+ from thestage.inference_model.business.inference_model_service import InferenceModelService
13
+ from thestage.inference_model.communication.inference_model_api_client import InferenceModelApiClient
14
+ from thestage.inference_simulator.business.inference_simulator_service import InferenceSimulatorService
15
+ from thestage.inference_simulator.communication.inference_simulator_api_client import InferenceSimulatorApiClient
16
+ from thestage.instance.business.instance_service import InstanceService
17
+ from thestage.instance.communication.instance_api_client import InstanceApiClient
18
+ from thestage.logging.business.logging_service import LoggingService
19
+ from thestage.logging.communication.logging_api_client import LoggingApiClient
20
+ from thestage.project.business.project_service import ProjectService
21
+ from thestage.project.communication.project_api_client import ProjectApiClient
22
+ from thestage.services.clients.thestage_api.core.api_client_core import TheStageApiClientCore
5
23
  from thestage.services.filesystem_service import FileSystemService
6
- from thestage.services.logging.logging_service import LoggingService
7
- from thestage.services.project.project_service import ProjectService
8
- from thestage.services.remote_server_service import RemoteServerService
9
- from thestage.services.container.container_service import ContainerService
10
- from thestage.services.instance.instance_service import InstanceService
11
- from thestage.services.app_config_service import AppConfigService
12
- from thestage.services.clients.git.git_client import GitLocalClient
13
- from thestage.services.clients.thestage_api.api_client import TheStageApiClient
14
- from thestage.services.validation_service import ValidationService
24
+ from thestage.task.business.task_service import TaskService
25
+ from thestage.task.communication.task_api_client import TaskApiClient
15
26
 
16
27
 
17
28
  class ServiceFactory:
18
- __thestage_api_client: Optional[TheStageApiClient] = None
19
29
  __git_local_client: Optional[GitLocalClient] = None
20
30
  __file_system_service: Optional[FileSystemService] = None
21
31
  __config_provider: Optional[ConfigProvider] = None
22
-
32
+ __task_api_client: Optional[TaskApiClient] = None
33
+ __project_api_client: Optional[ProjectApiClient] = None
34
+ __inference_model_api_client: Optional[InferenceModelApiClient] = None
35
+ __inference_simulator_api_client: Optional[InferenceSimulatorApiClient] = None
36
+ __instance_api_client: Optional[InstanceApiClient] = None
37
+ __docker_container_api_client: Optional[DockerContainerApiClient] = None
38
+ __connect_api_client: Optional[ConnectApiClient] = None
39
+ __logging_api_client: Optional[LoggingApiClient] = None
23
40
 
24
41
  def get_validation_service(self) -> ValidationService:
42
+ config_provider = self.get_config_provider()
43
+ core_client = TheStageApiClientCore(url=config_provider.get_config().main.thestage_api_url)
25
44
  return ValidationService(
26
- thestage_api_client=self.get_thestage_api_client(),
27
- config_provider=self.get_config_provider(),
28
- )
45
+ core_client=core_client,
46
+ config_provider=config_provider,
47
+ )
29
48
 
30
49
  def get_instance_service(self) -> InstanceService:
31
50
  return InstanceService(
32
- thestage_api_client=self.get_thestage_api_client(),
33
- remote_server_service=self.get_remote_server_service(),
34
- config_provider=self.get_config_provider(),
35
- )
51
+ instance_api_client=self.get_instance_api_client(),
52
+ remote_server_service=self.get_remote_server_service(),
53
+ config_provider=self.get_config_provider(),
54
+ )
36
55
 
37
56
  def get_container_service(self) -> ContainerService:
38
57
  return ContainerService(
39
- thestage_api_client=self.get_thestage_api_client(),
40
- remote_server_service=self.get_remote_server_service(),
41
- file_system_service=self.get_file_system_service(),
42
- config_provider=self.get_config_provider(),
43
- )
58
+ docker_container_api_client=self.get_docker_container_api_client(),
59
+ remote_server_service=self.get_remote_server_service(),
60
+ file_system_service=self.get_file_system_service(),
61
+ config_provider=self.get_config_provider(),
62
+ connect_api_client=self.get_connect_api_client(),
63
+ )
44
64
 
45
65
  def get_connect_service(self) -> ConnectService:
46
66
  return ConnectService(
47
- thestage_api_client=self.get_thestage_api_client(),
67
+ instance_api_client=self.get_instance_api_client(),
68
+ connect_api_client=self.get_connect_api_client(),
48
69
  instance_service=self.get_instance_service(),
49
70
  container_service=self.get_container_service(),
50
71
  logging_service=self.get_logging_service(),
@@ -52,23 +73,100 @@ class ServiceFactory:
52
73
 
53
74
  def get_project_service(self) -> ProjectService:
54
75
  return ProjectService(
55
- thestage_api_client=self.get_thestage_api_client(),
76
+ task_api_client=self.get_task_api_client(),
77
+ docker_container_api_client=self.get_docker_container_api_client(),
78
+ project_api_client=self.get_project_api_client(),
56
79
  remote_server_service=self.get_remote_server_service(),
57
80
  file_system_service=self.get_file_system_service(),
58
81
  git_local_client=self.get_git_local_client(),
59
82
  config_provider=self.get_config_provider(),
60
83
  )
61
84
 
85
+ def get_task_service(self) -> TaskService:
86
+ return TaskService(
87
+ docker_container_api_client=self.get_docker_container_api_client(),
88
+ project_service=self.get_project_service(),
89
+ task_api_client=self.get_task_api_client(),
90
+ config_provider=self.get_config_provider(),
91
+ git_local_client=self.get_git_local_client(),
92
+ file_system_service=self.get_file_system_service(),
93
+ )
94
+
95
+ def get_inference_simulator_service(self) -> InferenceSimulatorService:
96
+ return InferenceSimulatorService(
97
+ inference_simulator_api_client=self.get_inference_simulator_api_client(),
98
+ inference_model_api_client=self.get_inference_model_api_client(),
99
+ config_provider=self.get_config_provider(),
100
+ git_local_client=self.get_git_local_client(),
101
+ project_service=self.get_project_service(),
102
+ )
103
+
104
+ def get_inference_model_service(self) -> InferenceModelService:
105
+ return InferenceModelService(
106
+ inference_model_api_client=self.get_inference_model_api_client(),
107
+ config_provider=self.get_config_provider(),
108
+ project_service=self.get_project_service(),
109
+ )
110
+
62
111
  def get_remote_server_service(self) -> RemoteServerService:
63
112
  return RemoteServerService(
64
113
  file_system_service=self.get_file_system_service(),
65
114
  config_provider=self.get_config_provider(),
66
115
  )
67
116
 
68
- def get_thestage_api_client(self) -> TheStageApiClient:
69
- if not self.__thestage_api_client:
70
- self.__thestage_api_client = TheStageApiClient(config_provider=self.get_config_provider())
71
- return self.__thestage_api_client
117
+ def get_app_config_service(self) -> AppConfigService:
118
+ return AppConfigService(
119
+ config_provider=self.get_config_provider(),
120
+ validation_service=self.get_validation_service(),
121
+ )
122
+
123
+ def get_logging_service(self) -> LoggingService:
124
+ return LoggingService(
125
+ logging_api_client=self.get_logging_api_client(),
126
+ docker_container_api_client=self.get_docker_container_api_client(),
127
+ task_api_client=self.get_task_api_client(),
128
+ inference_simulator_api_client=self.get_inference_simulator_api_client(),
129
+ )
130
+
131
+ def get_task_api_client(self) -> TaskApiClient:
132
+ if not self.__task_api_client:
133
+ self.__task_api_client = TaskApiClient(config_provider=self.get_config_provider())
134
+ return self.__task_api_client
135
+
136
+ def get_project_api_client(self) -> ProjectApiClient:
137
+ if not self.__project_api_client:
138
+ self.__project_api_client = ProjectApiClient(config_provider=self.get_config_provider())
139
+ return self.__project_api_client
140
+
141
+ def get_inference_model_api_client(self) -> InferenceModelApiClient:
142
+ if not self.__inference_model_api_client:
143
+ self.__inference_model_api_client = InferenceModelApiClient(config_provider=self.get_config_provider())
144
+ return self.__inference_model_api_client
145
+
146
+ def get_inference_simulator_api_client(self) -> InferenceSimulatorApiClient:
147
+ if not self.__inference_simulator_api_client:
148
+ self.__inference_simulator_api_client = InferenceSimulatorApiClient(config_provider=self.get_config_provider())
149
+ return self.__inference_simulator_api_client
150
+
151
+ def get_instance_api_client(self) -> InstanceApiClient:
152
+ if not self.__instance_api_client:
153
+ self.__instance_api_client = InstanceApiClient(config_provider=self.get_config_provider())
154
+ return self.__instance_api_client
155
+
156
+ def get_docker_container_api_client(self) -> DockerContainerApiClient:
157
+ if not self.__docker_container_api_client:
158
+ self.__docker_container_api_client = DockerContainerApiClient(config_provider=self.get_config_provider())
159
+ return self.__docker_container_api_client
160
+
161
+ def get_connect_api_client(self) -> ConnectApiClient:
162
+ if not self.__connect_api_client:
163
+ self.__connect_api_client = ConnectApiClient(config_provider=self.get_config_provider())
164
+ return self.__connect_api_client
165
+
166
+ def get_logging_api_client(self) -> LoggingApiClient:
167
+ if not self.__logging_api_client:
168
+ self.__logging_api_client = LoggingApiClient(config_provider=self.get_config_provider())
169
+ return self.__logging_api_client
72
170
 
73
171
  def get_git_local_client(self):
74
172
  if not self.__git_local_client:
@@ -80,18 +178,7 @@ class ServiceFactory:
80
178
  self.__file_system_service = FileSystemService()
81
179
  return self.__file_system_service
82
180
 
83
- def get_app_config_service(self) -> AppConfigService:
84
- return AppConfigService(
85
- config_provider=self.get_config_provider(),
86
- validation_service=self.get_validation_service(),
87
- )
88
-
89
- def get_logging_service(self) -> LoggingService:
90
- return LoggingService(
91
- thestage_api_client=self.get_thestage_api_client(),
92
- )
93
-
94
181
  def get_config_provider(self) -> ConfigProvider:
95
182
  if not self.__config_provider:
96
183
  self.__config_provider = ConfigProvider(self.get_file_system_service())
97
- return self.__config_provider
184
+ return self.__config_provider
File without changes
File without changes
File without changes
@@ -1,17 +1,17 @@
1
1
  from typing import Optional
2
2
 
3
- from thestage.entities.project_task import ProjectTaskEntity
3
+ from thestage.task.dto.task_entity import TaskEntity
4
4
  from thestage.services.abstract_mapper import AbstractMapper
5
- from thestage.services.task.dto.task_dto import TaskDto
5
+ from thestage.task.dto.task import Task
6
6
 
7
7
 
8
- class ProjectTaskMapper(AbstractMapper):
8
+ class TaskMapper(AbstractMapper):
9
9
 
10
- def build_entity(self, item: TaskDto) -> Optional[ProjectTaskEntity]:
10
+ def build_entity(self, item: Task) -> Optional[TaskEntity]:
11
11
  if not item:
12
12
  return None
13
13
 
14
- return ProjectTaskEntity(
14
+ return TaskEntity(
15
15
  public_id=item.public_id or '',
16
16
  title=item.title or '',
17
17
  status=item.frontend_status.status_translation or '',