Example #1
0
    def from_dict(doc: Dict, validate: bool = True) -> File:
        """Get file parameter instance from a dictionary serialization.

        Parameters
        ----------
        doc: dict
            Dictionary serialization for file parameter declaration.
        validate: bool, default=True
            Validate the serialized object if True.

        Returns
        -------
        flowserv.model.parameter.files.File

        Raises
        ------
        flowserv.error.InvalidParameterError
        """
        if validate:
            util.validate_doc(doc,
                              mandatory=pd.MANDATORY,
                              optional=pd.OPTIONAL + ['target'],
                              exception=err.InvalidParameterError)
            if doc[pd.TYPE] != PARA_FILE:
                raise ValueError("invalid type '{}'".format(doc[pd.TYPE]))
        return File(name=doc[pd.NAME],
                    index=doc[pd.INDEX],
                    label=doc.get(pd.LABEL),
                    help=doc.get(pd.HELP),
                    default=doc.get(pd.DEFAULT),
                    required=doc[pd.REQUIRED],
                    group=doc.get(pd.GROUP),
                    target=doc.get('target'))
Example #2
0
    def from_dict(cls, doc, validate=True):
        """Get an instance of the sort column from the dictionary serialization.
        Raises an error if the given dictionary does not contain the expected
        elements as generated by the to_dict() method of the class.

        Parameters
        ----------
        doc: dict
            Dictionary serialization of a column object
        validate: bool, default=True
            Validate the serialization if True.

        Returns
        -------
        flowserv.model.template.schema.SortColumn

        Raises
        ------
        flowserv.error.InvalidTemplateError
        """
        # Validate the serialization dictionary
        if validate:
            try:
                util.validate_doc(
                    doc,
                    mandatory=['name'],
                    optional=['sortDesc']
                )
            except ValueError as ex:
                raise err.InvalidTemplateError(str(ex))
        sort_desc = None
        if 'sortDesc' in doc:
            sort_desc = doc['sortDesc']
        # Return instance of the column object
        return cls(column_id=doc['name'], sort_desc=sort_desc)
Example #3
0
    def from_dict(cls, doc, validate=True):
        """Create object instance from dictionary serialization.

        Parameters
        ----------
        doc: dict
            Dictionary serialization for a workflow output file.
        validate: bool, default=True
            Validate the serialization if True.

        Returns
        -------
        flowserv.model.template.files.WorkflowOutputFile

        Raises
        ------
        ValueError
        """
        if validate:
            # Validate the document if the respective flag is True.
            util.validate_doc(
                doc=doc,
                mandatory=['source'],
                optional=['key', 'title', 'caption', 'widget', 'format'])
        return cls(source=doc['source'],
                   key=doc.get('key'),
                   title=doc.get('title'),
                   caption=doc.get('caption'),
                   format=doc.get('format'),
                   widget=doc.get('widget'))
Example #4
0
def validate_workflow_handle(doc):
    """Validate serialization of a workflow handle. Here we distinguish between
    handles that have optional elements (description and instructions) and
    those that have not.

    Parameters
    ----------
    doc: dict
        Workflow handle serialization.

    Raises
    ------
    ValueError
    """
    # Note: The parameter groups element is optional but it should be contained
    # in all local test cases. That is the reason why it is in the list of
    # mandatory elements here.
    mandatory = ['id', 'name', 'parameters', 'parameterGroups']
    util.validate_doc(doc=doc,
                      mandatory=mandatory,
                      optional=[
                          'description', 'instructions', 'groups', 'postproc',
                          'outputs'
                      ])
    # Validate the post-processing run handle if present
    if 'postproc' in doc:
        postproc = doc['postproc']
        validate_run_handle(doc=postproc, state=postproc['state'])
Example #5
0
    def from_dict(doc: Dict, validate: Optional[bool] = True) -> Actor:
        """Get an actor parameter instance from a given dictionary
        serialization.

        Parameters
        ----------
        doc: dict
            Dictionary serialization for string parameter delaration.
        validate: bool, default=True
            Validate the serialized object if True.

        Returns
        -------
        flowserv.model.parameter.string.String

        Raises
        ------
        flowserv.error.InvalidParameterError
        """
        if validate:
            util.validate_doc(doc,
                              mandatory=pd.MANDATORY,
                              optional=pd.OPTIONAL,
                              exception=err.InvalidParameterError)
            if doc[pd.TYPE] != PARA_ACTOR:
                raise ValueError("invalid type '{}'".format(doc[pd.TYPE]))
        return Actor(name=doc[pd.NAME],
                     index=doc[pd.INDEX],
                     label=doc.get(pd.LABEL),
                     help=doc.get(pd.HELP),
                     default=doc.get(pd.DEFAULT),
                     required=doc[pd.REQUIRED],
                     group=doc.get(pd.GROUP))
