Internal API

V2 Models

Base Model

class BaseModel

Base class for all models to be used with DEEPaaS.

Note that it is not needed for DEEPaaS to inherit from this abstract base class in order to expose the model functionality, but the entrypoint that is configured should expose the same API.

abstract get_metadata()

Return metadata from the exposed model.

The metadata that is expected should follow the schema that is shown below. This basically means that you should return a dictionary with the following aspect:

{
    "author": "Author name",
    "description": "Model description",
    "license": "Model's license",
    "url": "URL for the model (e.g. GitHub repository)",
    "version": "Model version",
}

If you want to integrate with the deephdc platform you should provide at least an [name, author, author-email, license]. You can nevertheless set them to None if you don’t feel like providing the information.

The schema that we are following is the following:

{
    "id": =  fields.Str(required=True,
                        description='Model identifier'),
    "name": fields.Str(required=True,
                       description='Model name'),
    "description": fields.Str(required=True,
                              description='Model description'),
    "license": fields.Str(required=False,
                          description='Model license'),
    "author": fields.Str(required=False,
                         description='Model author'),
    "version": fields.Str(required=False,
                          description='Model version'),
    "url": fields.Str(required=False,
                      description='Model url'),
    "links": fields.List(
        fields.Nested(
            {
                "rel": fields.Str(required=True),
                "href": fields.Url(required=True),
            }
        )
    )
}
Returns:

dictionary containing the model’s metadata.

abstract get_predict_args()

Return the arguments that are needed to perform a prediction.

This function should return a dictionary of webargs fields (check here for more information). For example:

from webargs import fields

(...)

def get_predict_args():
    return {
        "arg1": fields.Str(
            required=False,  # force the user to define the value
            missing="foo",  # default value to use
            enum=["choice1", "choice2"],  # list of choices
            description="Argument one"  # help string
        ),
    }
Return dict:

A dictionary of webargs fields containing the application required arguments.

abstract get_train_args()

Return the arguments that are needed to train the application.

This function should return a dictionary of webargs fields (check here for more information). For example:

from webargs import fields

(...)

def get_train_args():
    return {
        "arg1": fields.Str(
            required=False,  # force the user to define the value
            missing="foo",  # default value to use
            enum=["choice1", "choice2"],  # list of choices
            description="Argument one"  # help string
        ),
    }
Return dict:

A dictionary of webargs fields containing the application required arguments.

abstract predict(**kwargs)

Prediction from incoming keyword arguments.

Parameters:

kwargs – The keyword arguments that the predict method accepts must be defined by the get_predict_args() method so the API is able to pass them down.

Returns:

The response must be a str or a dict.

schema = None

Must contain a valid schema for the model’s predictions or None.

A valid schema is either a marshmallow.Schema subclass or a dictionary schema that can be converted into a schema.

In order to provide a consistent API specification we use this attribute to define the schema that all the prediction responses will follow, therefore: - If this attribute is set we will validate them against it. - If it is not set (i.e. schema = None), the model’s response will be converted into a string and the response will have the following form:

{
    "status": "OK",
    "predictions": "<model response as string>"
}

As previously stated, there are two ways of defining an schema here. If our response have the following form:

{
    "status": "OK",
    "predictions": [
        {
            "label": "foo",
            "probability": 1.0,
        },
        {
            "label": "bar",
            "probability": 0.5,
        },
    ]
}

We should define or schema as schema as follows:

  • Using a schema dictionary. This is the most straightforward way. In order to do so, you must use the marshmallow Python module, as follows:

    from marshmallow import fields
    
    schema = {
        "status": fields.Str(
                    description="Model predictions",
                    required=True
        ),
        "predictions": fields.List(
            fields.Nested(
                {
                    "label": fields.Str(required=True),
                    "probability": fields.Float(required=True),
                },
            )
        )
    }
    
  • Using a marshmallow.Schema subclass. Note that the schema must be the class that you have created, not an object:

    import marshmallow
    from marshmallow import fields
    
    class Prediction(marshmallow.Schema):
        label = fields.Str(required=True)
        probability = fields.Float(required=True)
    
    class Response(marshmallow.Schema):
        status = fields.Str(
            description="Model predictions",
            required=True
        )
        predictions = fields.List(fields.Nested(Prediction))
    
    schema = Response
    
abstract train(**kwargs)

Perform a training.

Parameters:

kwargs – The keyword arguments that the predict method accepts must be defined by the get_train_args() method so the API is able to pass them down. Usually you would populate these with all the training hyper-parameters

Returns:

You can return any Python object that is JSON parseable (eg. dict, string, float).

abstract warm()

Warm (initialize, load) the model.

This is called when the model is loaded, before the API is spawned.

If implemented, it should prepare the model for execution. This is useful for loading it into memory, perform any kind of preliminary checks, etc.

Model wrapper

V2 test model

class TestModel

Dummy model implementing minimal functionality.

This is a simple class that mimics the behaviour of a module, just for showing how the whole DEEPaaS works and documentation purposes.

get_metadata()

Return metadata from the exposed model.

The metadata that is expected should follow the schema that is shown below. This basically means that you should return a dictionary with the following aspect:

{
    "author": "Author name",
    "description": "Model description",
    "license": "Model's license",
    "url": "URL for the model (e.g. GitHub repository)",
    "version": "Model version",
}

