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.
- lightning_sdk/__init__.py +13 -7
- lightning_sdk/__version__.py +3 -0
- lightning_sdk/agents.py +2 -1
- lightning_sdk/ai_hub.py +2 -1
- lightning_sdk/api/__init__.py +2 -0
- lightning_sdk/api/base_studio_api.py +13 -9
- lightning_sdk/api/cloud_account_api.py +31 -10
- lightning_sdk/api/deployment_api.py +27 -1
- lightning_sdk/api/job_api.py +16 -12
- lightning_sdk/api/license_api.py +26 -59
- lightning_sdk/api/llm_api.py +25 -2
- lightning_sdk/api/mmt_api.py +5 -2
- lightning_sdk/api/studio_api.py +252 -55
- lightning_sdk/api/teamspace_api.py +106 -30
- lightning_sdk/api/user_api.py +56 -2
- lightning_sdk/api/utils.py +108 -18
- lightning_sdk/base_studio.py +51 -27
- lightning_sdk/cli/__init__.py +1 -0
- lightning_sdk/cli/base_studio/__init__.py +10 -0
- lightning_sdk/cli/base_studio/list.py +43 -0
- lightning_sdk/cli/config/__init__.py +14 -0
- lightning_sdk/cli/config/get.py +57 -0
- lightning_sdk/cli/config/set.py +92 -0
- lightning_sdk/cli/config/show.py +9 -0
- lightning_sdk/cli/entrypoint.py +71 -71
- lightning_sdk/cli/groups.py +56 -0
- lightning_sdk/cli/job/__init__.py +7 -0
- lightning_sdk/cli/{clusters_menu.py → legacy/clusters_menu.py} +9 -6
- lightning_sdk/cli/{configure.py → legacy/configure.py} +2 -2
- lightning_sdk/cli/{connect.py → legacy/connect.py} +2 -2
- lightning_sdk/cli/{create.py → legacy/create.py} +12 -14
- lightning_sdk/cli/{delete.py → legacy/delete.py} +5 -5
- lightning_sdk/cli/legacy/deploy/__init__.py +0 -0
- lightning_sdk/cli/{deploy → legacy/deploy}/_auth.py +5 -6
- lightning_sdk/cli/{deploy → legacy/deploy}/devbox.py +8 -2
- lightning_sdk/cli/{deploy → legacy/deploy}/serve.py +19 -8
- lightning_sdk/cli/{download.py → legacy/download.py} +14 -15
- lightning_sdk/cli/legacy/entrypoint.py +110 -0
- lightning_sdk/cli/{generate.py → legacy/generate.py} +1 -1
- lightning_sdk/cli/{inspection.py → legacy/inspection.py} +1 -1
- lightning_sdk/cli/{job_and_mmt_action.py → legacy/job_and_mmt_action.py} +6 -6
- lightning_sdk/cli/{jobs_menu.py → legacy/jobs_menu.py} +1 -1
- lightning_sdk/cli/{list.py → legacy/list.py} +12 -13
- lightning_sdk/cli/{mmts_menu.py → legacy/mmts_menu.py} +1 -1
- lightning_sdk/cli/{open.py → legacy/open.py} +4 -4
- lightning_sdk/cli/{start.py → legacy/start.py} +1 -0
- lightning_sdk/cli/{stop.py → legacy/stop.py} +1 -1
- lightning_sdk/cli/{switch.py → legacy/switch.py} +1 -0
- lightning_sdk/cli/{teamspace_menu.py → legacy/teamspace_menu.py} +1 -1
- lightning_sdk/cli/{upload.py → legacy/upload.py} +7 -8
- lightning_sdk/cli/license/__init__.py +14 -0
- lightning_sdk/cli/license/get.py +15 -0
- lightning_sdk/cli/license/list.py +45 -0
- lightning_sdk/cli/license/set.py +13 -0
- lightning_sdk/cli/mmt/__init__.py +7 -0
- lightning_sdk/cli/studio/__init__.py +24 -0
- lightning_sdk/cli/studio/connect.py +139 -0
- lightning_sdk/cli/studio/create.py +96 -0
- lightning_sdk/cli/studio/delete.py +49 -0
- lightning_sdk/cli/studio/list.py +85 -0
- lightning_sdk/cli/studio/ssh.py +64 -0
- lightning_sdk/cli/studio/start.py +115 -0
- lightning_sdk/cli/studio/stop.py +45 -0
- lightning_sdk/cli/studio/switch.py +66 -0
- lightning_sdk/cli/utils/__init__.py +7 -0
- lightning_sdk/cli/utils/cloud_account_map.py +10 -0
- lightning_sdk/cli/utils/get_base_studio.py +24 -0
- lightning_sdk/cli/utils/handle_machine_and_gpus_args.py +69 -0
- lightning_sdk/cli/utils/logging.py +122 -0
- lightning_sdk/cli/utils/owner_selection.py +110 -0
- lightning_sdk/cli/utils/resolve.py +28 -0
- lightning_sdk/cli/utils/richt_print.py +35 -0
- lightning_sdk/cli/utils/save_to_config.py +27 -0
- lightning_sdk/cli/utils/ssh_connection.py +59 -0
- lightning_sdk/cli/utils/studio_selection.py +113 -0
- lightning_sdk/cli/utils/teamspace_selection.py +125 -0
- lightning_sdk/cli/vm/__init__.py +20 -0
- lightning_sdk/cli/vm/create.py +33 -0
- lightning_sdk/cli/vm/delete.py +25 -0
- lightning_sdk/cli/vm/list.py +30 -0
- lightning_sdk/cli/vm/ssh.py +31 -0
- lightning_sdk/cli/vm/start.py +60 -0
- lightning_sdk/cli/vm/stop.py +25 -0
- lightning_sdk/cli/vm/switch.py +38 -0
- lightning_sdk/constants.py +1 -0
- lightning_sdk/deployment/__init__.py +2 -0
- lightning_sdk/deployment/deployment.py +17 -2
- lightning_sdk/helpers.py +56 -37
- lightning_sdk/job/base.py +21 -6
- lightning_sdk/job/job.py +13 -0
- lightning_sdk/job/v1.py +11 -0
- lightning_sdk/job/v2.py +12 -0
- lightning_sdk/lightning_cloud/login.py +320 -10
- lightning_sdk/lightning_cloud/openapi/__init__.py +113 -3
- lightning_sdk/lightning_cloud/openapi/api/__init__.py +3 -0
- lightning_sdk/lightning_cloud/openapi/api/assistants_service_api.py +713 -75
- lightning_sdk/lightning_cloud/openapi/api/auth_service_api.py +376 -0
- lightning_sdk/lightning_cloud/openapi/api/billing_service_api.py +191 -1
- lightning_sdk/lightning_cloud/openapi/api/cloud_space_environment_template_service_api.py +5 -1
- lightning_sdk/lightning_cloud/openapi/api/cloud_space_service_api.py +420 -0
- lightning_sdk/lightning_cloud/openapi/api/cloudy_service_api.py +0 -97
- lightning_sdk/lightning_cloud/openapi/api/cluster_service_api.py +420 -0
- lightning_sdk/lightning_cloud/openapi/api/data_connection_service_api.py +101 -0
- lightning_sdk/lightning_cloud/openapi/api/incidents_service_api.py +1058 -0
- lightning_sdk/lightning_cloud/openapi/api/jobs_service_api.py +121 -0
- lightning_sdk/lightning_cloud/openapi/api/k8_s_cluster_service_api.py +1742 -94
- lightning_sdk/lightning_cloud/openapi/api/markets_service_api.py +145 -0
- lightning_sdk/lightning_cloud/openapi/api/models_store_api.py +4 -4
- lightning_sdk/lightning_cloud/openapi/api/product_license_service_api.py +108 -108
- lightning_sdk/lightning_cloud/openapi/api/projects_service_api.py +105 -0
- lightning_sdk/lightning_cloud/openapi/api/schedules_service_api.py +347 -0
- lightning_sdk/lightning_cloud/openapi/api/sdk_command_history_service_api.py +141 -0
- lightning_sdk/lightning_cloud/openapi/api/storage_service_api.py +761 -1
- lightning_sdk/lightning_cloud/openapi/configuration.py +3 -19
- lightning_sdk/lightning_cloud/openapi/models/__init__.py +110 -3
- lightning_sdk/lightning_cloud/openapi/models/assistant_id_conversations_body.py +15 -15
- lightning_sdk/lightning_cloud/openapi/models/cloudspace_id_visibility_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/cluster_id_kubernetestemplates_body.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/cluster_id_metrics_body.py +131 -1
- lightning_sdk/lightning_cloud/openapi/models/create.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/create_machine_request_represents_the_request_to_create_a_machine.py +461 -0
- lightning_sdk/lightning_cloud/openapi/models/deployments_id_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/externalv1_cloud_space_instance_status.py +105 -1
- lightning_sdk/lightning_cloud/openapi/models/externalv1_user_status.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/id_codeconfig_body.py +3 -81
- lightning_sdk/lightning_cloud/openapi/models/id_fork_body1.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/id_render_body.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/id_sleepconfig_body.py +175 -0
- lightning_sdk/lightning_cloud/openapi/models/id_transfer_body.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/incident_id_messages_body.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/incidents_id_body.py +279 -0
- lightning_sdk/lightning_cloud/openapi/models/job_id_reportroutingtelemetry_body.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/kubernetestemplates_id_body.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/license_key_validate_body.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/message_id_actions_body.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/messages_message_id_body.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/metricsstream_create_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/models_model_id_body.py +109 -31
- lightning_sdk/lightning_cloud/openapi/models/models_model_id_body1.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/orgs_id_body.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/project_id_storage_body.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/project_id_storagetransfers_body.py +175 -0
- lightning_sdk/lightning_cloud/openapi/models/project_tab_management_messages.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/projects_id_body.py +79 -1
- lightning_sdk/lightning_cloud/openapi/models/storage_complete_body.py +41 -15
- lightning_sdk/lightning_cloud/openapi/models/storagetransfers_validate_body.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/update1.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/uploads_upload_id_body1.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/user_id_affiliatelinks_body.py +107 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_abort_storage_transfer_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_aggregated_pod_metrics.py +799 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_ai_pod_v1.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_assistant_session_daily_aggregated.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_billing_tier.py +0 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cancel_running_cloud_space_instance_transfer_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_provider.py +2 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_environment_template_config.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_specialized_view.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cloud_space_transfer_metadata.py +147 -17
- lightning_sdk/lightning_cloud/openapi/models/v1_cloudflare_v1.py +3 -29
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_accelerator.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_capacity_reservation.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_metrics.py +1527 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_security_options.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_spec.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_cluster_type.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_container_metrics.py +21 -21
- lightning_sdk/lightning_cloud/openapi/models/v1_create_incident_request.py +305 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_create_license_request.py +175 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_create_machine_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_create_model_metrics_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_create_project_request.py +79 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_create_sdk_command_history_request.py +253 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_create_sdk_command_history_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_daily_model_metrics.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_data_connection.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_delete_incident_message_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_delete_incident_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_delete_kubernetes_template_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_delete_license_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_delete_machine_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_deployment.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_external_cluster_spec.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_external_search_user.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_filestore_data_connection.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_filesystem_metric.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_firewall_rule.py +175 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_get_cloud_space_required_balance_status_response.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_get_cloud_space_transfer_estimate_response.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_get_latest_model_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_get_machine_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_get_market_pricing_response.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_get_model_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_get_temp_bucket_credentials_response.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_get_user_response.py +41 -15
- lightning_sdk/lightning_cloud/openapi/models/v1_google_cloud_direct_v1.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_group_node_metrics.py +1215 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_group_pod_metrics.py +1241 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_guest_login_request.py +177 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_guest_login_response.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_guest_user.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_incident.py +565 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_incident_detail.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_incident_event.py +591 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_incident_message.py +253 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_incident_severity.py +105 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_incident_type.py +108 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_job.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_job_spec.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_k8s_incident_indexes.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_kai_scheduler_queue_metrics.py +627 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_aws_config.py +279 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_direct_settings_v1.py +253 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_direct_v1.py +107 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_template.py +357 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_kubernetes_template_property.py +227 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_lambda_labs_direct_v1.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_license.py +227 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_lightning_elastic_cluster_v1.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_aggregated_pod_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_cluster_metric_timestamps_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_cluster_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_cluster_namespace_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_cluster_namespace_user_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_conversation_message_actions_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_filesystem_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_group_pod_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_incident_events_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_incident_messages_response.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_incidents_response.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_kai_scheduler_queues_metrics_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_kubernetes_templates_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/{v1_list_product_licenses_response.py → v1_list_license_response.py} +16 -16
- lightning_sdk/lightning_cloud/openapi/models/v1_list_machines_response.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_platform_notifications_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_schedule_runs_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_list_storage_transfers_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_lustre_data_connection.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_machine.py +617 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_machine_direct_v1.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_magic_link_login_request.py +1 -27
- lightning_sdk/lightning_cloud/openapi/models/v1_magic_link_login_response.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_managed_model.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_market_price.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_membership.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_message_action.py +279 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_metrics_stream.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_model_metrics.py +175 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_namespace_metrics.py +591 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_namespace_user_metrics.py +435 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_nebius_direct_v1.py +29 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_node_metrics.py +361 -23
- lightning_sdk/lightning_cloud/openapi/models/v1_notification_type.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_organization.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_pause_storage_transfer_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_platform_notification.py +279 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_pod_metrics.py +335 -23
- lightning_sdk/lightning_cloud/openapi/models/v1_project.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_project_cluster_binding.py +27 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_project_membership.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_project_settings.py +53 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_project_tab.py +149 -0
- lightning_sdk/lightning_cloud/openapi/models/{v1_product_license_check_response.py → v1_purchase_annual_upsell_request.py} +23 -23
- lightning_sdk/lightning_cloud/openapi/models/v1_purchase_annual_upsell_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_quote_annual_upsell_response.py +227 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_render_kubernetes_template_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_report_deployment_routing_telemetry_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_required_balance_reason.py +107 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_reset_api_key_request.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_reset_api_key_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_resource_visibility.py +1 -27
- lightning_sdk/lightning_cloud/openapi/models/v1_resume_storage_transfer_response.py +97 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_routing_telemetry.py +79 -1
- lightning_sdk/lightning_cloud/openapi/models/v1_rule_resource.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_schedule_run.py +357 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_sdk_command_history_severity.py +104 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_sdk_command_history_type.py +104 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_secret_type.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_server_alert_type.py +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_slack_notifier.py +201 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_slack_notifier_type.py +105 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_storage_asset.py +133 -3
- lightning_sdk/lightning_cloud/openapi/models/v1_storage_transfer.py +435 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_storage_transfer_status.py +108 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_token_login_request.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_token_login_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_token_owner_type.py +104 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_update_cloud_space_instance_config_request.py +3 -81
- lightning_sdk/lightning_cloud/openapi/models/v1_update_project_tab_order_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_update_user_request.py +41 -15
- lightning_sdk/lightning_cloud/openapi/models/v1_user_features.py +444 -600
- lightning_sdk/lightning_cloud/openapi/models/v1_validate_license_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_validate_storage_transfer_response.py +123 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_voltage_park_direct_v1.py +29 -3
- lightning_sdk/lightning_cloud/rest_client.py +48 -45
- lightning_sdk/lightning_cloud/utils/data_connection.py +51 -1
- lightning_sdk/llm/llm.py +175 -56
- lightning_sdk/llm/public_assistants.py +44 -7
- lightning_sdk/machine.py +21 -2
- lightning_sdk/mmt/base.py +7 -0
- lightning_sdk/mmt/mmt.py +11 -3
- lightning_sdk/mmt/v1.py +3 -1
- lightning_sdk/mmt/v2.py +4 -0
- lightning_sdk/owner.py +2 -1
- lightning_sdk/pipeline/steps.py +6 -0
- lightning_sdk/plugin.py +6 -1
- lightning_sdk/studio.py +294 -53
- lightning_sdk/teamspace.py +167 -7
- lightning_sdk/user.py +19 -1
- lightning_sdk/utils/config.py +179 -0
- lightning_sdk/utils/license.py +13 -0
- lightning_sdk/utils/logging.py +79 -0
- lightning_sdk/utils/names.py +1179 -0
- lightning_sdk/utils/progress.py +283 -0
- lightning_sdk/utils/resolve.py +82 -7
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/METADATA +2 -1
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/RECORD +328 -169
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/entry_points.txt +1 -0
- lightning_sdk/lightning_cloud/openapi/models/v1_product_license.py +0 -435
- lightning_sdk/services/license.py +0 -363
- /lightning_sdk/cli/{deploy → legacy}/__init__.py +0 -0
- /lightning_sdk/cli/{ai_hub.py → legacy/ai_hub.py} +0 -0
- /lightning_sdk/cli/{docker_cli.py → legacy/docker_cli.py} +0 -0
- /lightning_sdk/cli/{exceptions.py → legacy/exceptions.py} +0 -0
- /lightning_sdk/cli/{run.py → legacy/run.py} +0 -0
- /lightning_sdk/cli/{studios_menu.py → legacy/studios_menu.py} +0 -0
- /lightning_sdk/cli/{coloring.py → utils/coloring.py} +0 -0
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/LICENSE +0 -0
- {lightning_sdk-2025.8.6rc2.dist-info → lightning_sdk-2025.11.5.dist-info}/WHEEL +0 -0
- {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()
|
|
@@ -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.
|
|
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(
|
|
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
|
|
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
|
|
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.
|
|
12
|
-
from lightning_sdk.lightning_cloud.openapi import
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
245
|
+
menu = TeamspacesMenu()
|
|
246
246
|
clusters_menu = _ClustersMenu()
|
|
247
|
-
resolved_teamspace = menu
|
|
247
|
+
resolved_teamspace = menu(teamspace=teamspace)
|
|
248
248
|
|
|
249
249
|
if not cloud_account:
|
|
250
|
-
|
|
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.
|
|
10
|
-
from lightning_sdk.cli.
|
|
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 =
|
|
53
|
-
resolved_teamspace = menu
|
|
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
|
|
@@ -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
|
|
|
@@ -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.
|
|
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
|
|
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 =
|
|
141
|
-
teamspace = menu
|
|
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
|
-
|
|
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,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)
|