Example #6
0
def is_fh(value: Any) -> bool:
    """Check whether an argument value is a serialization of an input file.
    Expects a dictionary with the following schema:

    {'type': '$file', 'value': {'fileId': 'string', 'targetPath': 'string'}}

    The target path is optional.

    Parameters
    ----------
    value: any
        User provided argument value.

    Returns
    -------
    bool
    """
    if not isinstance(value, dict):
        return False
    try:
        util.validate_doc(value, mandatory=['type', 'value'])
        assert value['type'] == '$file'
        util.validate_doc(
            value['value'],
            mandatory=['fileId'],
            optional=['targetPath']
        )
        return True
    except ValueError:
        pass
    return False
Example #7
0
def validate_file_handle(doc):
    """Validate serialization of a file handle.

    Parameters
    ----------
    doc: dict
        File handle serialization

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc, mandatory=['id', 'name', 'createdAt', 'size'])
Example #8
0
def validate_run_descriptor(doc):
    """Validate serialization of  run descriptor.

    Parameters
    ----------
    doc: dict
        Run handle serialization

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc, mandatory=['id', 'state', 'createdAt'])
Example #9
0
def validate_reset_request(doc):
    """Validate serialization of a user password reset request.

    Parameters
    ----------
    doc: dict
        Reset request response serialization

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc, mandatory=['requestId'])
Example #10
0
def validate_para_module(doc):
    """Validate serialization of a workflow parameter module handle.

    Parameters
    ----------
    doc: dict
        Workflow parameter module handle serialization

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc, mandatory=['name', 'title', 'index'])
Example #11
0
    def cast(self, value: Any) -> Dict:
        """Convert the given value into a record. Returns a dictionary that is
        a mapping of filed identifier to the converted values returned by the
        respective parameter declaration.

        Expects a list of dictionaries containing two elements: 'name' and
        'value'. The name identifies the record field and the value is the
        argument value for that field.

        Raises an error if the value is not a list, if any of the dictionaries
        are not well-formed, if required fields are not present in the given list,
        or if the respective parameter declaration for a record fields raised an
        exception during cast.

        Parameters
        ----------
        value: any
            User-provided value for a template parameter.

        Returns
        -------
        sting

        Raises
        ------
        flowserv.error.InvalidArgumentError
        """
        if not isinstance(value, list):
            raise err.InvalidArgumentError('invalid argument type')
        result = dict()
        # Cast all given values using their respective parameter declaration.
        for obj in value:
            util.validate_doc(obj,
                              mandatory=['name', 'value'],
                              exception=err.InvalidArgumentError)
            name = obj['name']
            if name not in self.fields:
                raise err.InvalidArgumentError(
                    "unknown argument '{}'".format(name))
            result[name] = self.fields[name].cast(obj['value'])
        # Add default values for missing fields.
        for key, para in self.fields.items():
            if key not in result:
                if para.default is not None:
                    result[key] = para.cast(para.default)
                elif para.required:
                    raise err.InvalidArgumentError(
                        "missing field '{}'".format(key))
        return result
Example #12
0
def validate_user_listing(doc):
    """Validate serialization of a user listing.

    Parameters
    ----------
    doc: dict
        Serialization for listing of user descriptors

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc, mandatory=['users'])
    for user in doc['users']:
        util.validate_doc(doc=user, mandatory=['id', 'username'])
Example #13
0
def validate_parameter(doc):
    """Validate serialization of a workflow parameter.

    Parameters
    ----------
    doc: dict
        Parameter serialization

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc,
                      mandatory=pd.MANDATORY,
                      optional=pd.OPTIONAL + ['target', 'values', 'range'])
Example #14
0
def validate_group_listing(doc):
    """Validate serialization of a workflow group listing.

    Parameters
    ----------
    doc: dict
        Listing of workflow group descriptor serializations

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc, mandatory=['groups'])
    for g in doc['groups']:
        util.validate_doc(doc=g, mandatory=['id', 'name', 'workflow'])
Example #15
0
def validate_run_listing(doc):
    """Validate serialization of a workflow run listing.

    Parameters
    ----------
    doc: dict
        Serialization for listing of workflow run descriptors

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc, mandatory=['runs'])
    for r in doc['runs']:
        validate_run_descriptor(doc=r)
