1+ import time
12from dataset import DSSDataset
23from recipe import DSSRecipe
34from managedfolder import DSSManagedFolder
910import os .path as osp
1011from .future import DSSFuture
1112from .notebook import DSSNotebook
13+ from dataikuapi .utils import DataikuException
14+
1215
1316class DSSProject (object ):
1417 """
@@ -276,7 +279,33 @@ def start_job(self, definition):
276279 job_def = self .client ._perform_json ("POST" , "/projects/%s/jobs/" % self .project_key , body = definition )
277280 return DSSJob (self .client , self .project_key , job_def ['id' ])
278281
279-
282+ def start_job_and_wait (self , definition , no_fail = False ):
283+ """
284+ Create a new job. Wait the end of the job to complete.
285+
286+ Args:
287+ definition: the definition for the job to create. The definition must contain the type of job (RECURSIVE_BUILD,
288+ NON_RECURSIVE_FORCED_BUILD, RECURSIVE_FORCED_BUILD, RECURSIVE_MISSING_ONLY_BUILD) and a list of outputs to build.
289+ Optionally, a refreshHiveMetastore field can specify whether to re-synchronize the Hive metastore for recomputed
290+ HDFS datasets.
291+ """
292+ job_def = self .client ._perform_json ("POST" , "/projects/%s/jobs/" % self .project_key , body = definition )
293+ job = DSSJob (self .client , self .project_key , job_def ['id' ])
294+ job_state = job .get_status ().get ("baseStatus" , {}).get ("state" , "" )
295+ sleep_time = 2
296+ while job_state not in ["DONE" , "ABORTED" , "FAILED" ]:
297+ sleep_time = 300 if sleep_time >= 300 else sleep_time * 2
298+ time .sleep (sleep_time )
299+ job_state = job .get_status ().get ("baseStatus" , {}).get ("state" , "" )
300+ if job_state in ["ABORTED" , "FAILED" ]:
301+ if no_fail :
302+ break
303+ else :
304+ raise DataikuException ("Job run did not finish. Status: %s" % (job_state ))
305+ return job_state
306+
307+ def new_job_definition_builder (self , job_type = 'NON_RECURSIVE_FORCED_BUILD' ):
308+ return JobDefinitionBuilder (self .project_key , job_type )
280309
281310 ########################################################
282311 # Variables
@@ -380,7 +409,7 @@ def list_imported_bundles(self):
380409 "/projects/%s/bundles/imported" % self .project_key )
381410
382411 def import_bundle_from_archive (self , archive_path ):
383- return self .client ._perform_empty ("POST" ,
412+ return self .client ._perform_json ("POST" ,
384413 "/projects/%s/bundles/imported/actions/importFromArchive" % (self .project_key ),
385414 params = { "archivePath" : osp .abspath (archive_path ) })
386415
@@ -545,3 +574,45 @@ def set_tags(self, tags={}):
545574 @param obj: must be a modified version of the object returned by list_tags
546575 """
547576 return self .client ._perform_empty ("PUT" , "/projects/%s/tags" % self .project_key , body = tags )
577+
578+
579+ class JobDefinitionBuilder (object ):
580+ def __init__ (self , project_key , job_type = "NON_RECURSIVE_FORCED_BUILD" ):
581+ """
582+ Create a helper to build a job definition
583+
584+ :param project_key: the project in which the job is launched
585+ :param job_type: the build type for the job RECURSIVE_BUILD, NON_RECURSIVE_FORCED_BUILD,
586+ RECURSIVE_FORCED_BUILD, RECURSIVE_MISSING_ONLY_BUILD
587+
588+ """
589+ self .project_key = project_key
590+ self .definition = {'type' :job_type , 'refreshHiveMetastore' :False , 'outputs' :[]}
591+
592+ def with_type (self , job_type ):
593+ """
594+ Sets the build type
595+
596+ :param job_type: the build type for the job RECURSIVE_BUILD, NON_RECURSIVE_FORCED_BUILD,
597+ RECURSIVE_FORCED_BUILD, RECURSIVE_MISSING_ONLY_BUILD
598+ """
599+ self .definition ['type' ] = job_type
600+ return self
601+
602+ def with_refresh_metastore (self , refresh_metastore ):
603+ """
604+ Sets whether the hive tables built by the job should have their definitions
605+ refreshed after the corresponding dataset is built
606+ """
607+ self .definition ['refreshHiveMetastore' ] = refresh_metastore
608+ return self
609+
610+ def with_output (self , name , object_type = None , object_project_key = None , partition = None ):
611+ """
612+ Adds an item to build in the definition
613+ """
614+ self .definition ['outputs' ].append ({'type' :object_type , 'id' :name , 'projectKey' :object_project_key , 'partition' :partition })
615+ return self
616+
617+ def get_definition (self ):
618+ return self .definition
0 commit comments