예제 #1
0
def get_model(module, serve_model=False):
    import_name = prepare_import(module)

    try:
        module = importlib.import_module(import_name)
    except Exception as ex:
        logger.error(traceback.format_exc())
        return None

    serve_models = [
        v for v in module.__dict__.values() if isinstance(v, ServeModel)
    ]
    if len(serve_models) > 0 and serve_model:
        serve_model = serve_models[0]
        return serve_model
    apps = [v for v in module.__dict__.values() if isinstance(v, MLServer)]
    if len(apps) > 0:
        return apps[0]
    if len(serve_models) > 0:
        return serve_models[0]

    # Could not find model
    logger.debug("Could not find ServeModel")
    serve_models = [
        v for v in module.__dict__.values() if not isinstance(v, type)
    ]
    if len(serve_models) > 0 and serve_model:
        serve_model = ServeModel(serve_models[-1])
        return serve_model

    logger.error(
        "Could not find any instance to serve. So please check again the mlconfig.yaml or server file!"
    )
    return None
예제 #2
0
 def upload_file(self,
                 filename,
                 key,
                 bucket_name=None,
                 overwrite=False,
                 encrypt=False,
                 acl=None,
                 use_basename=False):
     """
     Uploads a local file to S3.
     Args:
         filename: `str`. name of the file to upload.
         key: `str`. S3 key that will point to the file.
         bucket_name: `str`. Name of the bucket in which to store the file.
         overwrite: `bool`. A flag to decide whether or not to overwrite the key
             if it already exists. If replace is False and the key exists, an
             error will be raised.
         encrypt: `bool`. If True, the file will be encrypted on the server-side
             by S3 and will be stored in an encrypted form while at rest in S3.
         acl: `str`. ACL to use for uploading, e.g. "public-read".
         use_basename: `bool`. whether or not to use the basename of the filename.
     """
     if not bucket_name:
         bucket_name = self.bucket
     if bucket_name is None:
         raise MlChainError("bucket can't be None",
                            code="S000",
                            status_code=500)
     if use_basename:
         key = os.path.join(key, os.path.basename(filename))
     try:
         self.client.upload_file(filename, bucket_name, key)
     except Exception as ex:
         logger.error(str(ex))
         raise MlChainError(str(ex), code="S005", status_code=500)
예제 #3
0
 def download_cv2(self, key, bucket_name=None):
     """
     Download a file from S3.
     Args:
         key: `str`. S3 key that will point to the file.
         local_path: `str`. the path to download to.
         bucket_name: `str`. Name of the bucket in which to store the file.
         use_basename: `bool`. whether or not to use the basename of the key.
     """
     if not bucket_name:
         bucket_name = self.bucket
     if bucket_name is None:
         raise MlChainError("bucket can't be None",
                            code="S000",
                            status_code=500)
     try:
         buffer = BytesIO()
         self.client.download_fileobj(bucket_name, key, buffer)
         cv2 = import_cv2()
         return cv2.imdecode(
             np.asarray(bytearray(buffer.getvalue()), dtype="uint8"),
             cv2.IMREAD_COLOR)
     except Exception as ex:
         logger.error(str(ex))
         raise MlChainError(str(ex), code="S003", status_code=500)
예제 #4
0
def get_model(module, serve_model=False, queue=None, trace=False, name=None):
    import_name = prepare_import(module)

    module = importlib.import_module(import_name)
    serve_models = [
        v for v in module.__dict__.values() if isinstance(v, ServeModel)
    ]
    if len(serve_models) > 0 and serve_model:
        serve_model = serve_models[0]
        if queue == 'rabbit':
            logger.debug('load rabbit {0}'.format(serve_model))
            from mlchain.queue.rabbit_queue import RabbitQueue
            if not isinstance(serve_model, RabbitQueue):
                serve_model = RabbitQueue(serve_model,
                                          module_name=name,
                                          trace=trace)
            serve_model.run(threading=True)
        elif queue == 'redis':
            logger.debug('load redis {0}'.format(serve_model))
            from mlchain.queue.redis_queue import RedisQueue
            if not isinstance(serve_model, RedisQueue):
                serve_model = RedisQueue(serve_model,
                                         module_name=name,
                                         trace=trace)
            serve_model.run(threading=True)
        return serve_model
    apps = [v for v in module.__dict__.values() if isinstance(v, MLServer)]
    if len(apps) > 0:
        return apps[0]
    if len(serve_models) > 0:
        return serve_models[0]

    # Could not find model
    logger.debug("Could not find ServeModel")
    serve_models = [
        v for v in module.__dict__.values() if not isinstance(v, type)
    ]
    if len(serve_models) > 0 and serve_model:
        serve_model = ServeModel(serve_models[-1])
        if queue == 'rabbit':
            logger.debug('Load rabbit {0}'.format(serve_model))
            from mlchain.queue.rabbit_queue import RabbitQueue
            if not isinstance(serve_model, RabbitQueue):
                serve_model = RabbitQueue(serve_model,
                                          module_name=name,
                                          trace=trace)
            serve_model.run(threading=True)
        elif queue == 'redis':
            logger.debug('load redis {0}'.format(serve_model))
            from mlchain.queue.redis_queue import RedisQueue
            if not isinstance(serve_model, RedisQueue):
                serve_model = RedisQueue(serve_model,
                                         module_name=name,
                                         trace=trace)
            serve_model.run(threading=True)
        return serve_model

    logger.error("Could not find any instance to serve")
    return None