Example #16
0
def test_validate_doc():
    """Test document validation with custom error classes."""
    doc = {'name': 'A', 'value': 1}
    assert util.validate_doc(doc, mandatory=['name', 'value'])
    assert util.validate_doc(doc, mandatory=['name'], optional=['value'])
    assert util.validate_doc(doc, mandatory=['name', 'value'], optional=['id'])
    with pytest.raises(ValueError):
        util.validate_doc(doc, mandatory=['name'])
    with pytest.raises(ValueError):
        util.validate_doc(doc, mandatory=['name', 'value', 'id'])
    with pytest.raises(err.InvalidArgumentError):
        util.validate_doc(doc, mandatory=['name'], exception=err.InvalidArgumentError)
Example #17
0
def jsonbody(request, mandatory=None, optional=None) -> Dict:
    """Get Json object from the body of an API request. Validates the object
    based on the given (optional) lists of mandatory and optional labels.

    Returns the JSON object (dictionary). Raises an error if an invalid request
    or body is given.

    Parameters
    ----------
    request: flask.request
        HTTP request
    mandatory: list(string)
        List of mandatory labels for the dictionary serialization
    optional: list(string), optional
        List of optional labels for the dictionary serialization

    Returns
    -------
    dict

    Raises
    ------
    robflask.error.InvalidRequest
    """
    try:
        return validate_doc(request.json,
                            mandatory=mandatory,
                            optional=optional)
    except (AttributeError, TypeError, ValueError) as ex:
        raise err.InvalidRequestError(str(ex))
Example #18
0
def validate_group_handle(doc):
    """Validate serialization of a workflow group handle.

    Parameters
    ----------
    doc: dict
        Workflow group handle serialization

    Raises
    ------
    ValueError
    """
    util.validate_doc(
        doc=doc,
        mandatory=['id', 'name', 'workflow', 'members', 'parameters', 'files'],
        optional=['runs', 'config'])
Example #19
0
def validate_workflow_listing(doc):
    """Validate serialization of a workflow descriptor listing.

    Parameters
    ----------
    doc: dict
        Serialization for listing of workflow descriptors

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc, mandatory=['workflows'])
    for wf in doc['workflows']:
        util.validate_doc(doc=wf,
                          mandatory=['id', 'name'],
                          optional=['description', 'instructions'])
Example #20
0
    def from_dict(doc: Dict, validate: Optional[bool] = True) -> Select:
        """Get select parameter instance from a dictionary serialization.

        Parameters
        ----------
        doc: dict
            Dictionary serialization for select parameter declaration.
        validate: bool, default=True
            Validate the serialized object if True.

        Returns
        -------
        flowserv.model.parameter.enum.Select

        Raises
        ------
        flowserv.error.InvalidParameterError
        """
        if validate:
            util.validate_doc(
                doc,
                mandatory=pd.MANDATORY + ['values'],
                optional=pd.OPTIONAL,
                exception=err.InvalidParameterError
            )
            for val in doc['values']:
                util.validate_doc(
                    val,
                    mandatory=['name', 'value'],
                    optional=['isDefault'],
                    exception=err.InvalidParameterError
                )
            if doc[pd.TYPE] != PARA_SELECT:
                raise ValueError("invalid type '{}'".format(doc[pd.TYPE]))
        return Select(
            name=doc[pd.NAME],
            index=doc[pd.INDEX],
            label=doc.get(pd.LABEL),
            help=doc.get(pd.HELP),
            default=doc.get(pd.DEFAULT),
            required=doc[pd.REQUIRED],
            group=doc.get(pd.GROUP),
            values=doc['values']
        )
Example #21
0
    def from_dict(doc: Dict, validate: Optional[bool] = True) -> Numeric:
        """Get numeric parameter instance from a dictionary serialization.

        Parameters
        ----------
        doc: dict
            Dictionary serialization for numeric parameter.
        validate: bool, default=True
            Validate the serialized object if True.

        Returns
        -------
        flowserv.model.parameter.numeric.Numeric

        Raises
        ------
        flowserv.error.InvalidParameterError
        """
        if validate:
            try:
                util.validate_doc(doc,
                                  mandatory=pd.MANDATORY,
                                  optional=pd.OPTIONAL + ['range'])
                constraint = None
                if 'range' in doc:
                    constraint = RangeConstraint.from_string(doc['range'])
            except (ValueError, TypeError) as ex:
                raise err.InvalidParameterError(str(ex))
        try:
            constraint = None
            if 'range' in doc:
                constraint = RangeConstraint.from_string(doc['range'])
        except (ValueError, TypeError) as ex:
            raise err.InvalidParameterError(str(ex))
        return Numeric(dtype=doc[pd.TYPE],
                       name=doc[pd.NAME],
                       index=doc[pd.INDEX],
                       label=doc.get(pd.LABEL),
                       help=doc.get(pd.HELP),
                       default=doc.get(pd.DEFAULT),
                       required=doc[pd.REQUIRED],
                       group=doc.get(pd.GROUP),
                       constraint=constraint)
Example #22
0
def validate_file_listing(doc, count):
    """Validate serialization of a file listing. The count parameter gives the
    expected number of files in the listing.

    Parameters
    ----------
    doc: dict
        Listing of file handle serializations
    count: int
        Expected number of files in the listing

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc, mandatory=['files'])
    assert len(doc['files']) == count
    for fh in doc['files']:
        validate_file_handle(fh)
