thestage 0.5.37__tar.gz → 0.5.39__tar.gz

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 (172) hide show
  1. {thestage-0.5.37 → thestage-0.5.39}/PKG-INFO +2 -2
  2. {thestage-0.5.37 → thestage-0.5.39}/pyproject.toml +3 -4
  3. {thestage-0.5.37 → thestage-0.5.39}/thestage/__init__.py +1 -1
  4. {thestage-0.5.37 → thestage-0.5.39}/thestage/controllers/config_controller.py +3 -4
  5. {thestage-0.5.37 → thestage-0.5.39}/thestage/controllers/container_controller.py +12 -16
  6. {thestage-0.5.37 → thestage-0.5.39}/thestage/controllers/project_controller.py +145 -3
  7. {thestage-0.5.37 → thestage-0.5.39}/thestage/controllers/utils_controller.py +2 -3
  8. thestage-0.5.39/thestage/entities/file_item.py +27 -0
  9. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/project_inference_simulator_model.py +1 -0
  10. thestage-0.5.39/thestage/exceptions/file_system_exception.py +6 -0
  11. {thestage-0.5.37 → thestage-0.5.39}/thestage/helpers/error_handler.py +2 -2
  12. {thestage-0.5.37 → thestage-0.5.39}/thestage/helpers/logger/app_logger.py +3 -4
  13. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/abstract_service.py +1 -2
  14. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/app_config_service.py +2 -3
  15. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/git/git_client.py +3 -3
  16. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/api_client.py +58 -61
  17. thestage-0.5.39/thestage/services/clients/thestage_api/core/api_client_abstract.py +91 -0
  18. thestage-0.5.39/thestage/services/clients/thestage_api/core/api_client_core.py +25 -0
  19. thestage-0.5.39/thestage/services/clients/thestage_api/core/http_client_exception.py +12 -0
  20. thestage-0.5.39/thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_request.py +14 -0
  21. thestage-0.5.39/thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_instance_response.py +13 -0
  22. thestage-0.5.39/thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_sagemaker_request.py +12 -0
  23. thestage-0.5.39/thestage/services/clients/thestage_api/dtos/inference_controller/deploy_inference_model_to_sagemaker_response.py +12 -0
  24. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/logging_controller/log_polling_request.py +1 -1
  25. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/sftp_path_helper.py +3 -2
  26. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/config_provider/config_provider.py +98 -44
  27. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/connect/connect_service.py +1 -1
  28. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/container/container_service.py +2 -8
  29. thestage-0.5.39/thestage/services/core_files/config_entity.py +25 -0
  30. thestage-0.5.39/thestage/services/filesystem_service.py +115 -0
  31. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/instance/instance_service.py +1 -2
  32. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/logging/logging_service.py +76 -95
  33. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/project/dto/inference_simulator_model_dto.py +1 -0
  34. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/project/mapper/project_inference_simulator_model_mapper.py +1 -0
  35. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/project/project_service.py +184 -7
  36. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/remote_server_service.py +3 -3
  37. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/service_factory.py +1 -2
  38. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/validation_service.py +26 -10
  39. {thestage-0.5.37 → thestage-0.5.39}/LICENSE.txt +0 -0
  40. {thestage-0.5.37 → thestage-0.5.39}/README.md +0 -0
  41. {thestage-0.5.37 → thestage-0.5.39}/thestage/.env +0 -0
  42. {thestage-0.5.37 → thestage-0.5.39}/thestage/__main__.py +0 -0
  43. {thestage-0.5.37 → thestage-0.5.39}/thestage/color_scheme/color_scheme.py +0 -0
  44. {thestage-0.5.37 → thestage-0.5.39}/thestage/config/__init__.py +0 -0
  45. {thestage-0.5.37 → thestage-0.5.39}/thestage/config/env_base.py +0 -0
  46. {thestage-0.5.37 → thestage-0.5.39}/thestage/controllers/__init__.py +0 -0
  47. {thestage-0.5.37 → thestage-0.5.39}/thestage/controllers/base_controller.py +0 -0
  48. {thestage-0.5.37 → thestage-0.5.39}/thestage/controllers/instance_controller.py +0 -0
  49. {thestage-0.5.37 → thestage-0.5.39}/thestage/debug_main.dist.py +0 -0
  50. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/__init__.py +0 -0
  51. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/container.py +0 -0
  52. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/enums/__init__.py +0 -0
  53. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/enums/order_direction_type.py +0 -0
  54. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/enums/shell_type.py +0 -0
  55. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/enums/tail_output_type.py +0 -0
  56. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/enums/yes_no_response.py +0 -0
  57. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/project_inference_simulator.py +0 -0
  58. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/project_task.py +0 -0
  59. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/rented_instance.py +0 -0
  60. {thestage-0.5.37 → thestage-0.5.39}/thestage/entities/self_hosted_instance.py +0 -0
  61. {thestage-0.5.37 → thestage-0.5.39}/thestage/exceptions/__init__.py +0 -0
  62. {thestage-0.5.37 → thestage-0.5.39}/thestage/exceptions/auth_exception.py +0 -0
  63. {thestage-0.5.37 → thestage-0.5.39}/thestage/exceptions/base_exception.py +0 -0
  64. {thestage-0.5.37 → thestage-0.5.39}/thestage/exceptions/business_logic_exception.py +0 -0
  65. {thestage-0.5.37 → thestage-0.5.39}/thestage/exceptions/config_exception.py +0 -0
  66. {thestage-0.5.37 → thestage-0.5.39}/thestage/exceptions/git_access_exception.py +0 -0
  67. {thestage-0.5.37 → thestage-0.5.39}/thestage/exceptions/http_error_exception.py +0 -0
  68. {thestage-0.5.37 → thestage-0.5.39}/thestage/exceptions/remote_server_exception.py +0 -0
  69. {thestage-0.5.37 → thestage-0.5.39}/thestage/git/ProgressPrinter.py +0 -0
  70. {thestage-0.5.37 → thestage-0.5.39}/thestage/helpers/__init__.py +0 -0
  71. {thestage-0.5.37 → thestage-0.5.39}/thestage/helpers/logger/__init__.py +0 -0
  72. {thestage-0.5.37 → thestage-0.5.39}/thestage/helpers/ssh_util.py +0 -0
  73. {thestage-0.5.37 → thestage-0.5.39}/thestage/i18n/en_GB/messages.po +0 -0
  74. {thestage-0.5.37 → thestage-0.5.39}/thestage/i18n/translation.py +0 -0
  75. {thestage-0.5.37 → thestage-0.5.39}/thestage/main.py +0 -0
  76. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/.env +0 -0
  77. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/__init__.py +0 -0
  78. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/abstract_mapper.py +0 -0
  79. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/.DS_Store +0 -0
  80. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/__init__.py +0 -0
  81. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/git/__init__.py +0 -0
  82. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/__init__.py +0 -0
  83. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/__init__.py +0 -0
  84. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/base_response.py +0 -0
  85. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/cloud_provider_region.py +0 -0
  86. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/container_param_request.py +0 -0
  87. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/container_response.py +0 -0
  88. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/docker_container_assigned_device.py +0 -0
  89. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/docker_container_controller/docker_container_list_request.py +0 -0
  90. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/docker_container_controller/docker_container_list_response.py +0 -0
  91. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/docker_container_mapping.py +0 -0
  92. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/entity_filter_request.py +0 -0
  93. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/__init__.py +0 -0
  94. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/container_pending_action.py +0 -0
  95. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/container_status.py +0 -0
  96. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/cpu_type.py +0 -0
  97. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/currency_type.py +0 -0
  98. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/daemon_status.py +0 -0
  99. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/disk_type.py +0 -0
  100. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/drive_type.py +0 -0
  101. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/gpu_name.py +0 -0
  102. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/inference_model_status.py +0 -0
  103. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/inference_simulator_status.py +0 -0
  104. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/instance_rented_status.py +0 -0
  105. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/instance_type.py +0 -0
  106. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/location_region.py +0 -0
  107. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/power_status.py +0 -0
  108. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/provider_name.py +0 -0
  109. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/selfhosted_status.py +0 -0
  110. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/task_execution_status.py +0 -0
  111. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/enums/task_status.py +0 -0
  112. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/frontend_status.py +0 -0
  113. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_request.py +0 -0
  114. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/inference_controller/get_inference_simulator_response.py +0 -0
  115. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_list_for_project_request.py +0 -0
  116. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_list_for_project_response.py +0 -0
  117. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_model_list_for_project_request.py +0 -0
  118. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/inference_controller/inference_simulator_model_list_for_project_response.py +0 -0
  119. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/inference_simulator_model_response.py +0 -0
  120. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/inference_simulator_response.py +0 -0
  121. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/installed_service.py +0 -0
  122. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/instance_detected_gpus.py +0 -0
  123. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/instance_rented_response.py +0 -0
  124. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/logging_controller/docker_container_log_stream_request.py +0 -0
  125. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/logging_controller/log_polling_response.py +0 -0
  126. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/logging_controller/task_log_stream_request.py +0 -0
  127. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/logging_controller/user_logs_query_request.py +0 -0
  128. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/logging_controller/user_logs_query_response.py +0 -0
  129. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/paginated_entity_list.py +0 -0
  130. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/pagination_data.py +0 -0
  131. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/price_definition.py +0 -0
  132. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_request.py +0 -0
  133. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/project_controller/project_get_deploy_ssh_key_response.py +0 -0
  134. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_request.py +0 -0
  135. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/project_controller/project_push_inference_simulator_model_response.py +0 -0
  136. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_request.py +0 -0
  137. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/project_controller/project_run_task_response.py +0 -0
  138. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_request.py +0 -0
  139. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/project_controller/project_start_inference_simulator_response.py +0 -0
  140. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/project_response.py +0 -0
  141. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/selfhosted_instance_response.py +0 -0
  142. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_key_to_user_request.py +0 -0
  143. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_key_to_user_response.py +0 -0
  144. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_public_key_to_instance_request.py +0 -0
  145. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/ssh_key_controller/add_ssh_public_key_to_instance_response.py +0 -0
  146. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/ssh_key_controller/is_user_has_public_ssh_key_request.py +0 -0
  147. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/ssh_key_controller/is_user_has_public_ssh_key_response.py +0 -0
  148. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/task_controller/task_list_for_project_request.py +0 -0
  149. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/task_controller/task_list_for_project_response.py +0 -0
  150. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/task_controller/task_status_localized_map_response.py +0 -0
  151. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/task_controller/task_view_response.py +0 -0
  152. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/clients/thestage_api/dtos/user_profile.py +0 -0
  153. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/config_provider/__init__.py +0 -0
  154. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/connect/dto/remote_server_config.py +0 -0
  155. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/container/__init__.py +0 -0
  156. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/container/mapper/__init__.py +0 -0
  157. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/container/mapper/container_mapper.py +0 -0
  158. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/instance/__init__.py +0 -0
  159. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/instance/mapper/__init__.py +0 -0
  160. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/instance/mapper/instance_mapper.py +0 -0
  161. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/instance/mapper/selfhosted_mapper.py +0 -0
  162. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/logging/byte_print_style.py +0 -0
  163. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/logging/dto/log_message.py +0 -0
  164. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/logging/dto/log_type.py +0 -0
  165. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/logging/logging_constants.py +0 -0
  166. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/project/__init__.py +0 -0
  167. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/project/dto/inference_simulator_dto.py +0 -0
  168. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/project/dto/project_config.py +0 -0
  169. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/project/mapper/__init__.py +0 -0
  170. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/project/mapper/project_inference_simulator_mapper.py +0 -0
  171. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/project/mapper/project_task_mapper.py +0 -0
  172. {thestage-0.5.37 → thestage-0.5.39}/thestage/services/task/dto/task_dto.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: thestage
