Exemple #1
0
    def __init__(self, api_key=None, api_address=None, serializer='msgpack',
                 image_encoder=None, name=None, version='lastest',
                 check_status=False, headers=None, **kwargs):
        MLClient.__init__(self, api_key=api_key, api_address=api_address,
                          serializer=serializer, image_encoder=image_encoder,
                          name=name, version=version,
                          check_status=check_status, headers=headers, **kwargs)
        if isinstance(self.api_address, str):
            self.api_address = self.api_address.strip()
            if len(self.api_address) > 0 and self.api_address[-1] == '/':
                self.api_address = self.api_address[:-1]

            if len(self.api_address) > 0 and self.api_address[0] != 'h':
                self.api_address = 'http://{0}'.format(api_address)

        self.content_type = 'application/{0}'.format(self.serializer_type)
        if check_status:
            try:
                ping = self.get('ping', timeout=5)
                logger.info("Connected to server {0}: {1}".format(api_address, ping))
            except Exception as e:
                logger.info("Can't connect to server {0}: {1}".format(api_address, e))
            output_description = self.get('description', timeout=20)
            if 'error' in output_description:
                with except_handler():
                    raise AssertionError("ERROR: Model {0} in version {1} is not found".format(
                        name,
                        version))
            else:
                output_description = output_description['output']
                self.__doc__ = output_description['__main__']
                self.all_func_des = output_description['all_func_des']
                self.all_func_params = output_description['all_func_params']
                self.all_attributes = output_description['all_attributes']
Exemple #2
0
    def __init__(self,
                 api_key=None,
                 api_address=None,
                 serializer='msgpack',
                 image_encoder=None,
                 timeout=5 * 60,
                 name=None,
                 version='lastest',
                 check_status=False,
                 headers=None,
                 **kwargs):
        """
        Client to communicate with Mlchain server
        :api_key: Your API KEY
        :api_address: API or URL of server to communicate with
        :serializer: The way to serialize data ['json', 'msgpack', 'msgpack_blosc']
        """
        assert serializer in ['json', 'msgpack', 'msgpack_blosc']
        assert image_encoder in ['jpg', 'png', None]

        if api_key is None and os.getenv('MLCHAIN_API_KEY') is not None:
            api_key = os.getenv('MLCHAIN_API_KEY')
        self.api_key = api_key
        self.name = name
        self.version = version
        self.chek_status = check_status
        if api_address is None:
            if os.getenv('MLCHAIN_API_ADDRESS') is not None:
                api_address = os.getenv('MLCHAIN_API_ADDRESS')
            else:
                api_address = mlchain.API_ADDRESS
        self.api_address = api_address
        self.headers = headers or dict
        self.json_serializer = JsonSerializer()

        # Serializer initalization
        self.serializer_type = serializer
        try:
            if serializer == 'msgpack':
                if image_encoder is None:
                    self.serializer = MsgpackSerializer()
                elif image_encoder == 'jpg':
                    self.serializer = JpgMsgpackSerializer()
                elif image_encoder == 'png':
                    self.serializer = PngMsgpackSerializer()
            elif serializer == 'msgpack_blosc':
                self.serializer = MsgpackBloscSerializer()
            else:
                self.serializer_type = 'json'
                self.serializer = self.json_serializer
        except:
            logger.info("{0} not found, using json instead".format(serializer))
            self.serializer_type = 'json'
            self.serializer = self.json_serializer

        self.image_encoder = image_encoder
        self._cache = {}
        self.store_ = None
        self.all_func_des = None
        self.all_func_params = None
        self.all_attributes = None
        self.timeout = timeout
    def run(self, host='127.0.0.1', port=8080, bind=None, cors=False, cors_resources={},
            cors_allow_origins='*', gunicorn=False, debug=False,
            use_reloader=False, workers=1, timeout=60, keepalive=10,
            max_requests=0, threads=1, worker_class='gthread', umask='0',
            ngrok=False, model_id=None, **kwargs):
        """
        Run a server from a Python class
        :model: Your model class
        :host: IP address you want to start server
        :port: Port to start server at
        :bind: Gunicorn: The socket to bind. A list of string or string of the form: HOST, HOST:PORT, unix:PATH, fd://FD. An IP is a valid HOST.
        :deny_all_function: Default is False, which enable all function except function with @except_serving or function in blacklist, True is deny all and you could use with whitelist
        :blacklist: All listing function name here won't be served
        :whitelist: Served all function name inside whitelist
        :cors: Enable CORS or not
        :cors_resources: Config Resources of flask-cors
        :cors_allow_origins: Allow host of cors
        :gunicorn: Run with Gunicorn or not
        :debug: Debug or not
        :use_reloader: Default False, which is using 1 worker in debug instead of 2
        :workers: Number of workers to run Gunicorn
        :timeout: Timeout of each request
        :keepalive: The number of seconds to wait for requests on a Keep-Alive connection.
        :threads: The number of worker threads for handling requests. Be careful, threads would break your result if it is bigger than 1
        :worker_class: The type of workers to use.
        :max_requests: Max Request to restart Gunicorn Server, default is 0 which means no restart
        :umask: A bit mask for the file mode on files written by Gunicorn.
        :kwargs: Other Gunicorn options
        """
        try:
            self.register_swagger()
        except Exception as ex:
            logger.error("Can't register swagger with error {0}".format(ex))

        if ngrok:
            from pyngrok import ngrok as pyngrok
            endpoint = pyngrok.connect(port=port)
            logger.info("Ngrok url: {0}".format(endpoint))
            os.environ['NGROK_URL'] = endpoint
        else:
            endpoint = os.environ.get('NGROK_URL')

        try:
            register_autofrontend(model_id=model_id, serve_model=self.model,
                                  version=self.version,
                                  endpoint=endpoint)
        except Exception as ex:
            logger.error("Can't register autofrontend with error {0}".format(ex))

        if cors:
            CORS(self.app, resources=cors_resources, origins=cors_allow_origins)
        
        if not gunicorn:
            if bind is not None:
                if isinstance(bind, str):
                    bind = [bind]
                if isinstance(bind, list):
                    for ip_port in bind:
                        if re.match(r'(localhost:|((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|:)){4})\d+', ip_port):
                            logger.warning("Using host and port in bind to runserver")
                            host, port = ip_port.split(":")

            logger.info("-" * 80)
            logger.info("Served model with Flask at host={0}, port={1}".format(host, port))
            logger.info("Debug = {}".format(debug))
            logger.info("-" * 80)

            self.app.run(host=host, port=port, debug=debug,
                         use_reloader=use_reloader, threaded=threads > 1)
        else:
            # Process bind, host, port
            if isinstance(bind, str):
                bind = [bind]

            bind_host_port = '%s:%s' % (host, port)
            if bind is None:
                bind = [bind_host_port]

            logger.info("-" * 80)
            logger.info("Served model with Flask and Gunicorn at bind={}".format(bind))
            logger.info("Number of workers: {}".format(workers))
            logger.info("Number of threads: {}".format(threads))
            logger.info("API timeout: {}".format(timeout))
            logger.info("Debug = {}".format(debug))
            logger.info("-" * 80)

            loglevel = kwargs.get('loglevel', 'warning' if debug else 'info')
            
            GunicornWrapper(self.app, bind=bind, workers=workers, timeout=timeout,
                            keepalive=keepalive, max_requests=max_requests,
                            loglevel=loglevel, worker_class=worker_class,
                            threads=threads, umask=umask, **kwargs).run()