If you want to integrate with the deephdc platform you should provide at least an [name, author, author-email, license]. You can nevertheless set them to None if you don’t feel like providing the information.

The schema that we are following is the following:

{
    "id": =  fields.Str(required=True,
                        description='Model identifier'),
    "name": fields.Str(required=True,
                       description='Model name'),
    "description": fields.Str(required=True,
                              description='Model description'),
    "license": fields.Str(required=False,
                          description='Model license'),
    "author": fields.Str(required=False,
                         description='Model author'),
    "version": fields.Str(required=False,
                          description='Model version'),
    "url": fields.Str(required=False,
                      description='Model url'),
    "links": fields.List(
        fields.Nested(
            {
                "rel": fields.Str(required=True),
                "href": fields.Url(required=True),
            }
        )
    )
}
Returns:

dictionary containing the model’s metadata.

get_predict_args()

Return the arguments that are needed to perform a prediction.

This function should return a dictionary of webargs fields (check here for more information). For example:

from webargs import fields

(...)

def get_predict_args():
    return {
        "arg1": fields.Str(
            required=False,  # force the user to define the value
            missing="foo",  # default value to use
            enum=["choice1", "choice2"],  # list of choices
            description="Argument one"  # help string
        ),
    }
Return dict:

A dictionary of webargs fields containing the application required arguments.

get_train_args()

Return the arguments that are needed to train the application.

This function should return a dictionary of webargs fields (check here for more information). For example:

from webargs import fields

(...)

def get_train_args():
    return {
        "arg1": fields.Str(
            required=False,  # force the user to define the value
            missing="foo",  # default value to use
            enum=["choice1", "choice2"],  # list of choices
            description="Argument one"  # help string
        ),
    }
Return dict:

A dictionary of webargs fields containing the application required arguments.

predict(**kwargs)

Prediction from incoming keyword arguments.

Parameters:

kwargs – The keyword arguments that the predict method accepts must be defined by the get_predict_args() method so the API is able to pass them down.

Returns:

The response must be a str or a dict.

schema = {'data': <fields.String(dump_default=<marshmallow.missing>, attribute=None, validate=None, required=False, load_only=False, dump_only=False, load_default=<marshmallow.missing>, allow_none=False, error_messages={'required': 'Missing data for required field.', 'null': 'Field may not be null.', 'validator_failed': 'Invalid value.', 'invalid': 'Not a valid string.', 'invalid_utf8': 'Not a valid utf-8 string.'})>, 'date': <fields.Date(dump_default=<marshmallow.missing>, attribute=None, validate=None, required=False, load_only=False, dump_only=False, load_default=<marshmallow.missing>, allow_none=False, error_messages={'required': 'Missing data for required field.', 'null': 'Field may not be null.', 'validator_failed': 'Invalid value.', 'invalid': 'Not a valid date.', 'invalid_awareness': 'Not a valid {awareness} {obj_type}.', 'format': '"{input}" cannot be formatted as a date.'})>, 'labels': <fields.List(dump_default=<marshmallow.missing>, attribute=None, validate=None, required=False, load_only=False, dump_only=False, load_default=<marshmallow.missing>, allow_none=False, error_messages={'required': 'Missing data for required field.', 'null': 'Field may not be null.', 'validator_failed': 'Invalid value.', 'invalid': 'Not a valid list.'})>}

Must contain a valid schema for the model’s predictions or None.

A valid schema is either a marshmallow.Schema subclass or a dictionary schema that can be converted into a schema.

In order to provide a consistent API specification we use this attribute to define the schema that all the prediction responses will follow, therefore: - If this attribute is set we will validate them against it. - If it is not set (i.e. schema = None), the model’s response will be converted into a string and the response will have the following form:

{
    "status": "OK",
    "predictions": "<model response as string>"
}

As previously stated, there are two ways of defining an schema here. If our response have the following form:

{
    "status": "OK",
    "predictions": [
        {
            "label": "foo",
            "probability": 1.0,
        },
        {
            "label": "bar",
            "probability": 0.5,
        },
    ]
}

We should define or schema as schema as follows:

  • Using a schema dictionary. This is the most straightforward way. In order to do so, you must use the marshmallow Python module, as follows:

    from marshmallow import fields
    
    schema = {
        "status": fields.Str(
                    description="Model predictions",
                    required=True
        ),
        "predictions": fields.List(
            fields.Nested(
                {
                    "label": fields.Str(required=True),
                    "probability": fields.Float(required=True),
                },
            )
        )
    }
    
  • Using a marshmallow.Schema subclass. Note that the schema must be the class that you have created, not an object:

    import marshmallow
    from marshmallow import fields
    
    class Prediction(marshmallow.Schema):
        label = fields.Str(required=True)
        probability = fields.Float(required=True)
    
    class Response(marshmallow.Schema):
        status = fields.Str(
            description="Model predictions",
            required=True
        )
        predictions = fields.List(fields.Nested(Prediction))
    
    schema = Response
    
train(*args, **kwargs)

Perform a training.

Parameters:

kwargs – The keyword arguments that the predict method accepts must be defined by the get_train_args() method so the API is able to pass them down. Usually you would populate these with all the training hyper-parameters

Returns:

You can return any Python object that is JSON parseable (eg. dict, string, float).

warm()

Warm (initialize, load) the model.

This is called when the model is loaded, before the API is spawned.

If implemented, it should prepare the model for execution. This is useful for loading it into memory, perform any kind of preliminary checks, etc.