コード例 #1
0
ファイル: omegacontentsmgr.py プロジェクト: omegaml/omegaml
    def _read_file(self, os_path, format):
        """Read a non-notebook file.

        os_path: The path to be read.
        format:
          If 'text', the contents will be decoded as UTF-8.
          If 'base64', the raw bytes contents will be encoded as base64.
          If not specified, try to decode as UTF-8, and fall back to base64
        """
        if os_path.endswith('.ipynb'):
            meta = self.omega.jobs.metadata(os_path)
        else:
            meta = self.omega.datasets.metadata(os_path)
        if meta is None or meta.gridfile is None:
            raise HTTPError(400, "Cannot read non-file %s" % os_path)

        if meta.gridfile:
            bcontent = meta.gridfile.read()
            meta.gridfile.close()

        if format is None or format == 'text':
            # Try to interpret as unicode if format is unknown or if unicode
            # was explicitly requested.
            try:
                return bcontent.decode('utf8'), 'text'
            except UnicodeError:
                if format == 'text':
                    raise HTTPError(
                        400,
                        "%s is not UTF-8 encoded" % os_path,
                        reason='bad format',
                    )
        return encodebytes(bcontent).decode('ascii'), 'base64'
コード例 #2
0
ファイル: inspect_handler.py プロジェクト: QCDIS/FAIRCells
    def get(self, path, command):
        notebook = self.contents_manager.get(path, content=True)
        inspector = self._get_inspector(notebook)

        if command == 'available':
            self.set_status(201)
            self.finish()
        elif command == 'variables':
            cell_index = self._int_argument('cellIdx')

            if cell_index is None:
                raise HTTPError(400, 'invalid_cell_idx')

            variables = inspector.get_variables(notebook, cell_index)

            self.finish(json.dumps({'data': variables}))
        elif command == "inspector.html":
            cell_index = self._int_argument('cellIdx')

            if cell_index is None:
                raise HTTPError(400, 'invalid_cell_idx')

            self.render(
                "inspector.html",
                **{'variables': inspector.get_variables(notebook, cell_index)})
        else:
            raise HTTPError(400, 'no_cmd')
コード例 #3
0
ファイル: command_handler.py プロジェクト: QCDIS/FAIRCells
    def post(self, image_name, command):
        if command == 'run':
            return self._run(image_name)
        elif command == 'stop':
            return self._stop(image_name)

        raise HTTPError(400, 'no_cmd')
コード例 #4
0
ファイル: omegacontentsmgr.py プロジェクト: omegaml/omegaml
 def _dir_model(self, path, content=True):
     """
     Build a model to return all of the files in gridfs
     if content is requested, will include a listing of the directory
     """
     # this looks like a seemingly simple task, it's carefully crafted
     path = unquote(path).strip('/')
     model = self._base_model(path, kind='directory')
     model['format'] = 'json'
     contents = model['content']
     # get existing entries from a pattern that matches either
     #    top-level files: ([\w -]+\.[\w -]*)
     #    directories (files in): ([\w ]+/([\w ]+\.[\w]*))
     # does not work:
     #    pattern = r'([\w ]+/_placeholder\.[\w]*)|([\w ]+\.[\w]*)$'
     #    it is too restrictive as entries can be generated without a placeholder
     # so we get all, which may include sub/sub/file
     # and we need to include them because we need to find sub/sub directories
     # note \w is any word character (letter, digit, underscore)
     #      \s is any white space
     #      \d is any digit
     #      :_  match literally
     #      [^\/]  matches any character except /
     #pattern = r'([\w\s\-.\d:()+]+\/)?([\w\s\-.\d:()+]+\.[\w]*)$'
     pattern = r'([^\/]+\/)?([^\/]+\.[^\/]*)$'
     # if we're looking in an existing directory, prepend that
     if path:
         pattern = r'{path}/{pattern}'.format(path=path, pattern=pattern)
     pattern = r'^{}'.format(pattern)
     entries = self.omega.jobs.list(regexp=pattern, raw=True, hidden=True, include_temp=True)
     if path and not entries:
         raise HTTPError(400, "Directory not found {}".format(path))
     # by default assume the current path is listed already
     directories = [path]
     for meta in entries:
         # get path of entry, e.g. sub/foo.ipynb => sub
         entry_path = os.path.dirname(meta.name)
         # if not part of listed directories yet, include
         if entry_path not in directories:
             entry = self._base_model(entry_path, kind='directory')
             contents.append(entry)
             directories.append(entry_path)
         # ignore placeholder files
         if meta.name.endswith(self._dir_placeholder):
             continue
         # only include files that are in the path we're listing
         if entry_path != path:
             continue
         # include the actual file
         try:
             entry = self._notebook_model(meta.name, content=content, meta=meta)
         except Exception as e:
             msg = ('_dir_model error, cannot get {}, '
                    'removing from list, exception {}'.format(meta.name, str(e)))
             self.log.warning(msg)
         else:
             contents.append(entry)
     return model
