1818
1919import click
2020import rich
21+ from lightning_cloud .openapi import Externalv1LightningappInstance
2122from rich .console import Console
2223from rich .live import Live
2324from rich .spinner import Spinner
@@ -44,9 +45,7 @@ def ls(path: Optional[str] = None) -> List[str]:
4445
4546 root = "/"
4647
47- with Live (Spinner ("point" , text = Text ("pending..." , style = "white" )), transient = True ) as live :
48-
49- live .stop ()
48+ with Live (Spinner ("point" , text = Text ("pending..." , style = "white" )), transient = True ):
5049
5150 if not os .path .exists (_LIGHTNING_CONNECTION_FOLDER ):
5251 os .makedirs (_LIGHTNING_CONNECTION_FOLDER )
@@ -76,45 +75,74 @@ def ls(path: Optional[str] = None) -> List[str]:
7675
7776 lit_apps = client .lightningapp_instance_service_list_lightningapp_instances (project_id = project_id ).lightningapps
7877
78+ lit_cloud_spaces = client .cloud_space_service_list_cloud_spaces (project_id = project_id ).cloudspaces
79+
7980 if len (splits ) == 1 :
80- app_names = sorted ([lit_app .name for lit_app in lit_apps ])
81- _print_names_with_colors (app_names , [_FOLDER_COLOR ] * len (app_names ))
82- return app_names
81+ apps = [lit_app .name for lit_app in lit_apps ]
82+ cloud_spaces = [lit_cloud_space .name for lit_cloud_space in lit_cloud_spaces ]
83+ ressource_names = sorted (set (cloud_spaces + apps ))
84+ _print_names_with_colors (ressource_names , [_FOLDER_COLOR ] * len (ressource_names ))
85+ return ressource_names
86+
87+ lit_ressources = [lit_resource for lit_resource in lit_cloud_spaces if lit_resource .name == splits [1 ]]
88+
89+ if len (lit_ressources ) == 0 :
8390
84- lit_apps = [lit_app for lit_app in lit_apps if lit_app .name == splits [1 ]]
91+ lit_ressources = [lit_resource for lit_resource in lit_apps if lit_resource .name == splits [1 ]]
8592
86- if len (lit_apps ) != 1 :
87- print (f"ERROR: There isn't any Lightning App matching the name { splits [1 ]} ." )
88- sys .exit (0 )
93+ if len (lit_ressources ) == 0 :
8994
90- lit_app = lit_apps [0 ]
95+ print (f"ERROR: There isn't any Lightning Ressource matching the name { splits [1 ]} ." )
96+ sys .exit (0 )
97+
98+ lit_resource = lit_ressources [0 ]
99+
100+ app_paths = []
101+ app_colors = []
102+
103+ cloud_spaces_paths = []
104+ cloud_spaces_colors = []
91105
92- paths = []
93- colors = []
94106 depth = len (splits )
95- subpath = "/" .join (splits [2 :])
96- # TODO: Replace with project level endpoints
97- for artifact in _collect_artifacts (client , project_id , lit_app .id ):
98- path = os .path .join (project_id , lit_app .name , artifact .filename )
107+
108+ prefix = "/" .join (splits [2 :])
109+ prefix = _get_prefix (prefix , lit_resource )
110+
111+ for artifact in _collect_artifacts (client = client , project_id = project_id , prefix = prefix ):
112+
113+ if str (artifact .filename ).startswith ("/" ):
114+ artifact .filename = artifact .filename [1 :]
115+
116+ path = os .path .join (project_id , prefix [1 :], artifact .filename )
117+
99118 artifact_splits = path .split ("/" )
100119
101- if len (artifact_splits ) < depth + 1 :
120+ if len (artifact_splits ) <= depth + 1 :
102121 continue
103122
104- if not str (artifact .filename ).startswith (subpath ):
105- continue
123+ path = artifact_splits [depth + 1 ]
106124
107- path = artifact_splits [depth ]
125+ paths = app_paths if isinstance (lit_resource , Externalv1LightningappInstance ) else cloud_spaces_paths
126+ colors = app_colors if isinstance (lit_resource , Externalv1LightningappInstance ) else cloud_spaces_colors
108127
109128 if path not in paths :
110129 paths .append (path )
111130
112131 # display files otherwise folders
113132 colors .append (_FILE_COLOR if len (artifact_splits ) == depth + 1 else _FOLDER_COLOR )
114133
115- _print_names_with_colors (paths , colors )
134+ if app_paths and cloud_spaces_paths :
135+ if app_paths :
136+ rich .print ("Lightning App" )
137+ _print_names_with_colors (app_paths , app_colors )
138+
139+ if cloud_spaces_paths :
140+ rich .print ("Lightning CloudSpaces" )
141+ _print_names_with_colors (cloud_spaces_paths , cloud_spaces_colors )
142+ else :
143+ _print_names_with_colors (app_paths + cloud_spaces_paths , app_colors + cloud_spaces_colors )
116144
117- return paths
145+ return app_paths + cloud_spaces_paths
118146
119147
120148def _add_colors (filename : str , color : Optional [str ] = None ) -> str :
@@ -156,21 +184,64 @@ def _print_names_with_colors(names: List[str], colors: List[str], padding: int =
156184def _collect_artifacts (
157185 client : LightningClient ,
158186 project_id : str ,
159- app_id : str ,
187+ prefix : str = "" ,
160188 page_token : Optional [str ] = "" ,
189+ cluster_id : Optional [str ] = None ,
190+ page_size : int = 100_000 ,
161191 tokens = None ,
192+ include_download_url : bool = False ,
162193) -> Generator :
163194 if tokens is None :
164195 tokens = []
165196
166- if page_token in tokens :
167- return
168-
169- response = client .lightningapp_instance_service_list_lightningapp_instance_artifacts (
170- project_id , app_id , page_token = page_token
171- )
172- yield from response .artifacts
173-
174- if response .next_page_token != "" :
175- tokens .append (page_token )
176- yield from _collect_artifacts (client , project_id , app_id , page_token = response .next_page_token , tokens = tokens )
197+ if cluster_id is None :
198+ clusters = client .projects_service_list_project_cluster_bindings (project_id )
199+ for cluster in clusters .clusters :
200+ yield from _collect_artifacts (
201+ client ,
202+ project_id ,
203+ prefix = prefix ,
204+ cluster_id = cluster .cluster_id ,
205+ page_token = page_token ,
206+ tokens = tokens ,
207+ page_size = page_size ,
208+ include_download_url = include_download_url ,
209+ )
210+ else :
211+
212+ if page_token in tokens :
213+ return
214+
215+ response = client .lightningapp_instance_service_list_project_artifacts (
216+ project_id ,
217+ prefix = prefix ,
218+ cluster_id = cluster_id ,
219+ page_token = page_token ,
220+ include_download_url = include_download_url ,
221+ page_size = str (page_size ),
222+ )
223+ yield from response .artifacts
224+
225+ if response .next_page_token != "" :
226+ tokens .append (page_token )
227+ yield from _collect_artifacts (
228+ client ,
229+ project_id ,
230+ prefix = prefix ,
231+ cluster_id = cluster_id ,
232+ page_token = response .next_page_token ,
233+ tokens = tokens ,
234+ )
235+
236+
237+ def _add_resource_prefix (prefix : str , resource_path : str ):
238+ if resource_path in prefix :
239+ return prefix
240+ return "/" + os .path .join (resource_path , prefix )
241+
242+
243+ def _get_prefix (prefix : str , lit_resource ) -> str :
244+ if isinstance (lit_resource , Externalv1LightningappInstance ):
245+ return _add_resource_prefix (prefix , f"lightningapps/{ lit_resource .id } " )
246+
247+ return _add_resource_prefix (prefix , f"cloudspaces/{ lit_resource .id } " )
0 commit comments