3
- Version: 0.5.37
3
+ Version: 0.5.39
4
4
  Summary:
5
5
  Author: TheStage AI team
6
6
  Author-email: hello@thestage.ai
@@ -11,6 +11,7 @@ Classifier: Programming Language :: Python :: 3.10
11
11
  Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
13
  Requires-Dist: aioconsole (>=0.8.0,<0.9.0)
14
+ Requires-Dist: boto3 (>=1.35.80,<2.0.0)
14
15
  Requires-Dist: gitpython (>=3.1.40,<4.0.0)
15
16
  Requires-Dist: httpx (>=0.27.2,<0.28.0)
16
17
  Requires-Dist: paramiko (>=3.4.0,<4.0.0)
@@ -19,7 +20,6 @@ Requires-Dist: python-dotenv (>=1.0.0,<2.0.0)
19
20
  Requires-Dist: python-gettext-translations (>=1.1.0,<2.0.0)
20
21
  Requires-Dist: requests (>=2.31.0,<3.0.0)
21
22
  Requires-Dist: tabulate (>=0.9.0,<0.10.0)
22
- Requires-Dist: thestage-core (==0.0.16)
23
23
  Requires-Dist: typer[all] (>=0.9.0,<0.10.0)
24
24
  Description-Content-Type: text/markdown
