Skip to content

Commit b6b285c

Browse files
authored
Add fusion commands to manage models in models space (#51)
1 parent bf12c40 commit b6b285c

File tree

3 files changed

+344
-31
lines changed

3 files changed

+344
-31
lines changed
Lines changed: 250 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
#!/usr/bin/env python3
2+
import os
3+
from typing import Any
4+
from typing import Dict
5+
from typing import Optional
6+
7+
from ..handler import SQLHandler
8+
from ..result import FusionSQLResult
9+
from .files import ShowFilesHandler
10+
from .utils import get_file_space
11+
12+
13+
class ShowModelsHandler(ShowFilesHandler):
14+
"""
15+
SHOW MODELS
16+
[ at_path ] [ <like> ]
17+
[ <order-by> ]
18+
[ <limit> ] [ recursive ] [ extended ];
19+
20+
# File path to list
21+
at_path = AT '<path>'
22+
23+
# Should the listing be recursive?
24+
recursive = RECURSIVE
25+
26+
# Should extended attributes be shown?
27+
extended = EXTENDED
28+
29+
Description
30+
-----------
31+
Displays the list of models in models space.
32+
33+
Arguments
34+
---------
35+
* ``<path>``: A path in the models space.
36+
* ``<pattern>``: A pattern similar to SQL LIKE clause.
37+
Uses ``%`` as the wildcard character.
38+
39+
Remarks
40+
-------
41+
* Use the ``LIKE`` clause to specify a pattern and return only the
42+
files that match the specified pattern.
43+
* The ``LIMIT`` clause limits the number of results to the
44+
specified number.
45+
* Use the ``ORDER BY`` clause to sort the results by the specified
46+
key. By default, the results are sorted in the ascending order.
47+
* The ``AT PATH`` clause specifies the path in the models
48+
space to list the files from.
49+
* To return more information about the files, use the ``EXTENDED``
50+
clause.
51+
52+
Examples
53+
--------
54+
The following command lists the models::
55+
56+
SHOW MODELS;
57+
58+
The following command lists the models with additional information::
59+
60+
SHOW MODELS EXTENDED;
61+
62+
See Also
63+
--------
64+
* ``UPLOAD MODEL model_name FROM path``
65+
* ``DOWNLOAD MODEL model_name``
66+
67+
68+
""" # noqa: E501
69+
70+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
71+
params['file_location'] = 'MODELS'
72+
73+
return super().run(params)
74+
75+
76+
ShowModelsHandler.register(overwrite=True)
77+
78+
79+
class UploadModelHandler(SQLHandler):
80+
"""
81+
UPLOAD MODEL model_name
82+
FROM local_path [ overwrite ];
83+
84+
# Model Name
85+
model_name = '<model-name>'
86+
87+
# Path to local file or directory
88+
local_path = '<local-path>'
89+
90+
# Should an existing file be overwritten?
91+
overwrite = OVERWRITE
92+
93+
Description
94+
-----------
95+
Uploads a file or folder to models space.
96+
97+
Arguments
98+
---------
99+
* ``<model-name>``: Model name.
100+
* ``<local-path>``: The path to the file or folder to upload in the local
101+
directory.
102+
103+
Remarks
104+
-------
105+
* If the ``OVERWRITE`` clause is specified, any existing file at the
106+
specified path in the models space is overwritten.
107+
108+
Examples
109+
--------
110+
The following command uploads a file to models space and overwrite any
111+
existing files at the specified path::
112+
113+
UPLOAD MODEL model_name
114+
FROM 'llama3/' OVERWRITE;
115+
116+
See Also
117+
--------
118+
* ``DOWNLOAD MODEL model_name``
119+
120+
""" # noqa: E501
121+
122+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
123+
params['file_location'] = 'MODELS'
124+
125+
model_name = params['model_name']
126+
local_path = params['local_path']
127+
128+
file_space = get_file_space(params)
129+
130+
if os.path.isdir(local_path):
131+
file_space.upload_folder(
132+
local_path=local_path,
133+
path=os.path.join(model_name, ''),
134+
overwrite=params['overwrite'],
135+
)
136+
else:
137+
file_space.upload_file(
138+
local_path=local_path,
139+
path=os.path.join(model_name, local_path),
140+
overwrite=params['overwrite'],
141+
)
142+
143+
return None
144+
145+
146+
UploadModelHandler.register(overwrite=True)
147+
148+
149+
class DownloadModelHandler(SQLHandler):
150+
"""
151+
DOWNLOAD MODEL model_name
152+
[ local_path ]
153+
[ overwrite ];
154+
155+
# Model Name
156+
model_name = '<model-name>'
157+
158+
# Path to local directory
159+
local_path = TO '<local-path>'
160+
161+
# Should an existing directory be overwritten?
162+
overwrite = OVERWRITE
163+
164+
Description
165+
-----------
166+
Download a model from models space.
167+
168+
Arguments
169+
---------
170+
* ``<model-name>``: Model name to download in models space.
171+
* ``<local-path>``: Specifies the path in the local directory
172+
where the model is downloaded.
173+
174+
Remarks
175+
-------
176+
* If the ``OVERWRITE`` clause is specified, any existing file or folder at
177+
the download location is overwritten.
178+
* If ``<local-path>`` is not specified, the model is downloaded to the current location.
179+
180+
Examples
181+
--------
182+
The following command displays the contents of the file on the
183+
standard output::
184+
185+
DOWNLOAD MODEL llama3;
186+
187+
The following command downloads a model to a specific location and
188+
overwrites any existing models folder with the name ``local_llama3`` on the local storage::
189+
190+
DOWNLOAD MODEL llama3
191+
TO 'local_llama3' OVERWRITE;
192+
193+
See Also
194+
--------
195+
* ``UPLOAD MODEL model_name FROM local_path``
196+
197+
""" # noqa: E501
198+
199+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
200+
params['file_location'] = 'MODELS'
201+
202+
file_space = get_file_space(params)
203+
204+
model_name = params['model_name']
205+
file_space.download_folder(
206+
path=os.path.join(model_name, ''),
207+
local_path=params['local_path'] or model_name,
208+
overwrite=params['overwrite'],
209+
)
210+
211+
return None
212+
213+
214+
DownloadModelHandler.register(overwrite=True)
215+
216+
217+
class DropModelsHandler(SQLHandler):
218+
"""
219+
DROP MODEL model_name;
220+
221+
# Model Name
222+
model_name = '<model-name>'
223+
224+
Description
225+
-----------
226+
Deletes a model from models space.
227+
228+
Arguments
229+
---------
230+
* ``<model-name>``: Model name to delete in models space.
231+
232+
Example
233+
--------
234+
The following commands deletes a model from a model space::
235+
236+
DROP MODEL llama3;
237+
238+
""" # noqa: E501
239+
240+
def run(self, params: Dict[str, Any]) -> Optional[FusionSQLResult]:
241+
params['file_location'] = 'MODELS'
242+
path = os.path.join(params['model_name'], '')
243+
244+
file_space = get_file_space(params)
245+
file_space.removedirs(path=path)
246+
247+
return None
248+
249+
250+
DropModelsHandler.register(overwrite=True)

singlestoredb/fusion/handlers/utils.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from ...management.files import FilesManager
1212
from ...management.files import FileSpace
1313
from ...management.files import manage_files
14+
from ...management.files import MODELS_SPACE
1415
from ...management.files import PERSONAL_SPACE
1516
from ...management.files import SHARED_SPACE
1617
from ...management.workspace import StarterWorkspace
@@ -296,15 +297,14 @@ def get_file_space(params: Dict[str, Any]) -> FileSpace:
296297
file_location = params.get('file_location')
297298
if file_location:
298299
file_location_lower_case = file_location.lower()
299-
if (
300-
file_location_lower_case != PERSONAL_SPACE and
301-
file_location_lower_case != SHARED_SPACE
302-
):
303-
raise ValueError(f'invalid file location: {file_location}')
304300

305301
if file_location_lower_case == PERSONAL_SPACE:
306302
return manager.personal_space
307303
elif file_location_lower_case == SHARED_SPACE:
308304
return manager.shared_space
305+
elif file_location_lower_case == MODELS_SPACE:
306+
return manager.models_space
307+
else:
308+
raise ValueError(f'invalid file location: {file_location}')
309309

310310
raise KeyError('no file space was specified')

0 commit comments

Comments
 (0)