Example #23
0
def validate_run_handle(doc, state):
    """Validate serialization of a run handle.

    Parameters
    ----------
    doc: dict
        Run handle serialization
    state: string
        Expected run state

    Raises
    ------
    ValueError
    """
    labels = ['id', 'workflowId', 'state', 'createdAt', 'arguments']
    if state == st.STATE_RUNNING:
        labels.append('startedAt')
    elif state in [st.STATE_ERROR, st.STATE_CANCELED]:
        labels.append('startedAt')
        labels.append('finishedAt')
        labels.append('messages')
    elif state == st.STATE_SUCCESS:
        labels.append('startedAt')
        labels.append('finishedAt')
        labels.append('files')
    util.validate_doc(
        doc=doc,
        mandatory=labels,
        optional=['parameters', 'groupId']
    )
    if 'parameters' in doc:
        for p in doc['parameters']:
            validate_parameter(p)
    assert doc['state'] == state
    if state == st.STATE_SUCCESS:
        for r in doc['files']:
            util.validate_doc(
                doc=r,
                mandatory=['id', 'name'],
                optional=['title', 'caption', 'mimeType', 'widget', 'format']
            )
Example #24
0
def validate_user_handle(doc, login, inactive=False):
    """Validate serialization of a user handle. Serialization depends on
    whether the user is currently logged in or not.

    Parameters
    ----------
    doc: dict
        User handle serialization
    login: bool
        Flag indicating whether the handle is for a user that is logged in
    inactive: bool, optional
        Flag indicating whether the user account has been activated yet

    Raises
    ------
    ValueError
    """
    mandatory = ['id', 'username']
    if login:
        mandatory.append('token')
    util.validate_doc(doc=doc, mandatory=mandatory)
Example #25
0
    def from_dict(cls, doc, validate=True):
        """Create object instance from dictionary serialization.

        Parameters
        ----------
        doc: dict
            Dictionary serialization for parameter group handles
        validate: bool, default=True
            Validate the serialization if True.

        Returns
        -------
        flowserv.model.parameter.base.ParameterGroup

        Raises
        ------
        ValueError
        """
        if validate:
            util.validate_doc(doc, mandatory=['name', 'title', 'index'])
        return cls(name=doc['name'], title=doc['title'], index=doc['index'])
Example #26
0
    def from_dict(doc: Dict, validate: Optional[bool] = True) -> List:
        """Get list parameter instance from a dictionary serialization.

        Parameters
        ----------
        doc: dict
            Dictionary serialization for a list parameter declaration.
        validate: bool, default=True
            Validate the serialized object if True.

        Returns
        -------
        flowserv.model.parameter.list.List

        Raises
        ------
        flowserv.error.InvalidParameterError
        """
        if validate:
            util.validate_doc(
                doc,
                mandatory=pd.MANDATORY + ['para'],
                optional=pd.OPTIONAL,
                exception=err.InvalidParameterError
            )
            if doc[pd.TYPE] != PARA_LIST:
                raise ValueError("invalid type '{}'".format(doc[pd.TYPE]))
        # Deserialize parameter declaration. Import the deserializer here to
        # avoid cyclic dependencies.
        from flowserv.model.parameter.factory import ParameterDeserializer as deserializer
        return Array(
            name=doc[pd.NAME],
            para=deserializer.from_dict(doc['para'], validate=validate),
            index=doc[pd.INDEX],
            label=doc.get(pd.LABEL),
            help=doc.get(pd.HELP),
            default=doc.get(pd.DEFAULT),
            required=doc[pd.REQUIRED],
            group=doc.get(pd.GROUP)
        )
