Skip to content

Commit

Permalink
Support for Cerberus 1.1
Browse files Browse the repository at this point in the history
(Based on original patch from dkellner)

This is a rather big change. I still decided to do a single commit, as
intermediate commits would be in a non-working state anyway.

Breaking changes:

- `keyschema` was renamed to `valueschema` and `propertyschema` to
  `keyschema` (following changes in Cerberus).
- A PATCH on a document which misses a field having a default value will
  now result in setting this value, even if the field was not provided
  in the PATCH's payload.
- Error messages for `keyschema` are now returned as dictionary.
  Before: {'propertyschema_dict': 'propertyschema_dict'}
  Now: {'keyschema_dict': {'AAA': "value does not match regex '[a-z]+'"}}
- Error messages for `type` validations are different now (following
  changes in Cerberus).
- It is no longer valid to have a field with `default` = None and
  `nullable` = False.
  (see patch.py:test_patch_nested_document_nullable_missing)

In a nutshell, changes to the codebase are as follows:

- Add data layer independent subclass of `cerberus.Validator`
  * Support new signature of `__init__` and `validate`
  * Use `_config`-aware properties instead of bare member attributes to
    pass the `resource`, `document_id` and `persisted_document` to make
    them available to child validators
  * Add schema-docstrings to all `_validate_*` methods

- Adjust Mongo-specific `Validator` subclass
  * Adjust `_validate_type_*` methods (following changes in Cerberus)
  * Add schema-docstrings to all `_validate_*` methods

- Add custom ErrorHandler to support `VALIDATION_ERROR_AS_LIST`

- A few renames:
  * `ValidationError` -> `DocumentError`
  * `propertyschema` -> `keyschema` and `keyschema` -> `valueschema`

- Adjust tests due to different validation error messages
  (mostly for `type`)

- Remove `transparent_schema_rules` without replacement
- Remove `default`-handling, as Cerberus takes care of this now
  • Loading branch information
dkellner authored and bcrochet committed May 18, 2017
1 parent a6b0c63 commit 1110f80
Show file tree
Hide file tree
Showing 23 changed files with 271 additions and 777 deletions.
14 changes: 14 additions & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,20 @@ Breaking Changes
``MONGO_CONNECT_TIMEOUT_MS``, ``MONGO_REPLICA_SET``,
``MONGO_READ_PREFERENCE`` removed. Use ``MONGO_OPTIONS`` or ``MONGO_URI``
instead.
- `keyschema` was renamed to `valueschema` and `propertyschema` to
`keyschema` (following changes in Cerberus).
- A PATCH on a document which misses a field having a default value will
now result in setting this value, even if the field was not provided
in the PATCH's payload.
- Error messages for `keyschema` are now returned as dictionary.
Before: {'propertyschema_dict': 'propertyschema_dict'}
Now: {'keyschema_dict': {'AAA': "value does not match regex '[a-z]+'"}}
- Error messages for `type` validations are different now (following
changes in Cerberus).
- It is no longer valid to have a field with `default` = None and
`nullable` = False.
(see patch.py:test_patch_nested_document_nullable_missing)
- See also: `Cerberus changes <https://cerberus.readthedocs.io/en/stable/upgrading.html>_`

Stable
------
Expand Down
8 changes: 2 additions & 6 deletions docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -370,9 +370,6 @@ uppercase.
:ref:`unknown` for more information.
Defaults to ``False``.

``TRANSPARENT_SCHEMA_RULES`` When ``True``, this option globally disables
:ref:`schema_validation` for any API endpoint.

``PROJECTION`` When ``True``, this option enables the
:ref:`projections` feature. Can be
overridden by resource settings. Defaults
Expand Down Expand Up @@ -1302,11 +1299,10 @@ defining the field validation rules. Allowed validation rules are:
for all of which must validate with given
schema. See `valueschema example <http://docs.python-cerberus.org/en/latest/usage.html#valueschema>`_.

``propertyschema`` This is the counterpart to ``valueschema`` that
``keyschema`` This is the counterpart to ``valueschema`` that
validates the keys of a dict. Validation
schema for all values of a ``dict``. See
`propertyschema example
<http://docs.python-cerberus.org/en/latest/usage.html#propertyschema>`_.
`keyschema example <http://docs.python-cerberus.org/en/latest/usage.html#keyschema>`_.