예제 #5
0
def register_autofrontend(model_id,
                          serve_model,
                          version='latest',
                          endpoint=None):
    mlchain_management = os.getenv('MLCHAIN_URL', None)
    if endpoint is None:
        endpoint = ''
    autofrontend_template = AutofrontendConfig()
    if serve_model.config is not None:
        out_configs = serve_model.config
    else:
        out_configs = {}
    for name, func in serve_model.get_all_func().items():
        if name in out_configs:
            out_config = out_configs[name]
            if 'config' in out_config:
                config = out_config['config']
            else:
                config = None
        else:
            config = None
        autofrontend_template.add_endpoint(func,
                                           f'{endpoint}/call/{name}',
                                           output_config=config)
    if os.path.exists("Readme.md"):
        description = open("Readme.md", encoding='utf-8').read()
    else:
        description = ""

    if os.path.exists("changelog.md"):
        changelog = open("changelog.md", encoding='utf-8').read()
    else:
        changelog = ""

    if mlchain_management and model_id is not None:
        config_version = {
            "model_id": model_id,
            "version": version,
            "input_config": autofrontend_template.input_config,
            "output_config": autofrontend_template.output_config,
            'endpoint': endpoint,
            'readme': description,
            'changelog': changelog
        }
        try:
            import requests
            res = requests.post(f'{mlchain_management}/version/create',
                                json=config_version)
            logger.info(str(res.json()))
        except Exception as ex:
            logger.error(ex)
예제 #6
0
 def download_bytes(self, key, bucket_name=None, use_basename=True):
     """
     Download a file from S3.
     Args:
         key: `str`. S3 key that will point to the file.
         local_path: `str`. the path to download to.
         bucket_name: `str`. Name of the bucket in which to store the file.
         use_basename: `bool`. whether or not to use the basename of the key.
     """
     if not bucket_name:
         bucket_name = self.bucket
     if bucket_name is None:
         raise MlChainError("bucket can't be None",
                            code="S000",
                            status_code=500)
     try:
         buffer = BytesIO()
         self.client.download_fileobj(bucket_name, key, buffer)
         return buffer.getvalue()
     except Exception as ex:
         logger.error(str(ex))
         raise MlChainError(str(ex), code="S002", status_code=500)
예제 #7
0
 def download_dir(self, prefix, dir_path, bucket_name=None):
     bucket_name = bucket_name or self.bucket
     if bucket_name is None:
         raise MlChainError("bucket can't be None",
                            code="S000",
                            status_code=500)
     if prefix.endswith('/'):
         prefix = prefix[:-1]
     if len(prefix) > 0:
         prefix = '{0}/'.format(prefix)
     try:
         results = self.list(bucket_name=bucket_name, prefix=prefix)
         for file in results['keys']:
             self.download_file(prefix + file,
                                os.path.join(dir_path, file),
                                bucket_name=bucket_name)
         for dir in results['prefixes']:
             self.download_dir(prefix + dir,
                               os.path.join(dir_path, dir),
                               bucket_name=bucket_name)
     except Exception as ex:
         logger.error(str(ex))
         raise MlChainError(str(ex), code="S004", status_code=500)
예제 #8
0
 def download_file(self,
                   key,
                   local_path,
                   bucket_name=None,
                   use_basename=False):
     """
     Download a file from S3.
     Args:
         key: `str`. S3 key that will point to the file.
         local_path: `str`. the path to download to.
         bucket_name: `str`. Name of the bucket in which to store the file.
         use_basename: `bool`. whether or not to use the basename of the key.
     """
     if not bucket_name:
         bucket_name = self.bucket
     if bucket_name is None:
         raise MlChainError("bucket can't be None",
                            code="S000",
                            status_code=500)
     local_path = os.path.abspath(local_path)
     if use_basename:
         local_path = os.path.join(local_path, os.path.basename(key))
     dir_name = os.path.dirname(local_path)
     if not os.path.exists(dir_name):
         os.makedirs(dir_name)
     try:
         content_length = self.client.head_object(Bucket=bucket_name,
                                                  Key=key)["ContentLength"]
         progress = ProgressPercentage(key, content_length)
         self.client.download_file(bucket_name,
                                   key,
                                   local_path,
                                   Callback=progress)
         return True
     except Exception as ex:
         logger.error(str(ex))
         raise MlChainError(str(ex), code="S001", status_code=500)