コード例 #5
0
ファイル: omegacontentsmgr.py プロジェクト: adbmd/omegaml
    def _save_file(self, os_path, content, format):
        """Save content of a generic file."""
        if format not in {'text', 'base64'}:
            raise HTTPError(
                400,
                "Must specify format of file contents as 'text' or 'base64'",
            )
        try:
            if format == 'text':
                bcontent = content.encode('utf8')
            else:
                b64_bytes = content.encode('ascii')
                bcontent = decodebytes(b64_bytes)
        except Exception as e:
            raise HTTPError(400,
                            u'Encoding error saving %s: %s' % (os_path, e))

        self.omega.datasets.put(BytesIO(bcontent), os_path)
コード例 #6
0
    def post(self, path):
        notebook = self.contents_manager.get(path, content=True)
        notebook_path = os.path.join(os.getcwd(), path)

        notebook_name = "notebook.ipynb"

        body = self.get_json_body()

        image_name = body.get('imageName')
        base_image = body.get('baseImage')
        cell_index = int(body.get('cellIndex'))
        variables = body.get('variables', {})

        if image_name is None or base_image is None or cell_index is None:
            raise HTTPError(400, 'abc')

        requirements = body.get('environment', BASE_STRING)

        #  Create a temporary dir which will be our build context.
        with tempfile.TemporaryDirectory() as tmpdir:
            shutil.copyfile(notebook_path, tmpdir + "/" + notebook_name)

            #  Find the location of the FAIR-Cells module on disk
            #  So it can copy & install it in the container.
            dirname = os.path.dirname(__file__)
            nested_levels = len(__name__.split('.')) - 2
            module_path = os.path.join(dirname + '/..' * nested_levels)

            #  Copy helper to build context.
            shutil.copytree(module_path,
                            tmpdir + "/fair-cells/",
                            ignore=shutil.ignore_patterns(
                                '.ipynb_checkpoints', '__pycache__'))

            with open(tmpdir + "/environment.yml", "a") as reqs:
                reqs.write(requirements)

            with open(tmpdir + "/nb_helper_config.json", "a") as cfg:
                config = create_config(notebook_name, cell_index, variables)
                cfg.write(config)

            with open(tmpdir + "/.dockerignore", "a") as ignore:
                ignore.write("**/backend\n")
                ignore.write("**/frontend\n")

            cc = ContainerCreator(tmpdir, image_name, base_image)

            try:
                _, log = cc.build_container(cc.get_dockerfile())
            except docker.errors.BuildError as be:
                log = be.build_log

        logs = "".join([l['stream'] if 'stream' in l else '' for l in log])

        self.finish(json.dumps({'logs': logs}))
コード例 #7
0
ファイル: command_handler.py プロジェクト: QCDIS/FAIRCells
    def _run(self, image_name):
        body = self.get_json_body()
        port = self._int_body('port', 10000)

        if port is None:
            raise HTTPError(400, 'def')


        cc = DockerService()
        container = cc.run_container(port=port,image=image_name)

        self.finish(json.dumps({
            'data': container.status
        }))