25
25
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "thestage"
3
- version = "0.5.37"
3
+ version = "0.5.39"
4
4
  description = ""
5
5
  authors = ["TheStage AI team <hello@thestage.ai>"]
6
6
  readme = "README.md"
@@ -28,11 +28,10 @@ gitpython = "^3.1.40"
28
28
  requests = "^2.31.0"
29
29
  python-gettext-translations = "^1.1.0"
30
30
  paramiko = "^3.4.0"
31
- #thestage-core = {git = "git@github.com:TheStageAI/thestage-core.git", branch = 'main'}
32
- #thestage_core = { path = "/Users/alexey/Documents/PYTHON_thestage_core", develop = true }
33
- thestage-core = "0.0.16"
31
+
34
32
  aioconsole = "^0.8.0"
35
33
  httpx = "^0.27.2"
34
+ boto3 = "^1.35.80"
36
35
 
37
36
  [tool.poetry.dev-dependencies]
38
37
  pytest = "^7.4.3"
@@ -1,3 +1,3 @@
1
1
  from . import *
2
2
  __app_name__ = "thestage"
3
- __version__ = "0.5.37"
3
+ __version__ = "0.5.39"
@@ -2,8 +2,7 @@ import os
2
2
  from pathlib import Path
3
3
 
4
4
  import click
5
- from thestage_core.entities.config_entity import ConfigEntity
6
- from thestage_core.services.filesystem_service import FileSystemServiceCore
5
+ from thestage.services.core_files.config_entity import ConfigEntity
7
6
 
8
7
  from thestage.entities.enums.yes_no_response import YesOrNoResponse
9
8
  from thestage.i18n.translation import __
@@ -33,7 +32,7 @@ def config_get():
33
32
  typer.echo(__('No configuration found'))
34
33
  raise typer.Exit(1)
35
34
 
