Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can a Cerberus dependency reference a field higher up in the document?

I am trying to create a schema for documents that have dependencies that reference fields higher up in the document. For example:

document = {
    'packages': {
        'some-package': {'version': 1}
    },
    'build-steps': {
        'needs-some-package': {'foo': 'bar'},
        'other-thing': {'funky': 'stuff'}
    }
}

What I'm struggling with here is enforcing the dependency between build-steps.needs-some-package and packages.some-package. Whenever build-steps contains "needs-some-package", packages must contain "some-package".

When "needs-some-package" is not present, "some-package" is not required. So this document should also validate.

other_document = {
    'packages': {
        'other-package': {'version': 1}
    },
    'build-steps': {
        'other-thing': {'funky': 'stuff'}
    }
}

A schema with the dependency in what seems like the appropriate place is

schema = {
    'packages': {
        'type': 'dict',
        'valueschema': {
            'type': 'dict'
        }
    },
    'build-steps': {
        'type': 'dict',
        'schema': {
            'needs-some-package': {
                'type': 'dict',
                'dependencies': 'packages.some-package'
            },
            'other-thing': {
                'type': 'dict'
            }
        }
    }
}

But that doesn't work because it appears that Cerberus is looking for "packages" within the sub-document under "build-steps". Is there any way to go up the document tree? Or to reference something with respect to the root of the document?

like image 661
Dan Craig Avatar asked Nov 22 '16 18:11

Dan Craig


1 Answers

Described problem got resolved in version 1.0.2:

When a subdocument is processed the lookup for a field in question starts at the level of that document. In order to address the processed document as root level, the declaration has to start with a ^. An occurance of two initial carets (^^) is interpreted as a literal, single ^ with no special meaning.

Example code:

import cerberus

schema = {
    'packages': {
        'type': 'dict',
        'valueschema': {
            'type': 'dict'
        }
    },
    'build-steps': {
        'type': 'dict',
        'schema': {
            'needs-some-package': {
                'type': 'dict',
                'dependencies': '^packages.some-package'
            },
            'other-thing': {
                'type': 'dict'
            }
        }
    }
}

document = {
    'packages': {
        'some-package': {'version': 1}
    },
    'build-steps': {
        'needs-some-package': {'foo': 'bar'},
        'other-thing': {'funky': 'stuff'}
    }
}

validator = cerberus.Validator(schema)
print(validator.validate(document))
like image 135
Nykakin Avatar answered Nov 13 '22 18:11

Nykakin