Example #27
0
    def from_dict(doc: Dict, validate: Optional[bool] = True) -> Record:
        """Get record parameter instance from a given dictionary serialization.

        Parameters
        ----------
        doc: dict
            Dictionary serialization for record parameter declaration.
        validate: bool, default=True
            Validate the serialized object if True.

        Returns
        -------
        flowserv.model.parameter.record.Record

        Raises
        ------
        flowserv.error.InvalidParameterError
        """
        if validate:
            util.validate_doc(doc,
                              mandatory=pd.MANDATORY + ['fields'],
                              optional=pd.OPTIONAL,
                              exception=err.InvalidParameterError)
            if doc[pd.TYPE] != PARA_RECORD:
                raise ValueError("invalid type '{}'".format(doc[pd.TYPE]))
        # Deserialize parameter declarations for record fields. Import the
        # deserializer here to avoid cyclic dependencies.
        from flowserv.model.parameter.factory import ParameterDeserializer as deserializer
        fields = list()
        for obj in doc['fields']:
            fields.append(deserializer.from_dict(obj, validate=validate))
        return Record(name=doc[pd.NAME],
                      fields=fields,
                      index=doc[pd.INDEX],
                      label=doc.get(pd.LABEL),
                      help=doc.get(pd.HELP),
                      default=doc.get(pd.DEFAULT),
                      required=doc[pd.REQUIRED],
                      group=doc.get(pd.GROUP))
Example #28
0
    def from_dict(cls, doc, validate=True):
        """Get an instance of the column from the dictionary serialization.
        Raises an error if the given dictionary does not contain the expected
        elements as generated by the to_dict() method of the class.

        Parameters
        ----------
        doc: dict
            Dictionary serialization of a column object
        validate: bool, default=True
            Validate the serialization if True.

        Returns
        -------
        flowserv.model.template.schema.ResultColumn

        Raises
        ------
        flowserv.error.InvalidTemplateError
        """
        # Validate the serialization dictionary.
        if validate:
            try:
                util.validate_doc(
                    doc,
                    mandatory=['name', 'label', 'dtype'],
                    optional=['path', 'required']
                )
            except ValueError as ex:
                raise err.InvalidTemplateError(str(ex))
        # Return instance of the column object
        return cls(
            column_id=doc['name'],
            name=doc['label'],
            dtype=doc['dtype'],
            path=doc.get('path'),
            required=doc.get('required')
        )
Example #29
0
def cancel_run(run_id):
    """Get handle for a given run. The user has to be a member of the run
    submission in order to be authorized to access the run.

    Parameters
    ----------
    run_id: string
        Unique run identifier

    Returns
    -------
    flask.response_class

    Raises
    ------
    flowserv.error.UnauthenticatedAccessError
    flowserv.error.UnauthorizedAccessError
    flowserv.error.UnknownWorkflowGroupError
    """
    # Get the access token first to raise an error immediately if no token is
    # present (to avoid unnecessarily instantiating the service API).
    token = ACCESS_TOKEN(request)
    # If the body contains a Json object verify that the object has the
    # mandatory element 'reason'
    reason = None
    if request.json:
        try:
            obj = util.validate_doc(request.json, mandatory=['reason'])
            reason = obj['reason']
        except ValueError as ex:
            raise err.InvalidRequestError(str(ex))
    from robflask.service import service
    with service(access_token=token) as api:
        # Authentication of the user from the expected api_token in the header
        # will fail if no token is given or if the user is not logged in.
        r = api.runs().cancel_run(run_id=run_id, reason=reason)
    return make_response(jsonify(r), 200)
Example #30
0
def validate_ranking(doc):
    """Validate serialization of a workflow evaluation ranking.

    Parameters
    ----------
    doc: dict
        Ranking serialization

    Raises
    ------
    ValueError
    """
    util.validate_doc(doc=doc,
                      mandatory=['schema', 'ranking'],
                      optional=['postproc', 'outputs'])
    # Schema columns
    for col in doc['schema']:
        util.validate_doc(doc=col, mandatory=['name', 'label', 'dtype'])
    # Run results
    for entry in doc['ranking']:
        util.validate_doc(doc=entry, mandatory=['run', 'group', 'results'])
        util.validate_doc(
            doc=entry['run'],
            mandatory=['id', 'createdAt', 'startedAt', 'finishedAt'])
        util.validate_doc(doc=entry['group'], mandatory=['id', 'name'])
        for result in entry['results']:
            util.validate_doc(doc=result, mandatory=['name', 'value'])