lightning-sdk 2025.8.6rc2__py3-none-any.whl → 2025.11.5__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 (330) hide show
  1. lightning_sdk/__init__.py +13 -7
  2. lightning_sdk/__version__.py +3 -0
  3. lightning_sdk/agents.py +2 -1
  4. lightning_sdk/ai_hub.py +2 -1
  5. lightning_sdk/api/__init__.py +2 -0
  6. lightning_sdk/api/base_studio_api.py +13 -9
  7. lightning_sdk/api/cloud_account_api.py +31 -10
  8. lightning_sdk/api/deployment_api.py +27 -1
  9. lightning_sdk/api/job_api.py +16 -12
  10. lightning_sdk/api/license_api.py +26 -59
  11. lightning_sdk/api/llm_api.py +25 -2
  12. lightning_sdk/api/mmt_api.py +5 -2
  13. lightning_sdk/api/studio_api.py +252 -55
  14. lightning_sdk/api/teamspace_api.py +106 -30
  15. lightning_sdk/api/user_api.py +56 -2
  16. lightning_sdk/api/utils.py +108 -18
  17. lightning_sdk/base_studio.py +51 -27
  18. lightning_sdk/cli/__init__.py +1 -0
  19. lightning_sdk/cli/base_studio/__init__.py +10 -0
  20. lightning_sdk/cli/base_studio/list.py +43 -0
  21. lightning_sdk/cli/config/__init__.py +14 -0
  22. lightning_sdk/cli/config/get.py +57 -0
  23. lightning_sdk/cli/config/set.py +92 -0
  24. lightning_sdk/cli/config/show.py +9 -0
  25. lightning_sdk/cli/entrypoint.py +71 -71
  26. lightning_sdk/cli/groups.py +56 -0
  27. lightning_sdk/cli/job/__init__.py +7 -0
  28. lightning_sdk/cli/{clusters_menu.py → legacy/clusters_menu.py} +9 -6
  29. lightning_sdk/cli/{configure.py → legacy/configure.py} +2 -2
  30. lightning_sdk/cli/{connect.py → legacy/connect.py} +2 -2
  31. lightning_sdk/cli/{create.py → legacy/create.py} +12 -14
  32. lightning_sdk/cli/{delete.py → legacy/delete.py} +5 -5
  33. lightning_sdk/cli/legacy/deploy/__init__.py +0 -0
  34. lightning_sdk/cli/{deploy → legacy/deploy}/_auth.py +5 -6
  35. lightning_sdk/cli/{deploy → legacy/deploy}/devbox.py +8 -2
  36. lightning_sdk/cli/{deploy → legacy/deploy}/serve.py +19 -8
  37. lightning_sdk/cli/{download.py → legacy/download.py} +14 -15
  38. lightning_sdk/cli/legacy/entrypoint.py +110 -0
  39. lightning_sdk/cli/{generate.py → legacy/generate.py} +1 -1
  40. lightning_sdk/cli/{inspection.py → legacy/inspection.py} +1 -1
  41. lightning_sdk/cli/{job_and_mmt_action.py → legacy/job_and_mmt_action.py} +6 -6
  42. lightning_sdk/cli/{jobs_menu.py → legacy/jobs_menu.py} +1 -1
  43. lightning_sdk/cli/{list.py → legacy/list.py} +12 -13
  44. lightning_sdk/cli/{mmts_menu.py → legacy/mmts_menu.py} +1 -1
  45. lightning_sdk/cli/{open.py → legacy/open.py} +4 -4
  46. lightning_sdk/cli/{start.py → legacy/start.py} +1 -0
  47. lightning_sdk/cli/{stop.py → legacy/stop.py} +1 -1
  48. lightning_sdk/cli/{switch.py → legacy/switch.py} +1 -0
  49. lightning_sdk/cli/{teamspace_menu.py → legacy/teamspace_menu.py} +1 -1
  50. lightning_sdk/cli/{upload.py → legacy/upload.py} +7 -8
  51. lightning_sdk/cli/license/__init__.py +14 -0
  52. lightning_sdk/cli/license/get.py +15 -0
  53. lightning_sdk/cli/license/list.py +45 -0
  54. lightning_sdk/cli/license/set.py +13 -0
  55. lightning_sdk/cli/mmt/__init__.py +7 -0
  56. lightning_sdk/cli/studio/__init__.py +24 -0
  57. lightning_sdk/cli/studio/connect.py +139 -0
  58. lightning_sdk/cli/studio/create.py +96 -0
  59. lightning_sdk/cli/studio/delete.py +49 -0
  60. lightning_sdk/cli/studio/list.py +85 -0
  61. lightning_sdk/cli/studio/ssh.py +64 -0
  62. lightning_sdk/cli/studio/start.py +115 -0
  63. lightning_sdk/cli/studio/stop.py +45 -0
  64. lightning_sdk/cli/studio/switch.py +66 -0
  65. lightning_sdk/cli/utils/__init__.py +7 -0
  66. lightning_sdk/cli/utils/cloud_account_map.py +10 -0
  67. lightning_sdk/cli/utils/get_base_studio.py +24 -0
  68. lightning_sdk/cli/utils/handle_machine_and_gpus_args.py +69 -0
  69. lightning_sdk/cli/utils/logging.py +122 -0
  70. lightning_sdk/cli/utils/owner_selection.py +110 -0
  71. lightning_sdk/cli/utils/resolve.py +28 -0
  72. lightning_sdk/cli/utils/richt_print.py +35 -0
  73. lightning_sdk/cli/utils/save_to_config.py +27 -0
  74. lightning_sdk/cli/utils/ssh_connection.py +59 -0
  75. lightning_sdk/cli/utils/studio_selection.py +113 -0
  76. lightning_sdk/cli/utils/teamspace_selection.py +125 -0
  77. lightning_sdk/cli/vm/__init__.py +20 -0
  78. lightning_sdk/cli/vm/create.py +33 -0
  79. lightning_sdk/cli/vm/delete.py +25 -0
  80. lightning_sdk/cli/vm/list.py +30 -0
  81. lightning_sdk/cli/vm/ssh.py +31 -0
  82. lightning_sdk/cli/vm/start.py +60 -0
  83. lightning_sdk/cli/vm/stop.py +25 -0
  84. lightning_sdk/cli/vm/switch.py +38 -0
  85. lightning_sdk/constants.py +1 -0
  86. lightning_sdk/deployment/__init__.py +2 -0
  87. lightning_sdk/deployment/deployment.py +17 -2
  88. lightning_sdk/helpers.py +56 -37
  89. lightning_sdk/job/base.py +21 -6
  90. lightning_sdk/job/job.py +13 -0
  91. lightning_sdk/job/v1.py +11 -0
  92. lightning_sdk/job/v2.py +12 -0
  93. lightning_sdk/lightning_cloud/login.py +320 -10
  94. lightning_sdk/lightning_cloud/openapi/__init__.py +113 -3
  95. lightning_sdk/lightning_cloud/openapi/api/__init__.py +3 -0
  96. lightning_sdk/lightning_cloud/openapi/api/assistants_service_api.py +713 -75
  97. lightning_sdk/lightning_cloud/openapi/api/auth_service_api.py +376 -0
  98. lightning_sdk/lightning_cloud/openapi/api/billing_service_api.py +191 -1
  99. lightning_sdk/lightning_cloud/openapi/api/cloud_space_environment_template_service_api.py +5 -1
  100. lightning_sdk/lightning_cloud/openapi/api/cloud_space_service_api.py +420 -0
  101. lightning_sdk/lightning_cloud/openapi/api/cloudy_service_api.py +0 -97
  102. lightning_sdk/lightning_cloud/openapi/api/cluster_service_api.py +420 -0
  103. lightning_sdk/lightning_cloud/openapi/api/data_connection_service_api.py +101 -0
  104. lightning_sdk/lightning_cloud/openapi/api/incidents_service_api.py +1058 -0
  105. lightning_sdk/lightning_cloud/openapi/api/jobs_service_api.py +121 -0
  106. lightning_sdk/lightning_cloud/openapi/api/k8_s_cluster_service_api.py +1742 -94
  107. lightning_sdk/lightning_cloud/openapi/api/markets_service_api.py +145 -0
  108. lightning_sdk/lightning_cloud/openapi/api/models_store_api.py +4 -4
  109. lightning_sdk/lightning_cloud/openapi/api/product_license_service_api.py +108 -108
  110. lightning_sdk/lightning_cloud/openapi/api/projects_service_api.py +105 -0
  111. lightning_sdk/lightning_cloud/openapi/api/schedules_service_api.py +347 -0
  112. lightning_sdk/lightning_cloud/openapi/api/sdk_command_history_service_api.py +141 -0
  113. lightning_sdk/lightning_cloud/openapi/api/storage_service_api.py +761 -1
  114. lightning_sdk/lightning_cloud/openapi/configuration.py +3 -19
  115. lightning_sdk/lightning_cloud/openapi/models/__init__.py +110 -3
  116. lightning_sdk/lightning_cloud/openapi/models/assistant_id_conversations_body.py +15 -15
  117. lightning_sdk/lightning_cloud/openapi/models/cloudspace_id_visibility_body.py +27 -1
  118. lightning_sdk/lightning_cloud/openapi/models/cluster_id_kubernetestemplates_body.py +201 -0
  119. lightning_sdk/lightning_cloud/openapi/models/cluster_id_metrics_body.py +131 -1
  120. lightning_sdk/lightning_cloud/openapi/models/create.py +27 -1
  121. lightning_sdk/lightning_cloud/openapi/models/create_machine_request_represents_the_request_to_create_a_machine.py +461 -0
  122. lightning_sdk/lightning_cloud/openapi/models/deployments_id_body.py +27 -1
  123. lightning_sdk/lightning_cloud/openapi/models/externalv1_cloud_space_instance_status.py +105 -1
  124. lightning_sdk/lightning_cloud/openapi/models/externalv1_user_status.py +27 -1
  125. lightning_sdk/lightning_cloud/openapi/models/id_codeconfig_body.py +3 -81
  126. lightning_sdk/lightning_cloud/openapi/models/id_fork_body1.py +27 -1
  127. lightning_sdk/lightning_cloud/openapi/models/id_render_body.py +123 -0
  128. lightning_sdk/lightning_cloud/openapi/models/id_sleepconfig_body.py +175 -0
  129. lightning_sdk/lightning_cloud/openapi/models/id_transfer_body.py +53 -1
  130. lightning_sdk/lightning_cloud/openapi/models/incident_id_messages_body.py +123 -0
  131. lightning_sdk/lightning_cloud/openapi/models/incidents_id_body.py +279 -0
  132. lightning_sdk/lightning_cloud/openapi/models/job_id_reportroutingtelemetry_body.py +123 -0
  133. lightning_sdk/lightning_cloud/openapi/models/kubernetestemplates_id_body.py +201 -0
  134. lightning_sdk/lightning_cloud/openapi/models/license_key_validate_body.py +123 -0
  135. lightning_sdk/lightning_cloud/openapi/models/message_id_actions_body.py +201 -0
  136. lightning_sdk/lightning_cloud/openapi/models/messages_message_id_body.py +123 -0
  137. lightning_sdk/lightning_cloud/openapi/models/metricsstream_create_body.py +27 -1
  138. lightning_sdk/lightning_cloud/openapi/models/models_model_id_body.py +109 -31
  139. lightning_sdk/lightning_cloud/openapi/models/models_model_id_body1.py +149 -0
  140. lightning_sdk/lightning_cloud/openapi/models/orgs_id_body.py +53 -1
  141. lightning_sdk/lightning_cloud/openapi/models/project_id_storage_body.py +27 -1
  142. lightning_sdk/lightning_cloud/openapi/models/project_id_storagetransfers_body.py +175 -0
  143. lightning_sdk/lightning_cloud/openapi/models/project_tab_management_messages.py +123 -0
  144. lightning_sdk/lightning_cloud/openapi/models/projects_id_body.py +79 -1
  145. lightning_sdk/lightning_cloud/openapi/models/storage_complete_body.py +41 -15
  146. lightning_sdk/lightning_cloud/openapi/models/storagetransfers_validate_body.py +149 -0
  147. lightning_sdk/lightning_cloud/openapi/models/update1.py +27 -1
  148. lightning_sdk/lightning_cloud/openapi/models/uploads_upload_id_body1.py +27 -1
  149. lightning_sdk/lightning_cloud/openapi/models/user_id_affiliatelinks_body.py +107 -3
  150. lightning_sdk/lightning_cloud/openapi/models/v1_abort_storage_transfer_response.py +97 -0
  151. lightning_sdk/lightning_cloud/openapi/models/v1_aggregated_pod_metrics.py +799 -0
  152. lightning_sdk/lightning_cloud/openapi/models/v1_ai_pod_v1.py +53 -1
  153. lightning_sdk/lightning_cloud/openapi/models/v1_assistant_session_daily_aggregated.py +27 -1
  154. lightning_sdk/lightning_cloud/openapi/models/v1_billing_tier.py +0 -1
  155. lightning_sdk/lightning_cloud/openapi/models/v1_cancel_running_cloud_space_instance_transfer_response.py +97 -0
  156. lightning_sdk/lightning_cloud/openapi/models/v1_cloud_provider.py +2 -0
  157. lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_environment_template_config.py +27 -1
  158. lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_specialized_view.py +1 -0
  159. lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_transfer_metadata.py +147 -17
  160. lightning_sdk/lightning_cloud/openapi/models/v1_cloudflare_v1.py +3 -29
  161. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_accelerator.py +53 -1
  162. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_capacity_reservation.py +27 -1
  163. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_metrics.py +1527 -0
  164. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_security_options.py +27 -1
  165. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_spec.py +53 -1
  166. lightning_sdk/lightning_cloud/openapi/models/v1_cluster_type.py +1 -0
  167. lightning_sdk/lightning_cloud/openapi/models/v1_container_metrics.py +21 -21
  168. lightning_sdk/lightning_cloud/openapi/models/v1_create_incident_request.py +305 -0
  169. lightning_sdk/lightning_cloud/openapi/models/v1_create_license_request.py +175 -0
  170. lightning_sdk/lightning_cloud/openapi/models/v1_create_machine_response.py +123 -0
  171. lightning_sdk/lightning_cloud/openapi/models/v1_create_model_metrics_response.py +97 -0
  172. lightning_sdk/lightning_cloud/openapi/models/v1_create_project_request.py +79 -1
  173. lightning_sdk/lightning_cloud/openapi/models/v1_create_sdk_command_history_request.py +253 -0
  174. lightning_sdk/lightning_cloud/openapi/models/v1_create_sdk_command_history_response.py +97 -0
  175. lightning_sdk/lightning_cloud/openapi/models/v1_daily_model_metrics.py +149 -0
  176. lightning_sdk/lightning_cloud/openapi/models/v1_data_connection.py +53 -1
  177. lightning_sdk/lightning_cloud/openapi/models/v1_delete_incident_message_response.py +97 -0
  178. lightning_sdk/lightning_cloud/openapi/models/v1_delete_incident_response.py +97 -0
  179. lightning_sdk/lightning_cloud/openapi/models/v1_delete_kubernetes_template_response.py +97 -0
  180. lightning_sdk/lightning_cloud/openapi/models/v1_delete_license_response.py +97 -0
  181. lightning_sdk/lightning_cloud/openapi/models/v1_delete_machine_response.py +97 -0
  182. lightning_sdk/lightning_cloud/openapi/models/v1_deployment.py +27 -1
  183. lightning_sdk/lightning_cloud/openapi/models/v1_external_cluster_spec.py +53 -1
  184. lightning_sdk/lightning_cloud/openapi/models/v1_external_search_user.py +27 -1
  185. lightning_sdk/lightning_cloud/openapi/models/v1_filestore_data_connection.py +27 -1
  186. lightning_sdk/lightning_cloud/openapi/models/v1_filesystem_metric.py +201 -0
  187. lightning_sdk/lightning_cloud/openapi/models/v1_firewall_rule.py +175 -0
  188. lightning_sdk/lightning_cloud/openapi/models/v1_get_cloud_space_required_balance_status_response.py +149 -0
  189. lightning_sdk/lightning_cloud/openapi/models/v1_get_cloud_space_transfer_estimate_response.py +149 -0
  190. lightning_sdk/lightning_cloud/openapi/models/v1_get_latest_model_metrics_response.py +123 -0
  191. lightning_sdk/lightning_cloud/openapi/models/v1_get_machine_response.py +123 -0
  192. lightning_sdk/lightning_cloud/openapi/models/v1_get_market_pricing_response.py +201 -0
  193. lightning_sdk/lightning_cloud/openapi/models/v1_get_model_metrics_response.py +123 -0
  194. lightning_sdk/lightning_cloud/openapi/models/v1_get_temp_bucket_credentials_response.py +201 -0
  195. lightning_sdk/lightning_cloud/openapi/models/v1_get_user_response.py +41 -15
  196. lightning_sdk/lightning_cloud/openapi/models/v1_google_cloud_direct_v1.py +27 -1
  197. lightning_sdk/lightning_cloud/openapi/models/v1_group_node_metrics.py +1215 -0
  198. lightning_sdk/lightning_cloud/openapi/models/v1_group_pod_metrics.py +1241 -0
  199. lightning_sdk/lightning_cloud/openapi/models/v1_guest_login_request.py +177 -0
  200. lightning_sdk/lightning_cloud/openapi/models/v1_guest_login_response.py +149 -0
  201. lightning_sdk/lightning_cloud/openapi/models/v1_guest_user.py +201 -0
  202. lightning_sdk/lightning_cloud/openapi/models/v1_incident.py +565 -0
  203. lightning_sdk/lightning_cloud/openapi/models/v1_incident_detail.py +149 -0
  204. lightning_sdk/lightning_cloud/openapi/models/v1_incident_event.py +591 -0
  205. lightning_sdk/lightning_cloud/openapi/models/v1_incident_message.py +253 -0
  206. lightning_sdk/lightning_cloud/openapi/models/v1_incident_severity.py +105 -0
  207. lightning_sdk/lightning_cloud/openapi/models/v1_incident_type.py +108 -0
  208. lightning_sdk/lightning_cloud/openapi/models/v1_job.py +53 -1
  209. lightning_sdk/lightning_cloud/openapi/models/v1_job_spec.py +27 -1
  210. lightning_sdk/lightning_cloud/openapi/models/v1_k8s_incident_indexes.py +149 -0
  211. lightning_sdk/lightning_cloud/openapi/models/v1_kai_scheduler_queue_metrics.py +627 -0
  212. lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_aws_config.py +279 -0
  213. lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_direct_settings_v1.py +253 -0
  214. lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_direct_v1.py +107 -3
  215. lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_template.py +357 -0
  216. lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_template_property.py +227 -0
  217. lightning_sdk/lightning_cloud/openapi/models/v1_lambda_labs_direct_v1.py +29 -3
  218. lightning_sdk/lightning_cloud/openapi/models/v1_license.py +227 -0
  219. lightning_sdk/lightning_cloud/openapi/models/v1_lightning_elastic_cluster_v1.py +97 -0
  220. lightning_sdk/lightning_cloud/openapi/models/v1_list_aggregated_pod_metrics_response.py +123 -0
  221. lightning_sdk/lightning_cloud/openapi/models/v1_list_cluster_metric_timestamps_response.py +123 -0
  222. lightning_sdk/lightning_cloud/openapi/models/v1_list_cluster_metrics_response.py +123 -0
  223. lightning_sdk/lightning_cloud/openapi/models/v1_list_cluster_namespace_metrics_response.py +123 -0
  224. lightning_sdk/lightning_cloud/openapi/models/v1_list_cluster_namespace_user_metrics_response.py +123 -0
  225. lightning_sdk/lightning_cloud/openapi/models/v1_list_conversation_message_actions_response.py +123 -0
  226. lightning_sdk/lightning_cloud/openapi/models/v1_list_filesystem_metrics_response.py +123 -0
  227. lightning_sdk/lightning_cloud/openapi/models/v1_list_group_pod_metrics_response.py +123 -0
  228. lightning_sdk/lightning_cloud/openapi/models/v1_list_incident_events_response.py +123 -0
  229. lightning_sdk/lightning_cloud/openapi/models/v1_list_incident_messages_response.py +149 -0
  230. lightning_sdk/lightning_cloud/openapi/models/v1_list_incidents_response.py +149 -0
  231. lightning_sdk/lightning_cloud/openapi/models/v1_list_kai_scheduler_queues_metrics_response.py +123 -0
  232. lightning_sdk/lightning_cloud/openapi/models/v1_list_kubernetes_templates_response.py +123 -0
  233. lightning_sdk/lightning_cloud/openapi/models/{v1_list_product_licenses_response.py → v1_list_license_response.py} +16 -16
  234. lightning_sdk/lightning_cloud/openapi/models/v1_list_machines_response.py +149 -0
  235. lightning_sdk/lightning_cloud/openapi/models/v1_list_platform_notifications_response.py +123 -0
  236. lightning_sdk/lightning_cloud/openapi/models/v1_list_schedule_runs_response.py +123 -0
  237. lightning_sdk/lightning_cloud/openapi/models/v1_list_storage_transfers_response.py +123 -0
  238. lightning_sdk/lightning_cloud/openapi/models/v1_lustre_data_connection.py +149 -0
  239. lightning_sdk/lightning_cloud/openapi/models/v1_machine.py +617 -0
  240. lightning_sdk/lightning_cloud/openapi/models/v1_machine_direct_v1.py +123 -0
  241. lightning_sdk/lightning_cloud/openapi/models/v1_magic_link_login_request.py +1 -27
  242. lightning_sdk/lightning_cloud/openapi/models/v1_magic_link_login_response.py +27 -1
  243. lightning_sdk/lightning_cloud/openapi/models/v1_managed_model.py +29 -3
  244. lightning_sdk/lightning_cloud/openapi/models/v1_market_price.py +149 -0
  245. lightning_sdk/lightning_cloud/openapi/models/v1_membership.py +53 -1
  246. lightning_sdk/lightning_cloud/openapi/models/v1_message_action.py +279 -0
  247. lightning_sdk/lightning_cloud/openapi/models/v1_metrics_stream.py +27 -1
  248. lightning_sdk/lightning_cloud/openapi/models/v1_model_metrics.py +175 -0
  249. lightning_sdk/lightning_cloud/openapi/models/v1_namespace_metrics.py +591 -0
  250. lightning_sdk/lightning_cloud/openapi/models/v1_namespace_user_metrics.py +435 -0
  251. lightning_sdk/lightning_cloud/openapi/models/v1_nebius_direct_v1.py +29 -3
  252. lightning_sdk/lightning_cloud/openapi/models/v1_node_metrics.py +361 -23
  253. lightning_sdk/lightning_cloud/openapi/models/v1_notification_type.py +1 -0
  254. lightning_sdk/lightning_cloud/openapi/models/v1_organization.py +53 -1
  255. lightning_sdk/lightning_cloud/openapi/models/v1_pause_storage_transfer_response.py +97 -0
  256. lightning_sdk/lightning_cloud/openapi/models/v1_platform_notification.py +279 -0
  257. lightning_sdk/lightning_cloud/openapi/models/v1_pod_metrics.py +335 -23
  258. lightning_sdk/lightning_cloud/openapi/models/v1_project.py +27 -1
  259. lightning_sdk/lightning_cloud/openapi/models/v1_project_cluster_binding.py +27 -1
  260. lightning_sdk/lightning_cloud/openapi/models/v1_project_membership.py +53 -1
  261. lightning_sdk/lightning_cloud/openapi/models/v1_project_settings.py +53 -1
  262. lightning_sdk/lightning_cloud/openapi/models/v1_project_tab.py +149 -0
  263. lightning_sdk/lightning_cloud/openapi/models/{v1_product_license_check_response.py → v1_purchase_annual_upsell_request.py} +23 -23
  264. lightning_sdk/lightning_cloud/openapi/models/v1_purchase_annual_upsell_response.py +123 -0
  265. lightning_sdk/lightning_cloud/openapi/models/v1_quote_annual_upsell_response.py +227 -0
  266. lightning_sdk/lightning_cloud/openapi/models/v1_render_kubernetes_template_response.py +123 -0
  267. lightning_sdk/lightning_cloud/openapi/models/v1_report_deployment_routing_telemetry_response.py +97 -0
  268. lightning_sdk/lightning_cloud/openapi/models/v1_required_balance_reason.py +107 -0
  269. lightning_sdk/lightning_cloud/openapi/models/v1_reset_api_key_request.py +97 -0
  270. lightning_sdk/lightning_cloud/openapi/models/v1_reset_api_key_response.py +123 -0
  271. lightning_sdk/lightning_cloud/openapi/models/v1_resource_visibility.py +1 -27
  272. lightning_sdk/lightning_cloud/openapi/models/v1_resume_storage_transfer_response.py +97 -0
  273. lightning_sdk/lightning_cloud/openapi/models/v1_routing_telemetry.py +79 -1
  274. lightning_sdk/lightning_cloud/openapi/models/v1_rule_resource.py +1 -0
  275. lightning_sdk/lightning_cloud/openapi/models/v1_schedule_run.py +357 -0
  276. lightning_sdk/lightning_cloud/openapi/models/v1_sdk_command_history_severity.py +104 -0
  277. lightning_sdk/lightning_cloud/openapi/models/v1_sdk_command_history_type.py +104 -0
  278. lightning_sdk/lightning_cloud/openapi/models/v1_secret_type.py +1 -0
  279. lightning_sdk/lightning_cloud/openapi/models/v1_server_alert_type.py +1 -0
  280. lightning_sdk/lightning_cloud/openapi/models/v1_slack_notifier.py +201 -0
  281. lightning_sdk/lightning_cloud/openapi/models/v1_slack_notifier_type.py +105 -0
  282. lightning_sdk/lightning_cloud/openapi/models/v1_storage_asset.py +133 -3
  283. lightning_sdk/lightning_cloud/openapi/models/v1_storage_transfer.py +435 -0
  284. lightning_sdk/lightning_cloud/openapi/models/v1_storage_transfer_status.py +108 -0
  285. lightning_sdk/lightning_cloud/openapi/models/v1_token_login_request.py +123 -0
  286. lightning_sdk/lightning_cloud/openapi/models/v1_token_login_response.py +123 -0
  287. lightning_sdk/lightning_cloud/openapi/models/v1_token_owner_type.py +104 -0
  288. lightning_sdk/lightning_cloud/openapi/models/v1_update_cloud_space_instance_config_request.py +3 -81
  289. lightning_sdk/lightning_cloud/openapi/models/v1_update_project_tab_order_response.py +123 -0
  290. lightning_sdk/lightning_cloud/openapi/models/v1_update_user_request.py +41 -15
  291. lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +444 -600
  292. lightning_sdk/lightning_cloud/openapi/models/v1_validate_license_response.py +123 -0
  293. lightning_sdk/lightning_cloud/openapi/models/v1_validate_storage_transfer_response.py +123 -0
  294. lightning_sdk/lightning_cloud/openapi/models/v1_voltage_park_direct_v1.py +29 -3
  295. lightning_sdk/lightning_cloud/rest_client.py +48 -45
  296. lightning_sdk/lightning_cloud/utils/data_connection.py +51 -1
  297. lightning_sdk/llm/llm.py +175 -56
  298. lightning_sdk/llm/public_assistants.py +44 -7
  299. lightning_sdk/machine.py +21 -2
  300. lightning_sdk/mmt/base.py +7 -0
  301. lightning_sdk/mmt/mmt.py +11 -3
  302. lightning_sdk/mmt/v1.py +3 -1
  303. lightning_sdk/mmt/v2.py +4 -0
  304. lightning_sdk/owner.py +2 -1
  305. lightning_sdk/pipeline/steps.py +6 -0
  306. lightning_sdk/plugin.py +6 -1
  307. lightning_sdk/studio.py +294 -53
  308. lightning_sdk/teamspace.py +167 -7
  309. lightning_sdk/user.py +19 -1
  310. lightning_sdk/utils/config.py +179 -0
  311. lightning_sdk/utils/license.py +13 -0
  312. lightning_sdk/utils/logging.py +79 -0
  313. lightning_sdk/utils/names.py +1179 -0
  314. lightning_sdk/utils/progress.py +283 -0
  315. lightning_sdk/utils/resolve.py +82 -7
  316. {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/METADATA +2 -1
  317. {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/RECORD +328 -169
  318. {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/entry_points.txt +1 -0
  319. lightning_sdk/lightning_cloud/openapi/models/v1_product_license.py +0 -435
  320. lightning_sdk/services/license.py +0 -363
  321. /lightning_sdk/cli/{deploy → legacy}/__init__.py +0 -0
  322. /lightning_sdk/cli/{ai_hub.py → legacy/ai_hub.py} +0 -0
  323. /lightning_sdk/cli/{docker_cli.py → legacy/docker_cli.py} +0 -0
  324. /lightning_sdk/cli/{exceptions.py → legacy/exceptions.py} +0 -0
  325. /lightning_sdk/cli/{run.py → legacy/run.py} +0 -0
  326. /lightning_sdk/cli/{studios_menu.py → legacy/studios_menu.py} +0 -0
  327. /lightning_sdk/cli/{coloring.py → utils/coloring.py} +0 -0
  328. {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/LICENSE +0 -0
  329. {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/WHEEL +0 -0
  330. {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,110 @@
1
+ import sys
2
+ import traceback
3
+ from types import TracebackType
4
+ from typing import Type
5
+
6
+ import click
7
+ from rich.console import Console, Group
8
+ from rich.panel import Panel
9
+ from rich.syntax import Syntax
10
+ from rich.text import Text
11
+
12
+ from lightning_sdk import __version__
13
+ from lightning_sdk.api.studio_api import _cloud_url
14
+ from lightning_sdk.cli.legacy.ai_hub import aihub
15
+ from lightning_sdk.cli.legacy.coloring import CustomHelpFormatter
16
+ from lightning_sdk.cli.legacy.configure import configure
17
+ from lightning_sdk.cli.legacy.connect import connect
18
+ from lightning_sdk.cli.legacy.create import create
19
+ from lightning_sdk.cli.legacy.delete import delete
20
+ from lightning_sdk.cli.legacy.deploy.serve import deploy
21
+ from lightning_sdk.cli.legacy.docker_cli import dockerize
22
+ from lightning_sdk.cli.legacy.download import download
23
+ from lightning_sdk.cli.legacy.generate import generate
24
+ from lightning_sdk.cli.legacy.inspection import inspect
25
+ from lightning_sdk.cli.legacy.list import list_cli
26
+ from lightning_sdk.cli.legacy.open import open
27
+ from lightning_sdk.cli.legacy.run import run
28
+ from lightning_sdk.cli.legacy.start import start
29
+ from lightning_sdk.cli.legacy.stop import stop
30
+ from lightning_sdk.cli.legacy.switch import switch
31
+ from lightning_sdk.cli.legacy.upload import upload
32
+ from lightning_sdk.constants import _LIGHTNING_DEBUG
33
+ from lightning_sdk.lightning_cloud.login import Auth
34
+
35
+
36
+ def _notify_exception(exception_type: Type[BaseException], value: BaseException, tb: TracebackType) -> None:
37
+ """CLI won't show tracebacks, just print the exception message."""
38
+ console = Console()
39
+
40
+ message = str(value.args[0]) if value.args else str(value) or "An unknown error occurred"
41
+
42
+ error_text = Text()
43
+ error_text.append(f"{exception_type.__name__}: ", style="bold red")
44
+ error_text.append(message, style="white")
45
+
46
+ renderables = [error_text]
47
+
48
+ if _LIGHTNING_DEBUG:
49
+ tb_text = "".join(traceback.format_exception(exception_type, value, tb))
50
+ renderables.append(Text("\n\nFull traceback:\n", style="bold yellow"))
51
+ renderables.append(Syntax(tb_text, "python", theme="monokai light", line_numbers=False, word_wrap=True))
52
+ else:
53
+ renderables.append(Text("\n\n🐞 To view the full traceback, set: LIGHTNING_DEBUG=1"))
54
+
55
+ renderables.append(Text("\n📘 Need help? Run: lightning <command> --help", style="cyan"))
56
+
57
+ console.print(Panel(Group(*renderables), title="⚡ Lightning CLI Error", border_style="red"))
58
+
59
+
60
+ @click.group(name="lightning", help="Command line interface (CLI) to interact with/manage Lightning AI Studios.")
61
+ @click.version_option(__version__, message="Lightning CLI version %(version)s")
62
+ def main_cli() -> None:
63
+ sys.excepthook = _notify_exception
64
+
65
+
66
+ # colorful help messages
67
+ main_cli.context_class.formatter_class = CustomHelpFormatter
68
+
69
+
70
+ @main_cli.command
71
+ def login() -> None:
72
+ """Login to Lightning AI Studios."""
73
+ auth = Auth()
74
+ auth.clear()
75
+
76
+ try:
77
+ auth.authenticate()
78
+ except ConnectionError:
79
+ raise RuntimeError(f"Unable to connect to {_cloud_url()}. Please check your internet connection.") from None
80
+
81
+
82
+ @main_cli.command
83
+ def logout() -> None:
84
+ """Logout from Lightning AI Studios."""
85
+ auth = Auth()
86
+ auth.clear()
87
+
88
+
89
+ # additional commands
90
+ main_cli.add_command(aihub)
91
+ main_cli.add_command(configure)
92
+ main_cli.add_command(connect)
93
+ main_cli.add_command(create)
94
+ main_cli.add_command(delete)
95
+ main_cli.add_command(dockerize)
96
+ main_cli.add_command(download)
97
+ main_cli.add_command(generate)
98
+ main_cli.add_command(inspect)
99
+ main_cli.add_command(list_cli)
100
+ main_cli.add_command(run)
101
+ main_cli.add_command(deploy)
102
+ main_cli.add_command(start)
103
+ main_cli.add_command(stop)
104
+ main_cli.add_command(switch)
105
+ main_cli.add_command(upload)
106
+ main_cli.add_command(open)
107
+
108
+
109
+ if __name__ == "__main__":
110
+ main_cli()
@@ -3,7 +3,7 @@ from typing import Optional
3
3
  import click
4
4
  from rich.console import Console
5
5
 
6
- from lightning_sdk.cli.studios_menu import _StudiosMenu
6
+ from lightning_sdk.cli.legacy.studios_menu import _StudiosMenu
7
7
 
8
8
 
9
9
  @click.group(name="generate")
@@ -3,7 +3,7 @@ from typing import Optional
3
3
  import click
4
4
  from rich.console import Console
5
5
 
6
- from lightning_sdk.cli.job_and_mmt_action import _JobAndMMTAction
6
+ from lightning_sdk.cli.legacy.job_and_mmt_action import _JobAndMMTAction
7
7
 
8
8
 
9
9
  @click.group(name="inspect")
@@ -1,13 +1,13 @@
1
1
  from typing import Optional
2
2
 
3
- from lightning_sdk.cli.jobs_menu import _JobsMenu
4
- from lightning_sdk.cli.mmts_menu import _MMTsMenu
5
- from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
3
+ from lightning_sdk.cli.legacy.jobs_menu import _JobsMenu
4
+ from lightning_sdk.cli.legacy.mmts_menu import _MMTsMenu
5
+ from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
6
6
  from lightning_sdk.job import Job
7
7
  from lightning_sdk.mmt import MMT
8
8
 
9
9
 
10
- class _JobAndMMTAction(_TeamspacesMenu, _JobsMenu, _MMTsMenu):
10
+ class _JobAndMMTAction(TeamspacesMenu, _JobsMenu, _MMTsMenu):
11
11
  """Inspect resources of the Lightning AI platform to get additional details as JSON."""
12
12
 
13
13
  def job(self, name: Optional[str] = None, teamspace: Optional[str] = None) -> Job:
@@ -20,7 +20,7 @@ class _JobAndMMTAction(_TeamspacesMenu, _JobsMenu, _MMTsMenu):
20
20
  If not specified can be selected interactively.
21
21
 
22
22
  """
23
- resolved_teamspace = self._resolve_teamspace(teamspace)
23
+ resolved_teamspace = self(teamspace)
24
24
  return self._resolve_job(name, teamspace=resolved_teamspace)
25
25
 
26
26
  def mmt(self, name: Optional[str] = None, teamspace: Optional[str] = None) -> MMT:
@@ -33,5 +33,5 @@ class _JobAndMMTAction(_TeamspacesMenu, _JobsMenu, _MMTsMenu):
33
33
  If not specified can be selected interactively.
34
34
 
35
35
  """
36
- resolved_teamspace = self._resolve_teamspace(teamspace)
36
+ resolved_teamspace = self(teamspace)
37
37
  return self._resolve_mmt(name, teamspace=resolved_teamspace)
@@ -3,7 +3,7 @@ from typing import Dict, List, Optional
3
3
  from rich.console import Console
4
4
  from simple_term_menu import TerminalMenu
5
5
 
6
- from lightning_sdk.cli.exceptions import StudioCliError
6
+ from lightning_sdk.cli.legacy.exceptions import StudioCliError
7
7
  from lightning_sdk.job import Job
8
8
  from lightning_sdk.teamspace import Teamspace
9
9
 
@@ -7,9 +7,9 @@ from rich.table import Table
7
7
  from typing_extensions import Literal
8
8
 
9
9
  from lightning_sdk import Job, Machine, Studio, Teamspace
10
- from lightning_sdk.cli.clusters_menu import _ClustersMenu
11
- from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
12
- from lightning_sdk.lightning_cloud.openapi import V1ClusterType, V1MultiMachineJob
10
+ from lightning_sdk.cli.legacy.clusters_menu import _ClustersMenu
11
+ from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
12
+ from lightning_sdk.lightning_cloud.openapi import V1MultiMachineJob
13
13
  from lightning_sdk.lit_container import LitContainer
14
14
  from lightning_sdk.utils.resolve import _get_authed_user
15
15
 
@@ -48,7 +48,7 @@ def studios(
48
48
  ) -> None:
49
49
  """List studios for a given teamspace."""
50
50
  studios = []
51
- menu = _TeamspacesMenu()
51
+ menu = TeamspacesMenu()
52
52
  if all and not teamspace:
53
53
  user = _get_authed_user()
54
54
  possible_teamspaces = menu._get_possible_teamspaces(user)
@@ -56,7 +56,7 @@ def studios(
56
56
  teamspace = Teamspace(**ts)
57
57
  studios.extend(teamspace.studios)
58
58
  else:
59
- resolved_teamspace = menu._resolve_teamspace(teamspace=teamspace)
59
+ resolved_teamspace = menu(teamspace=teamspace)
60
60
  studios = resolved_teamspace.studios
61
61
 
62
62
  table = Table(
@@ -111,7 +111,7 @@ def jobs(
111
111
  ) -> None:
112
112
  """List jobs for a given teamspace."""
113
113
  jobs = []
114
- menu = _TeamspacesMenu()
114
+ menu = TeamspacesMenu()
115
115
  if all and not teamspace:
116
116
  user = _get_authed_user()
117
117
  possible_teamspaces = menu._get_possible_teamspaces(user)
@@ -119,7 +119,7 @@ def jobs(
119
119
  teamspace = Teamspace(**ts)
120
120
  jobs.extend(teamspace.jobs)
121
121
  else:
122
- resolved_teamspace = menu._resolve_teamspace(teamspace=teamspace)
122
+ resolved_teamspace = menu(teamspace=teamspace)
123
123
  jobs = resolved_teamspace.jobs
124
124
 
125
125
  table = Table(pad_edge=True)
@@ -182,7 +182,7 @@ def mmts(
182
182
  ) -> None:
183
183
  """List multi-machine jobs for a given teamspace."""
184
184
  jobs = []
185
- menu = _TeamspacesMenu()
185
+ menu = TeamspacesMenu()
186
186
  if all and not teamspace:
187
187
  user = _get_authed_user()
188
188
  possible_teamspaces = menu._get_possible_teamspaces(user)
@@ -190,7 +190,7 @@ def mmts(
190
190
  teamspace = Teamspace(**ts)
191
191
  jobs.extend(teamspace.multi_machine_jobs)
192
192
  else:
193
- resolved_teamspace = menu._resolve_teamspace(teamspace=teamspace)
193
+ resolved_teamspace = menu(teamspace=teamspace)
194
194
  jobs = resolved_teamspace.multi_machine_jobs
195
195
 
196
196
  table = Table(pad_edge=True)
@@ -242,13 +242,12 @@ def mmts(
242
242
  def containers(teamspace: Optional[str] = None, cloud_account: Optional[str] = None) -> None:
243
243
  """Display the list of available containers."""
244
244
  api = LitContainer()
245
- menu = _TeamspacesMenu()
245
+ menu = TeamspacesMenu()
246
246
  clusters_menu = _ClustersMenu()
247
- resolved_teamspace = menu._resolve_teamspace(teamspace=teamspace)
247
+ resolved_teamspace = menu(teamspace=teamspace)
248
248
 
249
249
  if not cloud_account:
250
- cloud_account_obj = clusters_menu._resolve_cluster(resolved_teamspace)
251
- cloud_account = "" if cloud_account_obj.spec.cluster_type == V1ClusterType.GLOBAL else cloud_account_obj.id
250
+ cloud_account = clusters_menu._resolve_cluster(resolved_teamspace)
252
251
 
253
252
  result = api.list_containers(
254
253
  teamspace=resolved_teamspace.name, org=resolved_teamspace.owner.name, cloud_account=cloud_account
@@ -3,7 +3,7 @@ from typing import Dict, List, Optional
3
3
  from rich.console import Console
4
4
  from simple_term_menu import TerminalMenu
5
5
 
6
- from lightning_sdk.cli.exceptions import StudioCliError
6
+ from lightning_sdk.cli.legacy.exceptions import StudioCliError
7
7
  from lightning_sdk.mmt import MMT
8
8
  from lightning_sdk.teamspace import Teamspace
9
9
 
@@ -6,8 +6,8 @@ from typing import Optional
6
6
  import click
7
7
  from rich.console import Console
8
8
 
9
- from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
10
- from lightning_sdk.cli.upload import _upload_folder
9
+ from lightning_sdk.cli.legacy.upload import _upload_folder
10
+ from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
11
11
  from lightning_sdk.studio import Studio
12
12
  from lightning_sdk.teamspace import Teamspace
13
13
  from lightning_sdk.utils.resolve import _get_studio_url
@@ -49,8 +49,8 @@ def open(path: str = ".", teamspace: Optional[str] = None, cloud_account: Option
49
49
  try:
50
50
  resolved_teamspace = Teamspace()
51
51
  except ValueError:
52
- menu = _TeamspacesMenu()
53
- resolved_teamspace = menu._resolve_teamspace(teamspace=teamspace)
52
+ menu = TeamspacesMenu()
53
+ resolved_teamspace = menu(teamspace=teamspace)
54
54
 
55
55
  # default cloud account to current studios cloud account if run from studio
56
56
  # else it will fall back to teamspace default in the backend
@@ -103,4 +103,5 @@ def studio(
103
103
  except KeyError:
104
104
  resolved_machine = machine
105
105
 
106
+ Studio.show_progress = True
106
107
  studio.start(resolved_machine)
@@ -3,7 +3,7 @@ from typing import Optional
3
3
  import click
4
4
  from rich.console import Console
5
5
 
6
- from lightning_sdk.cli.job_and_mmt_action import _JobAndMMTAction
6
+ from lightning_sdk.cli.legacy.job_and_mmt_action import _JobAndMMTAction
7
7
  from lightning_sdk.lightning_cloud.openapi.rest import ApiException
8
8
  from lightning_sdk.studio import Studio
9
9
 
@@ -59,4 +59,5 @@ def studio(name: str, teamspace: Optional[str] = None, machine: str = "CPU") ->
59
59
  except KeyError:
60
60
  resolved_machine = machine
61
61
 
62
+ Studio.show_progress = True
62
63
  studio.switch_machine(resolved_machine)
@@ -4,7 +4,7 @@ from rich.console import Console
4
4
  from simple_term_menu import TerminalMenu
5
5
 
6
6
  from lightning_sdk.api import OrgApi
7
- from lightning_sdk.cli.exceptions import StudioCliError
7
+ from lightning_sdk.cli.legacy.exceptions import StudioCliError
8
8
  from lightning_sdk.teamspace import Teamspace
9
9
  from lightning_sdk.user import User
10
10
  from lightning_sdk.utils.resolve import _get_authed_user
@@ -14,13 +14,13 @@ from tqdm import tqdm
14
14
 
15
15
  from lightning_sdk.api.lit_container_api import DockerNotRunningError, LCRAuthFailedError, LitContainerApi
16
16
  from lightning_sdk.api.utils import _get_cloud_url
17
- from lightning_sdk.cli.exceptions import StudioCliError
18
- from lightning_sdk.cli.studios_menu import _StudiosMenu
19
- from lightning_sdk.cli.teamspace_menu import _TeamspacesMenu
17
+ from lightning_sdk.cli.legacy.exceptions import StudioCliError
18
+ from lightning_sdk.cli.legacy.studios_menu import _StudiosMenu
19
+ from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
20
20
  from lightning_sdk.constants import _LIGHTNING_DEBUG
21
21
  from lightning_sdk.models import upload_model as _upload_model
22
22
  from lightning_sdk.studio import Studio
23
- from lightning_sdk.utils.resolve import _get_authed_user, skip_studio_init
23
+ from lightning_sdk.utils.resolve import _get_authed_user
24
24
 
25
25
  _STUDIO_UPLOAD_STATUS_PATH = "~/.lightning/studios/uploads"
26
26
 
@@ -137,8 +137,8 @@ def upload_container(
137
137
  platform: Optional[str] = "linux/amd64",
138
138
  ) -> None:
139
139
  """Upload a container to Lightning AI's container registry."""
140
- menu = _TeamspacesMenu()
141
- teamspace = menu._resolve_teamspace(teamspace)
140
+ menu = TeamspacesMenu()
141
+ teamspace = menu(teamspace)
142
142
  console = Console()
143
143
  with Progress(
144
144
  SpinnerColumn(),
@@ -285,8 +285,7 @@ def _resolve_studio(studio: Optional[str]) -> Studio:
285
285
  "Please contact Lightning AI directly to resolve this issue."
286
286
  ) from e
287
287
 
288
- with skip_studio_init():
289
- return Studio(**selected_studio)
288
+ return Studio(**selected_studio)
290
289
 
291
290
 
292
291
  def _print_docker_push(lines: Generator, console: Console, progress: Progress, push_task: rich.progress.TaskID) -> None:
@@ -0,0 +1,14 @@
1
+ """Base Studio CLI commands."""
2
+
3
+ import click
4
+
5
+
6
+ def register_commands(group: click.Group) -> None:
7
+ """Register base studio commands with the given group."""
8
+ from lightning_sdk.cli.license.get import get_license
9
+ from lightning_sdk.cli.license.list import list_licenses
10
+ from lightning_sdk.cli.license.set import set_license
11
+
12
+ group.add_command(list_licenses)
13
+ group.add_command(get_license)
14
+ group.add_command(set_license)
@@ -0,0 +1,15 @@
1
+ import click
2
+
3
+ from lightning_sdk.utils.config import _DEFAULT_CONFIG_FILE_PATH, Config, DefaultConfigKeys
4
+
5
+
6
+ @click.command("get")
7
+ @click.argument("product_name")
8
+ @click.option("--config-file", help="Path to the config file")
9
+ def get_license(product_name: str, config_file: str = _DEFAULT_CONFIG_FILE_PATH) -> None:
10
+ """Get a license key for a given product."""
11
+ cfg = Config(config_file)
12
+ license_key = cfg.get(f"{DefaultConfigKeys.license}.{product_name}")
13
+ if license_key:
14
+ # echo the license key without any additional output to make parsing simpler
15
+ click.echo(license_key)
@@ -0,0 +1,45 @@
1
+ """License list command."""
2
+
3
+ from typing import Mapping
4
+
5
+ import click
6
+ from rich.table import Table
7
+
8
+ from lightning_sdk.cli.utils.richt_print import rich_to_str
9
+ from lightning_sdk.utils.config import _DEFAULT_CONFIG_FILE_PATH, Config, DefaultConfigKeys
10
+
11
+
12
+ @click.command("list")
13
+ @click.option("--include-key", help="Print the key as well", is_flag=True)
14
+ @click.option("--config-file", help="Path to the config file")
15
+ def list_licenses(include_key: bool, config_file: str = _DEFAULT_CONFIG_FILE_PATH) -> None:
16
+ """List configured licenses.
17
+
18
+ Example:
19
+ lightning license list --include-key
20
+
21
+ """
22
+ return list_impl(include_key=include_key, config_path=config_file)
23
+
24
+
25
+ def list_impl(include_key: bool, config_path: str) -> None:
26
+ cfg = Config(config_file=config_path)
27
+
28
+ license_cfg = cfg.get_sub_config(DefaultConfigKeys.license)
29
+
30
+ if isinstance(license_cfg, Mapping):
31
+ table = Table(
32
+ pad_edge=True,
33
+ )
34
+
35
+ table.add_column("Product")
36
+ table.add_column("License Key")
37
+
38
+ # sort by product_name
39
+ for product_name, license_key in sorted(license_cfg.items(), key=lambda x: x[0]):
40
+ table.add_row(product_name, license_key if include_key else "********")
41
+
42
+ click.echo(rich_to_str(table), color=True)
43
+
44
+ else:
45
+ click.echo("No licenses configured!")
@@ -0,0 +1,13 @@
1
+ import click
2
+
3
+ from lightning_sdk.utils.config import _DEFAULT_CONFIG_FILE_PATH, Config, DefaultConfigKeys
4
+
5
+
6
+ @click.command("set")
7
+ @click.argument("product_name")
8
+ @click.argument("license_key")
9
+ @click.option("--config-file", help="Path to the config file")
10
+ def set_license(product_name: str, license_key: str, config_file: str = _DEFAULT_CONFIG_FILE_PATH) -> None:
11
+ """Set a license key for a given product."""
12
+ cfg = Config(config_file)
13
+ cfg.set(f"{DefaultConfigKeys.license}.{product_name}", license_key)
@@ -0,0 +1,7 @@
1
+ """MMT CLI commands."""
2
+
3
+ import click
4
+
5
+
6
+ def register_commands(group: click.Group) -> None:
7
+ """Register MMT commands with the given group."""
@@ -0,0 +1,24 @@
1
+ """Studio CLI commands."""
2
+
3
+ import click
4
+
5
+
6
+ def register_commands(group: click.Group) -> None:
7
+ """Register studio commands with the given group."""
8
+ from lightning_sdk.cli.studio.connect import connect_studio
9
+ from lightning_sdk.cli.studio.create import create_studio
10
+ from lightning_sdk.cli.studio.delete import delete_studio
11
+ from lightning_sdk.cli.studio.list import list_studios
12
+ from lightning_sdk.cli.studio.ssh import ssh_studio
13
+ from lightning_sdk.cli.studio.start import start_studio
14
+ from lightning_sdk.cli.studio.stop import stop_studio
15
+ from lightning_sdk.cli.studio.switch import switch_studio
16
+
17
+ group.add_command(delete_studio)
18
+ group.add_command(create_studio)
19
+ group.add_command(list_studios)
20
+ group.add_command(ssh_studio)
21
+ group.add_command(start_studio)
22
+ group.add_command(stop_studio)
23
+ group.add_command(switch_studio)
24
+ group.add_command(connect_studio)
@@ -0,0 +1,139 @@
1
+ """Studio connect command."""
2
+
3
+ import subprocess
4
+ import sys
5
+ from contextlib import suppress
6
+ from typing import Optional
7
+
8
+ import click
9
+
10
+ from lightning_sdk.cli.utils.get_base_studio import get_base_studio_id
11
+ from lightning_sdk.cli.utils.handle_machine_and_gpus_args import handle_machine_and_gpus_args
12
+ from lightning_sdk.cli.utils.richt_print import studio_name_link
13
+ from lightning_sdk.cli.utils.save_to_config import save_studio_to_config, save_teamspace_to_config
14
+ from lightning_sdk.cli.utils.ssh_connection import configure_ssh_internal
15
+ from lightning_sdk.cli.utils.teamspace_selection import TeamspacesMenu
16
+ from lightning_sdk.lightning_cloud.openapi.rest import ApiException
17
+ from lightning_sdk.machine import CloudProvider, Machine
18
+ from lightning_sdk.studio import Studio
19
+ from lightning_sdk.utils.names import random_unique_name
20
+
21
+
22
+ def _parse_args_or_get_from_current_studio(
23
+ teamspace: Optional[str],
24
+ cloud_account: Optional[str],
25
+ studio_type: Optional[str],
26
+ machine: Optional[str],
27
+ gpus: Optional[str],
28
+ cloud_provider: Optional[str],
29
+ name: Optional[str],
30
+ ) -> tuple[Optional[str], Optional[str], Optional[str], Optional[str]]:
31
+ # Parse args provided by user
32
+ menu = TeamspacesMenu()
33
+ resolved_teamspace = menu(teamspace)
34
+ save_teamspace_to_config(resolved_teamspace, overwrite=False)
35
+
36
+ template_id = get_base_studio_id(studio_type)
37
+
38
+ if cloud_provider is not None:
39
+ cloud_provider = CloudProvider(cloud_provider)
40
+
41
+ name = name or random_unique_name()
42
+
43
+ with suppress(ValueError):
44
+ # Gets current studio context to use its parameters as defaults
45
+ s = Studio()
46
+ if not teamspace:
47
+ resolved_teamspace = s.teamspace
48
+ save_teamspace_to_config(resolved_teamspace, overwrite=False)
49
+ if not cloud_account:
50
+ cloud_account = s.cloud_account
51
+ if not template_id:
52
+ template_id = s._studio.environment_template_id
53
+ if not machine and not gpus:
54
+ machine = s.machine
55
+
56
+ return resolved_teamspace, cloud_account, template_id, machine, cloud_provider, name
57
+
58
+
59
+ @click.command("connect")
60
+ @click.argument("name", required=False)
61
+ @click.option("--teamspace", help="Override default teamspace (format: owner/teamspace)")
62
+ @click.option(
63
+ "--cloud-provider",
64
+ help="The cloud provider to start the studio on. Defaults to teamspace default.",
65
+ type=click.Choice(m.name for m in list(CloudProvider)),
66
+ )
67
+ @click.option(
68
+ "--cloud-account",
69
+ help="The cloud account to create the studio on. Defaults to teamspace default.",
70
+ type=click.STRING,
71
+ )
72
+ @click.option(
73
+ "--machine",
74
+ help="The machine type to start the studio on. Defaults to CPU-4",
75
+ type=click.Choice(m.name for m in Machine.__dict__.values() if isinstance(m, Machine) and m._include_in_cli),
76
+ )
77
+ @click.option(
78
+ "--gpus",
79
+ help="The number and type of GPUs to start the studio on (format: TYPE:COUNT, e.g. L4:4)",
80
+ type=click.STRING,
81
+ )
82
+ @click.option(
83
+ "--studio-type",
84
+ help="The base studio template name to use for creating the studio. "
85
+ "Must be lowercase and hyphenated (use '-' instead of spaces). "
86
+ "Run 'lightning base-studio list' to see all available templates. "
87
+ "Defaults to the first available template.",
88
+ type=click.STRING,
89
+ )
90
+ @click.option("--interruptible", is_flag=True, help="Start the studio on an interruptible instance.")
91
+ def connect_studio(
92
+ name: Optional[str] = None,
93
+ teamspace: Optional[str] = None,
94
+ cloud_provider: Optional[str] = None,
95
+ cloud_account: Optional[str] = None,
96
+ machine: Optional[str] = None,
97
+ gpus: Optional[str] = None,
98
+ studio_type: Optional[str] = None,
99
+ interruptible: bool = False,
100
+ ) -> None:
101
+ """Connect to a Studio.
102
+
103
+ Example:
104
+ lightning studio connect
105
+ """
106
+ teamspace, cloud_account, template_id, machine, cloud_provider, name = _parse_args_or_get_from_current_studio(
107
+ teamspace, cloud_account, studio_type, machine, gpus, cloud_provider, name
108
+ )
109
+
110
+ try:
111
+ studio = Studio(
112
+ name=name,
113
+ teamspace=teamspace,
114
+ create_ok=True,
115
+ cloud_provider=cloud_provider,
116
+ cloud_account=cloud_account,
117
+ studio_type=template_id,
118
+ )
119
+ except (RuntimeError, ValueError, ApiException):
120
+ raise ValueError(f"Could not create Studio: '{name}'") from None
121
+
122
+ click.echo(f"Connecting to Studio '{studio_name_link(studio)}' ...")
123
+
124
+ Studio.show_progress = True
125
+
126
+ machine = handle_machine_and_gpus_args(machine, gpus)
127
+
128
+ save_studio_to_config(studio)
129
+ studio.start(machine=machine, interruptible=interruptible)
130
+
131
+ ssh_private_key_path = configure_ssh_internal()
132
+
133
+ ssh_option = "-o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o LogLevel=ERROR"
134
+ try:
135
+ ssh_command = f"ssh -i {ssh_private_key_path} {ssh_option} s_{studio._studio.id}@ssh.lightning.ai"
136
+ subprocess.run(ssh_command.split())
137
+ except Exception as ex:
138
+ print(f"Failed to establish SSH connection: {ex}")
139
+ sys.exit(1)