23
23
import warnings
24
24
from pathlib import Path
25
25
26
- from hopsworks import client , constants , project , version
27
- from hopsworks . client . exceptions import ProjectException , RestAPIError
26
+ from hopsworks . client . exceptions import RestAPIError , ProjectException
27
+ from hopsworks import version , constants , client , project
28
28
from hopsworks .connection import Connection
29
+ from hopsworks .core import project_api , secret_api
30
+ from hopsworks .decorators import NoHopsworksConnectionError
29
31
30
32
31
33
# Needs to run before import of hsml and hsfs
42
44
_hw_connection = Connection .connection
43
45
44
46
_connected_project = None
45
-
47
+ _secrets_api = None
48
+ _project_api = None
46
49
47
50
def hw_formatwarning (message , category , filename , lineno , line = None ):
48
51
return "{}: {}\n " .format (category .__name__ , message )
@@ -113,6 +116,7 @@ def login(
113
116
if "REST_ENDPOINT" in os .environ :
114
117
_hw_connection = _hw_connection ()
115
118
_connected_project = _hw_connection .get_project ()
119
+ _initialize_module_apis ()
116
120
print ("\n Logged in to project, explore it here " + _connected_project .get_url ())
117
121
return _connected_project
118
122
@@ -140,6 +144,8 @@ def login(
140
144
elif host is None : # Always do a fallback to Serverless Hopsworks if not defined
141
145
host = constants .HOSTS .APP_HOST
142
146
147
+ is_app = (host == constants .HOSTS .APP_HOST )
148
+
143
149
# If port same as default, get HOPSWORKS_HOST environment variable
144
150
if port == 443 and "HOPSWORKS_PORT" in os .environ :
145
151
port = os .environ ["HOPSWORKS_PORT" ]
@@ -166,23 +172,24 @@ def login(
166
172
"Could not find api key file on path: {}" .format (api_key_file )
167
173
)
168
174
# If user connected to Serverless Hopsworks, and the cached .hw_api_key exists, then use it.
169
- elif os .path .exists (api_key_path ) and host == constants . HOSTS . APP_HOST :
175
+ elif os .path .exists (api_key_path ) and is_app :
170
176
try :
171
177
_hw_connection = _hw_connection (
172
178
host = host , port = port , api_key_file = api_key_path
173
179
)
174
- _connected_project = _prompt_project (_hw_connection , project )
180
+ _connected_project = _prompt_project (_hw_connection , project , is_app )
175
181
print (
176
182
"\n Logged in to project, explore it here "
177
183
+ _connected_project .get_url ()
178
184
)
185
+ _initialize_module_apis ()
179
186
return _connected_project
180
187
except RestAPIError :
181
188
logout ()
182
189
# API Key may be invalid, have the user supply it again
183
190
os .remove (api_key_path )
184
191
185
- if api_key is None and host == constants . HOSTS . APP_HOST :
192
+ if api_key is None and is_app :
186
193
print (
187
194
"Copy your Api Key (first register/login): https://c.app.hopsworks.ai/account/api/generated"
188
195
)
@@ -198,12 +205,17 @@ def login(
198
205
199
206
try :
200
207
_hw_connection = _hw_connection (host = host , port = port , api_key_value = api_key )
201
- _connected_project = _prompt_project (_hw_connection , project )
208
+ _connected_project = _prompt_project (_hw_connection , project , is_app )
202
209
except RestAPIError as e :
203
210
logout ()
204
211
raise e
205
212
206
- print ("\n Logged in to project, explore it here " + _connected_project .get_url ())
213
+ if _connected_project is None :
214
+ print ("Could not find any project, use hopsworks.create_project('my_project') to create one" )
215
+ else :
216
+ print ("\n Logged in to project, explore it here " + _connected_project .get_url ())
217
+
218
+ _initialize_module_apis ()
207
219
return _connected_project
208
220
209
221
@@ -245,11 +257,14 @@ def _get_cached_api_key_path():
245
257
return api_key_path
246
258
247
259
248
- def _prompt_project (valid_connection , project ):
260
+ def _prompt_project (valid_connection , project , is_app ):
249
261
saas_projects = valid_connection .get_projects ()
250
262
if project is None :
251
263
if len (saas_projects ) == 0 :
252
- raise ProjectException ("Could not find any project" )
264
+ if is_app :
265
+ raise ProjectException ("Could not find any project" )
266
+ else :
267
+ return None
253
268
elif len (saas_projects ) == 1 :
254
269
return saas_projects [0 ]
255
270
else :
@@ -258,7 +273,7 @@ def _prompt_project(valid_connection, project):
258
273
for index in range (len (saas_projects )):
259
274
print ("\t (" + str (index + 1 ) + ") " + saas_projects [index ].name )
260
275
while True :
261
- project_index = input ("\n Enter project to access : " )
276
+ project_index = input ("\n Enter number corresponding to the project to use : " )
262
277
# Handle invalid input type
263
278
try :
264
279
project_index = int (project_index )
@@ -285,8 +300,98 @@ def _prompt_project(valid_connection, project):
285
300
286
301
287
302
def logout ():
303
+ """Cleans up and closes the connection for the hopsworks, hsfs and hsml libraries.
304
+ """
288
305
global _hw_connection
289
- if isinstance (_hw_connection , Connection ):
306
+ global _project_api
307
+ global _secrets_api
308
+
309
+ if _is_connection_active ():
290
310
_hw_connection .close ()
311
+
291
312
client .stop ()
313
+ _project_api = None
314
+ _secrets_api = None
292
315
_hw_connection = Connection .connection
316
+
317
+ def _is_connection_active ():
318
+ global _hw_connection
319
+ return isinstance (_hw_connection , Connection )
320
+
321
+ def get_current_project () -> project .Project :
322
+ """Get a reference to the current logged in project.
323
+
324
+ Example for creating a new project
325
+
326
+ ```python
327
+
328
+ import hopsworks
329
+
330
+ hopsworks.login()
331
+
332
+ project = hopsworks.get_current_project()
333
+
334
+ ```
335
+
336
+ # Returns
337
+ `Project`. A project handle object to perform operations on.
338
+ """
339
+ global _connected_project
340
+ if _connected_project is None :
341
+ raise ProjectException ("No project is set for this session" )
342
+ return _connected_project
343
+
344
+ def _initialize_module_apis ():
345
+ global _project_api
346
+ global _secrets_api
347
+ _project_api = project_api .ProjectApi ()
348
+ _secrets_api = secret_api .SecretsApi ()
349
+
350
+ def create_project (
351
+ name : str , description : str = None , feature_store_topic : str = None
352
+ ):
353
+ """Create a new project.
354
+
355
+ Example for creating a new project
356
+
357
+ ```python
358
+
359
+ import hopsworks
360
+
361
+ hopsworks.login()
362
+
363
+ hopsworks.create_project("my_hopsworks_project", description="An example Hopsworks project")
364
+
365
+ ```
366
+ # Arguments
367
+ name: The name of the project.
368
+ description: optional description of the project
369
+ feature_store_topic: optional feature store topic name
370
+
371
+ # Returns
372
+ `Project`. A project handle object to perform operations on.
373
+ """
374
+ global _hw_connection
375
+ global _connected_project
376
+
377
+ if not _is_connection_active ():
378
+ raise NoHopsworksConnectionError ()
379
+
380
+ new_project = _hw_connection ._project_api ._create_project (name , description , feature_store_topic )
381
+ if _connected_project is None :
382
+ _connected_project = new_project
383
+ print ("Setting {} as the current project, a reference can be retrieved by calling hopsworks.get_current_project()" .format (_connected_project .name ))
384
+ return _connected_project
385
+ else :
386
+ print ("You are already using the project {}, to access the new project use hopsworks.login(..., project='{}')" .format (_connected_project .name , new_project .name ))
387
+
388
+ def get_secrets_api ():
389
+ """Get the secrets api.
390
+
391
+ # Returns
392
+ `SecretsApi`: The Secrets Api handle
393
+ """
394
+ global _secrets_api
395
+ if not _is_connection_active ():
396
+ raise NoHopsworksConnectionError ()
397
+ return _secrets_api
0 commit comments