36
- config_provider.save_global_config(config=config)
35
+ config_provider.save_config(config=config)
37
36
 
38
37
  typer.echo(__('THESTAGE TOKEN: %token%', {'token': config.main.thestage_auth_token or ''}))
39
38
  typer.echo(__('THESTAGE API LINK: %link%', {'link': config.main.thestage_api_url or ''}))
@@ -80,7 +79,7 @@ def config_clear():
80
79
  local_path = get_current_directory()
81
80
  config_provider = ConfigProvider(local_path=local_path)
82
81
  config_dir = config_provider.get_full_config().runtime.config_global_path
83
- config_provider.remove_all_config()
82
+ config_provider.clear_config()
84
83
  typer.echo(f'Removed {config_dir}')
85
84
 
86
85
  raise typer.Exit(0)
@@ -214,11 +214,6 @@ def put_file(
214
214
  typer.echo(__('Container unique ID is required'))
215
215
  raise typer.Exit(1)
216
216
 
217
- # TODO delete when we change mappings
218
- if destination_path.startswith("/app/") or destination_path == "/app":
219
- typer.echo("/app/ is reserved for project code and must not contain custom files. Сonsider adding your files to the project repository")
220
- raise typer.Exit(1)
221
-
222
217
  service_factory = validate_config_and_get_service_factory()
223
218
  config = service_factory.get_config_provider().get_full_config()
224
219
 
@@ -396,9 +391,16 @@ def stop_container(
396
391
  raise typer.Exit(0)
397
392
 
398
393
 
399
- @app.command(name="logs", no_args_is_help=True, help=__("Stream real-time container logs; log history is available in your TheStage AI account"))
394
+ @app.command(name="logs", no_args_is_help=True, help=__("Stream real-time Docker container logs or view last logs for a container"))
400
395
  def container_logs(
401
396
  container_uid: Optional[str] = typer.Argument(help=__("Container unique id")),
397
+ logs_number: Optional[int] = typer.Option(
398
+ None,
399
+ '--number',
400
+ '-n',
401
+ help=__("Display a number of latest log entries. No real-time stream if provided."),
402
+ is_eager=False,
403
+ ),
402
404
  ):
403
405
  """
404
406
  Streams real-time container logs
@@ -412,21 +414,15 @@ def container_logs(
412
414
  service_factory = validate_config_and_get_service_factory()
413
415
  config = service_factory.get_config_provider().get_full_config()
414
416
 
415
- container_service: ContainerService = service_factory.get_container_service()
416
417
  logging_service: LoggingService = service_factory.get_logging_service()
417
418
 
418
- container: Optional[DockerContainerDto] = container_service.get_container(
419
- config=config,
420
- container_slug=container_uid,
421
- )
422
-
423
- if container:
424
- logging_service.stream_container_logs(
419
+ if logs_number is None:
420
+ logging_service.stream_container_logs_with_controls(
425
421
  config=config,
426
- container=container
422
+ container_uid=container_uid
427
423
  )
428
424
  else:
429
- typer.echo(__("Container not found: %container_slug%", {'container_slug': container_uid}))
425
+ logging_service.print_last_container_logs(config=config, container_uid=container_uid, logs_number=logs_number)
430
426
 
431
427
  app_logger.info(f'Container logs - end')
432
428
  raise typer.Exit(0)
@@ -1,3 +1,4 @@
1
+ import time
1
2
  from typing import Optional, List
2
3
 
3
4
  import re
@@ -102,11 +103,10 @@ def init(
102
103
  )
103
104
 
104
105
  typer.echo(__("Project successfully initialized at %path%", {"path": config.runtime.working_directory}))
105
- typer.echo(__("Initialization complete"))
106
106
  raise typer.Exit(0)
107
107
 
108
108
 
109
- @app.command(name='run', no_args_is_help=True, help=__("Run task within project. By default, it uses the latest commit from the main branch and streams real-time task logs."))
109
+ @app.command(name='run', no_args_is_help=True, help=__("Run a task within the project. By default, it uses the latest commit from the main branch and streams real-time task logs."))
110
110
  def run(
111
111
  command: Annotated[List[str], typer.Argument(
112
112
  help=__("Command to run (required)"),
@@ -140,6 +140,13 @@ def run(
140
140
  help=__("Disable real-time log streaming"),
141
141
  is_eager=False,
142
142
  ),
143
+ task_title: Optional[str] = typer.Option(
144
+ None,
145
+ "--title",
146
+ "-t",
147
+ help=__("Provide a custom task title. Git commit message is used by default."),
148
+ is_eager=False,
149
+ ),
143
150
  ):
144
151
  """
145
152
  Runs a task within a project
@@ -160,6 +167,7 @@ def run(
160
167
  run_command=" ".join(command),
161
168
  commit_hash=commit_hash,
162
169
  docker_container_slug=docker_container_slug,
170
+ task_title=task_title,
163
171
  )
164
172
 
165
173
  if enable_log_stream:
@@ -723,4 +731,138 @@ def inference_simulator_logs(
723
731
  logging_service.print_last_inference_simulator_logs(config=config, inference_simulator_id=inference_simulator_id, logs_number=logs_number)
724
732
 
725
733
  app_logger.info(f'Inference simulator logs - end')
726
- raise typer.Exit(0)
734
+ raise typer.Exit(0)
735
+
736
+
737
+ @inference_simulator_model_app.command("deploy-instance", no_args_is_help=True, help=__("Deploy an inference simulator model to an instance"))
738
+ def deploy_inference_simulator_model_to_instance(
739
+ unique_id: Optional[str] = typer.Argument(help=__("Inference simulator model unique ID"), ),
740
+ rented_instance_unique_id: Optional[str] = typer.Option(
741
+ None,
742
+ '--rented-instance-unique-id',
743
+ '-ruid',
744
+ help=__("The rented instance unique ID on which the inference simulator model will be deployed"),
745
+ is_eager=False,
746
+ ),
747
+ self_hosted_instance_unique_id: Optional[str] = typer.Option(
748
+ None,
749
+ '--self-hosted-instance-unique-id',
750
+ '-suid',
751
+ help=__("The self-hosted instance unique ID on which the inference simulator model will be deployed"),
752
+ is_eager=False,
753
+ ),
754
+ working_directory: Optional[str] = typer.Option(
755
+ None,
756
+ "--working-directory",
757
+ "-wd",
758
+ help=__("Full path to working directory. By default, the current directory is used"),
759
+ show_default=False,
760
+ is_eager=False,
761
+ ),
762
+ enable_log_stream: Optional[bool] = typer.Option(
763
+ True,
764
+ " /--no-logs",
765
+ " /-nl",
766
+ help=__("Disable real-time log streaming"),
767
+ is_eager=False,
768
+ ),
769
+ ):
770
+ """
771
+ Deploy an inference simulator model to an instance
772
+ """
773
+
774
+ if unique_id and not re.match(r"^[a-zA-Z0-9-]+$", unique_id):
775
+ raise typer.BadParameter(__("Invalid UID format. The UID can only contain letters, numbers, and hyphens."))
776
+
777
+ unique_id_with_timestamp = f"{unique_id}-{int(time.time())}"
778
+
779
+ app_logger.info(f'Deploying an inference simulator model')
780
+
781
+ service_factory = validate_config_and_get_service_factory(working_directory=working_directory)
782
+ config = service_factory.get_config_provider().get_full_config()
783
+
784
+ project_service = service_factory.get_project_service()
785
+
786
+ project_service.project_deploy_inference_simulator_model_to_instance(
787
+ config=config,
788
+ unique_id=unique_id,
789
+ unique_id_with_timestamp=unique_id_with_timestamp,
790
+ rented_instance_unique_id=rented_instance_unique_id,
791
+ self_hosted_instance_unique_id=self_hosted_instance_unique_id,
792
+ )
793
+
794
+ if enable_log_stream:
795
+ logging_service: LoggingService = service_factory.get_logging_service()
796
+
797
+ logging_service.stream_inference_simulator_logs_with_controls(
798
+ config=config,
799
+ slug=unique_id_with_timestamp
800
+ )
801
+ raise typer.Exit(0)
802
+
803
+
804
+ @inference_simulator_model_app.command("deploy-sagemaker", no_args_is_help=True, help=__("Deploy an inference simulator model to SageMaker"))
805
+ def deploy_inference_simulator_model_to_sagemaker(
806
+ unique_id: Optional[str] = typer.Argument(help=__("Inference simulator model unique ID"), ),
807
+ arn: Optional[str] = typer.Option(
808
+ None,
809
+ '--amazon-resource-name',
810
+ '-arn',
811
+ help=__("The Amazon Resource Name of the IAM Role to use, e.g., arn:aws:iam::{aws_account_id}:role/{role}"),
812
+ is_eager=False,
813
+ ),
814
+ working_directory: Optional[str] = typer.Option(
815
+ None,
816
+ "--working-directory",
817
+ "-wd",
818
+ help=__("Full path to working directory. By default, the current directory is used"),
819
+ show_default=False,
820
+ is_eager=False,
821
+ ),
822
+ instance_type: Optional[str] = typer.Option(
823
+ None,
824
+ '--instance-type',
825
+ '-it',
826
+ help=__("Instance type on which the inference simulator model will be deployed"),
827
+ is_eager=False,
828
+ ),
829
+ initial_variant_weight: Optional[float] = typer.Option(
830
+ None,
831
+ "--initial-variant-weight",
832
+ "-ivw",
833
+ help=__("Initial Variant Weight. By default 1.0"),
834
+ show_default=False,
835
+ is_eager=False,
836
+ ),
837
+ initial_instance_count: Optional[int] = typer.Option(
838
+ None,
839
+ "--initial-instance-count",
840
+ "-iic",
841
+ help=__("Initial Instance Count"),
842
+ show_default=False,
843
+ is_eager=False,
844
+ ),
845
+
846
+ ):
847
+ """
848
+ Deploy an inference simulator model to SageMaker
849
+ """
850
+
851
+ if unique_id and not re.match(r"^[a-zA-Z0-9-]+$", unique_id):
852
+ raise typer.BadParameter(__("Invalid UID format. The UID can only contain letters, numbers, and hyphens."))
853
+
854
+ app_logger.info(f'Deploying an inference simulator model')
855
+
856
+ service_factory = validate_config_and_get_service_factory(working_directory=working_directory)
857
+ config = service_factory.get_config_provider().get_full_config()
858
+
859
+ project_service = service_factory.get_project_service()
860
+
861
+ project_service.project_deploy_inference_simulator_model_to_sagemaker(
862
+ config=config,
863
+ unique_id=unique_id,
864
+ arn=arn,
865
+ instance_type=instance_type,
866
+ initial_variant_weight=initial_variant_weight,
867
+ initial_instance_count=initial_instance_count,
868
+ )
@@ -2,8 +2,7 @@ import os
2
2
  import pathlib
3
3
  from typing import Optional, Dict, Tuple
4
4
 
5
- from thestage_core.entities.config_entity import ConfigEntity
6
-
5
+ from thestage.services.core_files.config_entity import ConfigEntity
7
6
  from thestage.helpers.error_handler import error_handler
8
7
  from thestage.services.service_factory import ServiceFactory
9
8
  from thestage.services.config_provider.config_provider import ConfigProvider
@@ -24,6 +23,6 @@ def validate_config_and_get_service_factory(
24
23
 
25
24
  validation_service = service_factory.get_validation_service()
26
25
  validation_service.check_token(config=config)
27
- config_provider.save_global_config(config=config)
26
+ config_provider.save_config(config=config)
28
27
 
29
28
  return service_factory
@@ -0,0 +1,27 @@
1
+ import os
2
+ from pathlib import Path
3
+ from typing import Optional, List
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field
6
+
7
+
8
+ class FileItemEntity(BaseModel):
9
+ model_config = ConfigDict(use_enum_values=True)
10
+
11
+ name: Optional[str] = Field(None)
12
+ path: Optional[str] = Field(None)
13
+ is_file: Optional[bool] = Field(False)
14
+ is_folder: Optional[bool] = Field(False)
15
+ file_size: Optional[int] = Field(None)
16
+ children: List['FileItemEntity'] = Field(default=[])
17
+
18
+ @staticmethod
19
+ def build_from_path(path: Path) -> 'FileItemEntity':
20
+ file_stat = os.stat(path)
21
+ return FileItemEntity(
22
+ name=path.name,
23
+ path=str(path.absolute()),
24
+ is_file=path.is_file(),
25
+ is_folder=path.is_dir(),
26
+ file_size=file_stat.st_size,
27
+ )
@@ -11,6 +11,7 @@ class ProjectInferenceSimulatorModelEntity(BaseModel):
11
11
  )
12
12
 
13
13
  id: Optional[int] = Field(None, alias='ID')
14
+ slug: Optional[str] = Field(None, alias='UNIQUE_ID')
14
15
  status: Optional[str] = Field(None, alias='STATUS')
15
16
  commit_hash: Optional[str] = Field(None, alias='COMMIT_HASH')
16
17
  environment_metadata: Optional[str] = Field(None, alias='ENVIRONMENT_METADATA')
@@ -0,0 +1,6 @@
1
+ from thestage.exceptions.base_exception import BaseAbstractException
2
+
3
+
4
+ class FileSystemException(BaseAbstractException):
5
+ def __init__(self, message: str):
6
+ super(FileSystemException, self).__init__(message=message)
@@ -6,10 +6,9 @@ import typer
6
6
  from click.exceptions import Exit, Abort
7
7
  from git import GitCommandError
8
8
  from paramiko.ssh_exception import PasswordRequiredException
9
- from thestage_core.exceptions.file_system_exception import FileSystemException
10
- from thestage_core.exceptions.http_error_exception import HttpClientException
11
9
 
12
10
  from thestage.config import THESTAGE_API_URL
11
+ from thestage.exceptions.file_system_exception import FileSystemException
13
12
  from thestage.exceptions.remote_server_exception import RemoteServerException
14
13
  from thestage.i18n.translation import __
15
14
  from thestage.exceptions.git_access_exception import GitAccessException
@@ -17,6 +16,7 @@ from thestage.exceptions.auth_exception import AuthException
17
16
  from thestage.exceptions.business_logic_exception import BusinessLogicException
18
17
  from thestage.exceptions.config_exception import ConfigException
19
18
  from thestage.helpers.logger.app_logger import app_logger
19
+ from thestage.services.clients.thestage_api.core.http_client_exception import HttpClientException
20
20
 
21
21
 
22
22
  def error_handler() -> Callable:
@@ -2,13 +2,12 @@ import logging
2
2
  import platform
3
3
  from logging.handlers import RotatingFileHandler
4
4
  from pathlib import Path
5
- from typing import Any
6
5
 
7
- import typer
8
- from thestage_core.config import THESTAGE_CONFIG_DIR, THESTAGE_CONFIG_FILE
9
- from thestage_core.exceptions.file_system_exception import FileSystemException
6
+
7
+ from thestage.config import THESTAGE_CONFIG_DIR
10
8
 
11
9
  from thestage.config import THESTAGE_LOGGING_FILE
10
+ from thestage.exceptions.file_system_exception import FileSystemException
12
11
 
13
12
 
14
13
  def get_log_path_from_os() -> Path:
@@ -3,8 +3,7 @@ from typing import List, Dict, Any, Optional
3
3
 
4
4
  import typer
5
5
  from tabulate import tabulate
6
- from thestage_core.entities.config_entity import ConfigEntity
7
-
6
+ from thestage.services.core_files.config_entity import ConfigEntity
8
7
  from thestage.helpers.logger.app_logger import app_logger
9
8
  from thestage.i18n.translation import __
10
9
  from thestage.services.abstract_mapper import AbstractMapper
@@ -2,8 +2,7 @@ import os
2
2
 
3
3
  import click
4
4
  import typer
5
- from thestage_core.entities.config_entity import ConfigEntity
6
-
5
+ from thestage.services.core_files.config_entity import ConfigEntity
7
6
  from thestage.i18n.translation import __
8
7
  from thestage.entities.enums.yes_no_response import YesOrNoResponse
9
8
  from thestage.services.config_provider.config_provider import ConfigProvider
@@ -42,7 +41,7 @@ class AppConfigService:
42
41
  config.main.thestage_auth_token = token
43
42
 
44
43
  self.__validation_service.check_token(config=config)
45
- self.__config_provider.save_global_config(config=config)
44
+ self.__config_provider.save_config(config=config)
46
45
 
47
46
  @staticmethod
48
47
  def app_remove_env():
@@ -7,11 +7,11 @@ import git
7
7
  import typer
8
8
  from git import Remote, Repo, GitCommandError, Commit
9
9
  from rich import print
10
- from thestage_core.services.filesystem_service import FileSystemServiceCore
11
10
 
12
11
  from thestage.color_scheme.color_scheme import ColorScheme
13
12
  from thestage.exceptions.git_access_exception import GitAccessException
14
13
  from thestage.git.ProgressPrinter import ProgressPrinter
14
+ from thestage.services.filesystem_service import FileSystemServiceCore
15
15
 
16
16
 
17
17
  class GitLocalClient:
@@ -260,8 +260,8 @@ class GitLocalClient:
260
260
  self.__file_system_service.create_if_not_exists_file(gitignore_path)
261
261
  self.git_add_by_path(repo_path=path, file_path=str(gitignore_path))
262
262
 
263
- is_present_tsr = self.__file_system_service.find_in_text_file(file=str(gitignore_path),
264
- find=self.__git_ignore_thestage_line)
263
+ is_present_tsr = self.__file_system_service.find_line_in_text_file(file=str(gitignore_path),
264
+ find=self.__git_ignore_thestage_line)
265
265
  if not is_present_tsr:
266
266
  self.__file_system_service.add_line_to_text_file(file=str(gitignore_path),
267
267
  new_line=self.__git_ignore_thestage_line)
@@ -2,14 +2,22 @@ from typing import Optional, List, Tuple, Dict, Iterator
2
2
 
3
3
  import httpx
4
4
  import requests
5
- from thestage_core.services.clients.thestage_api.api_client import TheStageApiClientCore
6
5
 
7
6
  from thestage.helpers.error_handler import error_handler
7
+ from thestage.services.clients.thestage_api.core.api_client_core import TheStageApiClientCore
8
8
  from thestage.services.clients.thestage_api.dtos.docker_container_controller.docker_container_list_request import \
9
9
  DockerContainerListRequest
10
10
  from thestage.services.clients.thestage_api.dtos.docker_container_controller.docker_container_list_response import \
11
11
  DockerContainerListResponse
12
12
  from thestage.services.clients.thestage_api.dtos.entity_filter_request import EntityFilterRequest
13
+ from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_instance_request import \
14
+ DeployInferenceModelToInstanceRequest
15
+ from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_instance_response import \
16
+ DeployInferenceModelToInstanceResponse
17
+ from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_sagemaker_request import \
18
+ DeployInferenceModelToSagemakerRequest
19
+ from thestage.services.clients.thestage_api.dtos.inference_controller.deploy_inference_model_to_sagemaker_response import \
20
+ DeployInferenceModelToSagemakerResponse
13
21
  from thestage.services.clients.thestage_api.dtos.inference_controller.get_inference_simulator_request import \
14
22
  GetInferenceSimulatorRequest
15
23
  from thestage.services.clients.thestage_api.dtos.inference_controller.get_inference_simulator_response import \
@@ -514,65 +522,6 @@ class TheStageApiClient(TheStageApiClientCore):
514
522
  return ProjectRunTaskResponse.model_validate(response) if response else None
515
523
 
516
524
 
517
- def get_container_log_stream(self, token: str, container_id: int) -> Iterator[str]:
518
- request_headers = {'Content-Type': 'application/json'}
519
- if token: request_headers['Authorization'] = f"Bearer {token}"
520
-
521
- session = requests.Session()
522
- request = DockerContainerLogStreamRequest(
523
- dockerContainerId=container_id,
524
- )
525
-
526
- with session.post(
527
- url=f"{self._get_host()}/user-api/v1/logging/stream/container",
528
- headers=request_headers,
529
- stream=True,
530
- json=request.model_dump(),
531
- ) as response:
532
- for line in response.iter_lines():
533
- if line:
534
- yield line.decode('utf-8')
535
-
536
-
537
- async def get_container_log_stream_httpx(self, token: str, container_id: int) -> Iterator[str]:
538
- request_headers = {'Content-Type': 'application/json'}
539
- if token: request_headers['Authorization'] = f"Bearer {token}"
540
-
541
- request = DockerContainerLogStreamRequest(
542
- dockerContainerId=container_id,
543
- )
544
-
545
- async with httpx.stream(
546
- method="POST",
547
- url=f"{self._get_host()}/user-api/v1/logging/stream/container",
548
- headers=request_headers,
549
- json=request.model_dump(),
550
- ) as response:
551
- async for line in response.iter_lines():
552
- if line:
553
- yield line.decode('utf-8')
554
-
555
-
556
- async def get_task_log_stream_httpx(self, token: str, task_id: int):
557
- request_headers = {'Content-Type': 'application/json'}
558
- if token: request_headers['Authorization'] = f"Bearer {token}"
559
-
560
- request = TaskLogStreamRequest(
561
- taskId=task_id,
562
- )
563
-
564
- async with httpx.AsyncClient() as client:
565
- async with client.stream(
566
- method="POST",
567
- url=f"{self._get_host()}/user-api/v1/logging/stream/task",
568
- headers=request_headers,
569
- json=request.model_dump(),
570
- ) as response:
571
- async for line in response.aiter_lines():
572
- if line:
573
- yield line
574
-
575
-
576
525
  async def poll_logs_httpx(self, token: str, docker_container_id: Optional[int], last_log_timestamp: str, last_log_id: str, task_id: Optional[int] = None, inference_simulator_id: Optional[int] = None) -> Optional[LogPollingResponse]:
577
526
  request_headers = {'Content-Type': 'application/json'}
578
527
  if token: request_headers['Authorization'] = f"Bearer {token}"
@@ -736,10 +685,58 @@ class TheStageApiClient(TheStageApiClientCore):
736
685
  return GetInferenceSimulatorResponse.model_validate(response) if response else None
737
686
 
738
687
 
739
- def query_user_logs(self, token: str, limit: int, task_id: Optional[int] = None, inference_simulator_id: Optional[int] = None) -> UserLogsQueryResponse:
688
+ @error_handler()
689
+ def deploy_inference_model_to_instance(
690
+ self,
691
+ token: str,
692
+ unique_id: str,
693
+ unique_id_with_timestamp: str,
694
+ rented_instance_unique_id: Optional[str] = None,
695
+ self_hosted_instance_unique_id: Optional[str] = None,
696
+
697
+ ) -> Optional[DeployInferenceModelToInstanceResponse]:
698
+ request = DeployInferenceModelToInstanceRequest(
699
+ inferenceSimulatorSlug=unique_id_with_timestamp,
700
+ modelSlug=unique_id,
701
+ instanceRentedSlug = rented_instance_unique_id,
702
+ selfhostedInstanceSlug = self_hosted_instance_unique_id
703
+ )
704
+
705
+ response = self._request(
706
+ method='POST',
707
+ url='/user-api/v1/inference-simulator-model/deploy/instance',
708
+ data=request.model_dump(),
709
+ token=token,
710
+ )
711
+ return DeployInferenceModelToInstanceResponse.model_validate(response) if response else None
712
+
713
+
714
+ @error_handler()
715
+ def deploy_inference_model_to_sagemaker(
716
+ self,
717
+ token: str,
718
+ unique_id: str,
719
+ arn: Optional[str] = None,
720
+ ) -> Optional[DeployInferenceModelToSagemakerResponse]:
721
+ request = DeployInferenceModelToSagemakerRequest(
722
+ modelSlug=unique_id,
723
+ arn=arn,
724
+ )
725
+
726
+ response = self._request(
727
+ method='POST',
728
+ url='/user-api/v1/inference-simulator-model/grant-user-arn-access',
729
+ data=request.model_dump(),
730
+ token=token,
731
+ )
732
+ return DeployInferenceModelToSagemakerResponse.model_validate(response) if response else None
733
+
734
+
735
+ def query_user_logs(self, token: str, limit: int, task_id: Optional[int] = None, inference_simulator_id: Optional[int] = None, container_id: Optional[int] = None) -> UserLogsQueryResponse:
740
736
  request = UserLogsQueryRequest(
741
737
  inferenceSimulatorId=inference_simulator_id,
742
738
  taskId=task_id,
739
+ containerId=container_id,
743
740
  limit=limit,
744
741
  ascendingOrder=False,
745
742
  )