コード例 #8
0
    def _run(self, image_name):
        body = self.get_json_body()
        port = self._int_body('port', 10000)

        if port is None:
            raise HTTPError(400, 'def')


        cc = ContainerCreator('.', image_name, None)
        container = cc.run_container(port)

        self.finish(json.dumps({
            'data': container.status
        }))
コード例 #9
0
ファイル: inspect_handler.py プロジェクト: QCDIS/FAIRCells
    def _get_inspector(self, notebook):
        kernel = notebook['content']['metadata']['kernelspec']['name']

        try:
            inspector_module = importlib.import_module(f'.inspection.{kernel}',
                                                       package="fair-cells")

            inspector = inspector_module.inspector()

            if inspector.available():
                return inspector
        except ModuleNotFoundError:
            pass

        raise HTTPError(501, 'inspector_unavailable')
コード例 #10
0
ファイル: omegacontentsmgr.py プロジェクト: omegaml/omegaml
 def _notebook_model(self, path, content=True, meta=None):
     """
     Build a notebook model
     if content is requested, the notebook content will be populated
     as a JSON structure (not double-serialized)
     """
     path = unquote(path).strip('/')
     model = self._base_model(path)
     model['type'] = 'notebook'
     # always add accurate created and modified
     meta = meta or self.omega.jobs.metadata(path)
     if meta is not None:
         model['created'] = meta.created
         model['last_modified'] = meta.modified
     if content:
         nb = self._read_notebook(path, as_version=4)
         if nb is None:
             raise HTTPError(400, "Cannot read non-file {}".format(path))
         self.mark_trusted_cells(nb, path)
         model['content'] = nb
         model['format'] = 'json'
         self.validate_notebook_model(model)
     return model
コード例 #11
0
ファイル: command_handler.py プロジェクト: QCDIS/FAIRCells
    def get(self, image_name, command):
        if command == 'status':
            return self._status(image_name)

        raise HTTPError(400, 'no_cmd')
コード例 #12
0
    def post(self, path):
        notebook = self.contents_manager.get(path, content=True)
        notebook_path = os.path.join(os.getcwd(), path)

        notebook_name = "notebook.ipynb"

        body = self.get_json_body()

        image_name = body.get('imageName')
        base_image = body.get('baseImage')
        cell_index = int(body.get('cellIndex'))
        variables = body.get('variables', {})
        logging.info("image_name: " + str(image_name))
        logging.info("base_image: " + str(base_image))
        logging.info("cell_index: " + str(cell_index))
        logging.info("variables: " + str(variables))
        if image_name is None or base_image is None or cell_index is None:
            raise HTTPError(400, 'abc')

        requirements = body.get('environment', BASE_STRING)

        #  Create a temporary dir which will be our build context.
        with tempfile.TemporaryDirectory() as tmpdir:
            shutil.copyfile(notebook_path, tmpdir + "/" + notebook_name)

            #  Find the location of the FAIR-Cells module on disk
            #  So it can copy & install it in the container.
            dirname = os.path.dirname(__file__)
            nested_levels = len(__name__.split('.')) - 2
            module_path = os.path.join(dirname + '/..' * nested_levels)

            #  Copy helper to build context.
            shutil.copytree(module_path,
                            tmpdir + "/fair-cells/",
                            ignore=shutil.ignore_patterns(
                                '.ipynb_checkpoints', '__pycache__'))

            with open(tmpdir + "/environment.yml", "a") as reqs:
                reqs.write(requirements)

            with open(tmpdir + "/environment.yml") as file:
                environment = yaml.load(file, Loader=yaml.FullLoader)

            lines = ''
            for requ in environment['dependencies'][0]['pip']:
                lines += requ + '\n'

            with open(tmpdir + '/requirements.txt', 'w') as f:
                f.write(lines)
            f.close()

            with open(tmpdir + "/nb_helper_config.json", "a") as cfg:
                config = create_config(notebook_name, cell_index, variables)
                cfg.write(config)

            with open(tmpdir + "/.dockerignore", "a") as ignore:
                ignore.write("**/backend\n")
                ignore.write("**/frontend\n")

            cc = DockerService()
            docker_file = cc.get_dockerfile(base_image)

        self.finish(json.dumps({'dockerFile': docker_file}))