``regex`` Validation will fail if field value does not
Expand Down
6 changes: 2 additions & 4 deletions docs/tutorials/custom_idfields.rst
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,11 @@ details on custom validation):
"""
Extends the base mongo validator adding support for the uuid data-type
"""
def _validate_type_uuid(self, field, value):
def _validate_type_uuid(self, value):
try:
UUID(value)
except ValueError:
self._error(field, "value '%s' cannot be converted to a UUID" %
value)
pass
``UUID`` URLs
~~~~~~~~~~~~~
Expand Down
19 changes: 5 additions & 14 deletions docs/validation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -97,16 +97,13 @@ code.
.. code-block:: python
def _validate_type_objectid(self, field, value):
def _validate_type_objectid(self, value):
""" Enables validation for `objectid` schema attribute.
:param unique: Boolean, whether the field value should be
unique or not.
:param field: field name.
:param value: field value.
"""
if not re.match('[a-f0-9]{24}', value):
self._error(field, ERROR_BAD_TYPE % 'ObjectId')
if isinstance(value, ObjectId):
return True
This method enables support for MongoDB ``ObjectId`` type in your schema,
allowing something like this:
Expand Down Expand Up @@ -194,14 +191,8 @@ Schema validation
By default, schemas are validated to ensure they conform to the structure
documented in :ref:`schema`.
There are two ways to deal with non-conforming schemas:
1. Add :ref:`custom_validation_rules` for non-conforming keys used in the
schema.
2. Set the global option ``TRANSPARENT_SCHEMA_RULES`` to disable schema
validation globally or the resource option ``transparent_schema_rules``
to disable schema validation for a given endpoint.
In order to deal with non-conforming schemas, add
:ref:`custom_validation_rules` for non-conforming keys used in the schema.
.. _Cerberus: http://python-cerberus.org
.. _`source code`: https://github.com/pyeve/eve/blob/master/eve/io/mongo/validation.py
Expand Down
3 changes: 0 additions & 3 deletions eve/default_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,9 +238,6 @@
# http://geojson.org/geojson-spec.html#geojson-objects
ALLOW_CUSTOM_FIELDS_IN_GEOJSON = False

# don't ignore unknown schema rules (raise SchemaError)
TRANSPARENT_SCHEMA_RULES = False

# Rate limits are disabled by default. Needs a running redis-server.
RATE_LIMIT_GET = None
RATE_LIMIT_POST = None
Expand Down
119 changes: 0 additions & 119 deletions eve/defaults.py

This file was deleted.

15 changes: 0 additions & 15 deletions eve/flaskapp.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
from werkzeug.serving import WSGIRequestHandler

import eve
from eve.defaults import build_defaults
from eve.endpoints import collections_endpoint, item_endpoint, home_endpoint, \
error_endpoint, media_endpoint, schema_collection_endpoint, \
schema_item_endpoint
Expand Down Expand Up @@ -605,8 +604,6 @@ def _set_resource_defaults(self, resource, settings):
settings.setdefault('auth_field',
self.config['AUTH_FIELD'])
settings.setdefault('allow_unknown', self.config['ALLOW_UNKNOWN'])
settings.setdefault('transparent_schema_rules',
self.config['TRANSPARENT_SCHEMA_RULES'])
settings.setdefault('extra_response_fields',
self.config['EXTRA_RESPONSE_FIELDS'])
settings.setdefault('mongo_write_concern',
Expand All @@ -619,12 +616,6 @@ def _set_resource_defaults(self, resource, settings):
schema = settings.setdefault('schema', {})
self.set_schema_defaults(schema, settings['id_field'])

# 'defaults' helper set contains the names of fields with default
# values in their schema definition.

# TODO support default values for embedded documents.
settings['defaults'] = build_defaults(schema)

# list of all media fields for the resource
settings['_media'] = [field for field, definition in schema.items() if
definition.get('type') == 'media']
Expand Down Expand Up @@ -705,12 +696,6 @@ def _set_resource_projection(self, ds, schema, settings):
ds['projection'] is not None:
ds['projection'][self.config['DELETED']] = 1

# 'defaults' helper set contains the names of fields with default
# values in their schema definition.

# TODO support default values for embedded documents.
settings['defaults'] = build_defaults(schema)

# list of all media fields for the resource
settings['_media'] = [field for field, definition in schema.items() if
definition.get('type') == 'media' or
Expand Down
Loading

0 comments on commit 1110f80

Please sign in to comment.