1515from .login import apikey
1616from .method import *
1717
18- def zip_to_tmp (obj_name ):
18+ def zip_to_tmp (files , ignore_files = []):
19+ file = files [0 ]
1920 zipname = os .path .join (tempfile .gettempdir (),
20- os .path .basename (obj_name )) + '.zip'
21+ os .path .basename (os . path . abspath ( os . path . expanduser ( file )) )) + '.zip'
2122 outZipFile = zipfile .ZipFile (zipname , 'w' , zipfile .ZIP_DEFLATED )
22-
23- if os .path .isdir (obj_name ):
24- for dirpath , dirnames , filenames in os .walk (obj_name ):
25- for filename in dirnames + filenames :
26- filepath = os .path .join (dirpath , filename )
27- basename = os .path .basename (filepath )
28- if ('/.git/' not in filepath
29- and basename not in ['.git' , '.gitignore' ]):
30- arcname = os .path .relpath (filepath , obj_name )
31- outZipFile .write (filepath , arcname )
32- else :
33- outZipFile .write (obj_name , os .path .basename (obj_name ))
34-
35- outZipFile .close ()
23+ files_added = set ()
24+ with outZipFile :
25+ for file in files :
26+ if os .path .isdir (file ):
27+ for dirpath , dirnames , filenames in os .walk (file ):
28+ dirnames [:] = [d for d in dirnames if d not in ignore_files ]
29+ for filename in filenames :
30+ if filename not in ignore_files :
31+ filepath = os .path .join (dirpath , filename )
32+ arcname = os .path .relpath (filepath , file )
33+ if arcname not in files_added :
34+ outZipFile .write (filepath , arcname )
35+ files_added .add (arcname )
36+ else :
37+ arcname = os .path .basename (file )
38+ if arcname not in files_added :
39+ outZipFile .write (file , arcname )
40+ files_added .add (arcname )
3641 return zipname
3742
3843
@@ -47,7 +52,9 @@ def method(category, method, params):
4752 elif not config .PAPERSPACE_API_KEY :
4853 config .PAPERSPACE_API_KEY = apikey ()
4954 params .pop ('tail' , None )
50- params .pop ('no_logging' , None )
55+ no_logging = params .pop ('no_logging' , None )
56+ workspace_files = params .pop ('extraFiles' , [])
57+ ignore_files = params .pop ('ignoreFiles' , [])
5158
5259 if method in ['artifactsGet' , 'artifactsList' , 'getJob' , 'getJobs' ,
5360 'getLogs' ]:
@@ -68,19 +75,39 @@ def method(category, method, params):
6875
6976 files = None
7077 if method == 'createJob' and 'workspace' in params :
71- workspace = params ['workspace' ]
72- workspace_file = None
73- if workspace and workspace != 'none' :
74- workspace_path = os .path .expanduser (workspace )
75- if os .path .exists (workspace_path ):
76- if (not workspace_path .endswith ('.zip' )
77- and not workspace_path .endswith ('.gz' )):
78- workspace_file = zip_to_tmp (workspace_path )
79- else :
80- workspace_file = workspace_path
78+
79+ workspace = params .get ('workspace' , None )
80+ ignore_files .extend (['.git' , '.gitignore' ])
81+ if workspace :
82+ if workspace != 'none' :
83+ workspace_files .insert (0 , workspace )
84+ del params ['workspace' ]
85+
86+ if workspace_files :
87+ workspace_file = None
88+ for file in workspace_files :
89+ file_path = os .path .expanduser (file )
90+ if not os .path .exists (file_path ):
91+ message = format ('error: file or directory not found: %s' % file_path )
92+ print (message )
93+ if no_logging :
94+ return { 'error' : True , 'message' : message }
95+ sys .exit (1 )
96+ elif file_path == '/' :
97+ message = 'error: cannot zip root directory'
98+ print (message )
99+ if no_logging :
100+ return { 'error' : True , 'message' : message }
101+ sys .exit (1 )
102+
103+ if len (workspace_files ) == 1 and (file_path .endswith ('.zip' ) or file_path .endswith ('.gz' )):
104+ workspace_file = file_path
105+
106+ if not workspace_file :
107+ workspace_file = zip_to_tmp (workspace_files , ignore_files )
108+
81109 files = {'file' : open (workspace_file , 'rb' )}
82110 params ['workspaceFileName' ] = os .path .basename (workspace_file )
83- del params ['workspace' ]
84111
85112 try :
86113 r = requests .request (http_method , config .CONFIG_HOST + path ,
@@ -219,7 +246,7 @@ def waitfor(params):
219246 time .sleep (5 )
220247
221248
222- def create (params , no_logging = False ):
249+ def create (params , no_logging = False , extra_files = [] ):
223250 no_logging = no_logging or params .get ('no_logging' , False )
224251 job = method ('jobs' , 'createJob' , params )
225252 if no_logging :
@@ -329,7 +356,6 @@ def artifactsGet(params, no_logging=False):
329356
330357
331358# TO DO:
332- # deal with invalid directories, e.g. root for workspace
333359# detect running interactively
334360# stream file uploads/downloads
335361
@@ -373,10 +399,6 @@ def run(params={}, no_logging=False):
373399 src = src .replace ('paperspace.login' , '_paperspace_null_func' )
374400 src = src .replace ('paperspace.logout' , '_paperspace_null_func' )
375401
376- # XXX TEST CODE
377- #print(src)
378- #sys.exit(0)
379-
380402 src_path = os .path .join (tempfile .gettempdir (), src_file )
381403 with open (src_path , "w" ) as file :
382404 file .write (src )
@@ -390,25 +412,58 @@ def run(params={}, no_logging=False):
390412 params ['machineType' ] = 'P5000'
391413 if 'container' not in params :
392414 params ['container' ] = 'paperspace/tensorflow-python'
393- if 'command' not in params :
394- # TODO validate python version; handle no version, specific version
395- python_ver = params ['python' ] if 'python' in params else str (sys .version_info [0 ])
396- params ['command' ] = 'python' + python_ver + ' ' + src_file
397- if 'workspace' not in params or run_this :
398- params ['workspace' ] = src_path
399415
400- # XXX TEST CODE
401- #print(params)
416+ python_ver = params . pop ( 'python' , str ( sys . version_info [ 0 ])) # defaults locally running version
417+ # TODO validate python version; handle no version, specific version
402418
403- params .pop ('python' , None )
404- params .pop ('conda' , None )
405- params .pop ('init' , None )
406- params .pop ('req' , None )
407- params .pop ('pipenv' , None )
419+ if 'command' not in params :
420+ params ['command' ] = 'python' + python_ver + ' ' + src_file
408421
409- # XXX TEST CODE
410- #print('edited', params)
411- #return {}
422+ params ['extraFiles' ] = []
423+ if 'workspace' not in params :
424+ params ['workspace' ] = src_path
425+ else :
426+ params ['extraFiles' ].append (src_path )
427+
428+ if 'ignoreFiles' in params :
429+ if isinstance (params ['ignoreFiles' ], str ):
430+ params ['ignoreFiles' ] = params ['ignoreFiles' ].split (',' )
431+
432+ req = params .pop ('req' , None )
433+ if req :
434+ if not isinstance (req , str ):
435+ req = 'requirements.txt'
436+ if os .path .exists (req ):
437+ params ['extraFiles' ].append (req )
438+ params ['command' ] = 'pip' + python_ver + ' install -r ' + os .path .basename (req ) + '\n ' + params ['command' ]
439+
440+ pipenv = params .pop ('pipenv' , None )
441+ if pipenv :
442+ if isinstance (pipenv , str ):
443+ pipenv = pipenv .split (',' )
444+ elif isinstance (pipenv , bool ):
445+ pipenv = ['Pipfile' , 'Pipfile.lock' ]
446+ for pipfile in pipenv :
447+ if os .path .exists (pipfile ):
448+ params ['extraFiles' ].append (pipfile )
449+ uses_python_ver = ''
450+ if python_ver .startswith ('3' ):
451+ uses_python_ver == '--three '
452+ elif python_ver .startswith ('2' ):
453+ uses_python_ver == '--two '
454+ params ['command' ] = 'pipenv ' + uses_python_ver + 'install\n pipenv graph\n ' + params ['command' ]
455+
456+ conda = params .pop ('conda' , None )
457+ if conda :
458+ params ['command' ] = 'conda -env ' + conda + '\n ' + params ['command' ]
459+
460+ init = params .pop ('init' , None )
461+ if init :
462+ if not isinstance (init , str ):
463+ init = 'init.sh'
464+ if os .path .exists (init ):
465+ params ['extraFiles' ].append (init )
466+ params ['command' ] = '. ' + os .path .basename (init ) + '\n ' + params ['command' ]
412467
413468 res = create (params , no_logging )
414469 if run_this :
@@ -419,5 +474,4 @@ def run(params={}, no_logging=False):
419474# TO DO:
420475# automatic install of imported dependencies
421476# allow return results
422- # combine local workspace with source
423477# detect/use python environment
0 commit comments