Source code for omegaml.backends.package.localpip

  1from os.path import basename, dirname
  2
  3import os
  4
  5from omegaml.backends.basedata import BaseDataBackend
  6from omegaml.backends.package.packager import build_sdist, install_and_import, load_from_path, RunnablePackageMixin
  7
  8
[docs] 9class PythonPackageData(RunnablePackageMixin, BaseDataBackend): 10 """ 11 Backend to support locally sourced custom scripts deployment to runtimes cluster 12 13 This supports any local setup.py 14 15 Usage:: 16 17 om.scripts.put('pkg://path/to/setup.py', 'myname') 18 om.scripts.get('myname') 19 20 Note that setup.py must minimally specify the following. The 21 name and packages kwargs must specify the same name as given 22 in put(..., name) 23 24 # setup.py 25 from setuptools import setup 26 setup(name='myname', packages=['myname']) 27 28 See Also: 29 https://packaging.python.org/tutorials/packaging-projects/ 30 """ 31 KIND = 'python.package' 32
[docs] 33 @classmethod 34 def supports(self, obj, name, **kwargs): 35 return isinstance(obj, str) and obj.startswith('pkg://')
36
[docs] 37 def put(self, obj, name, attributes=None, **kwargs): 38 """ 39 save a python package 40 41 This takes the full path to a setuptools setup.py, or a directory 42 containing a setup.py file. It then executes `python setup.py sdist` 43 and stores the resulting .tar.gz file in om.scripts 44 45 :param obj: full path to package file or directory, syntax as 46 pkg://path/to/dist.tar.gz or pkg://path/to/setup.py 47 :param name: name of package. must be the actual name of the package 48 as specified in setup.py 49 :return: the Metadata object 50 """ 51 pkgsrc = pkgdist = obj.split('//')[1] 52 if not 'tar.gz' in os.path.basename(pkgdist): 53 pkgsrc = pkgsrc.replace('setup.py', '') 54 distdir = os.path.join(pkgsrc, 'dist') 55 pkgdist = build_sdist(pkgsrc, distdir) 56 filename = self.data_store.object_store_key(name, 'pkg', hashed=True) 57 gridfile = self._store_to_file(self.data_store, pkgdist, filename) 58 return self.data_store._make_metadata( 59 name=name, 60 prefix=self.data_store.prefix, 61 bucket=self.data_store.bucket, 62 kind=PythonPackageData.KIND, 63 attributes=attributes, 64 gridfile=gridfile).save()
65
[docs] 66 def get(self, name, localpath=None, keep=False, install=True, **kwargs): 67 """ 68 Load package from store, install it locally and load. 69 70 This copies the package's .tar.gz file from om.scripts to a local temp 71 path and runs `pip install` on it. 72 73 :param name: the name of the package 74 :param keep: keep the packages load path in sys.path, defaults to False 75 :param localpath: the local path to store the package 76 :param install: if True call pip install on the retrieved package 77 :param kwargs: 78 :return: the loaded module 79 """ 80 pkgname = basename(name) 81 packagefname = '{}.tar.gz'.format(os.path.join(localpath or self.data_store.tmppath, pkgname)) 82 os.makedirs(dirname(packagefname), exist_ok=True) 83 self.path = self.packages_path 84 dstdir = localpath or self.path 85 if not os.path.exists(os.path.join(dstdir, pkgname)): 86 meta = self.data_store.metadata(name) 87 outf = meta.gridfile 88 with open(packagefname, 'wb') as pkgf: 89 pkgf.write(outf.read()) 90 if install: 91 mod = install_and_import(packagefname, pkgname, dstdir, keep=keep) 92 else: 93 mod = packagefname 94 elif install: 95 mod = load_from_path(pkgname, dstdir, keep=keep) 96 else: 97 mod = os.path.join(dstdir, pkgname) 98 return mod
99 100 @property 101 def packages_path(self): 102 return os.path.join(self.data_store.tmppath, 'packages')