Beispiel #1
0
    def __init__(self, fields, **kwargs):
        # Some helpful functions
        is_basetype = lambda tipe: isinstance(tipe, BaseType)
        is_model = lambda tipe: isinstance(tipe, ModelType)
        is_dicttype = lambda tipe: isinstance(tipe, DictType)

        # field instance
        if is_basetype(fields):
            if is_model(fields):
                kwargs.setdefault('primary_embedded', fields)
            fields = [fields]
        # something other than a list
        elif not isinstance(fields, list):
            raise TypeException('Argument to ListType constructor must be '
                                'a valid field or list of fields',
                                self.field_name, list)
        # some bad stuff in the list
        elif list(ifilterfalse(is_basetype, fields)):
            raise TypeException('Argument to ListType constructor must be '
                                'a valid field or list of valid fields',
                                self.field_name, list)
        else:
            models = filter(is_model, fields)
            dicts = filter(is_dicttype, fields)
            if dicts:
                kwargs.setdefault('primary_embedded', None)
            if models:
                kwargs.setdefault('primary_embedded', models[0])
        self.fields = fields
        kwargs.setdefault('default', list)

        self.primary_embedded = kwargs.pop('primary_embedded', None)
        super(ListType, self).__init__(**kwargs)
Beispiel #2
0
 def validate(self, value):
     if len(value) != MD5Type.hash_length:
         raise TypeException('MD5 value is wrong length', self.field_name,
                             value)
     try:
         int(value, 16)
     except:
         raise TypeException('MD5 value is not hex', self.field_name, value)
     return value
Beispiel #3
0
    def validate(self, value):
        """Make sure that a list of valid fields is being used.
        """
        if not isinstance(value, dict):
            raise TypeException('Only dictionaries may be used in a '
                                  'DictType', self.field_name, value)

        if any(('.' in k or '$' in k) for k in value):
            raise TypeException('Invalid dictionary key name - keys may not '
                                  'contain "." or "$" characters',
                                  self.field_name, value)
        return value
Beispiel #4
0
    def validate(self, value):
        if not URLType.URL_REGEX.match(value):
            raise TypeException('Invalid URL', self.field_name, value)

        if self.verify_exists:
            import urllib2
            try:
                request = urllib2.Request(value)
                urllib2.urlopen(request)
            except Exception:
                message = 'URL does not exist'
                raise TypeException(message, self.field_name, value)

        return value
Beispiel #5
0
    def validate(self, value):
        assert isinstance(value, (str, unicode))

        if self.max_length is not None and len(value) > self.max_length:
            raise TypeException('String value is too long',
                                  self.field_name, value)

        if self.min_length is not None and len(value) < self.min_length:
            raise TypeException('String value is too short',
                                  self.field_name, value)

        if self.regex is not None and self.regex.match(value) is None:
            message = 'String value did not match validation regex',
            raise TypeException(message, self.field_name, value)

        return value
Beispiel #6
0
    def _validate_helper(cls,
                         field_inspector,
                         values,
                         validate_all=False,
                         delete_rogues=True):
        """This is a convenience function that loops over the given values
        and attempts to validate them against the class definition. It only
        validates the data in values and does not guarantee a complete model
        is present.

        'not present' is defined as not having a value OR having '' (or u'')
        as a value.
        """
        if not hasattr(cls, '_fields'):
            raise ValueError('cls is not a Model instance')

        internal_fields = cls._get_internal_fields()

        # Create function for handling exceptions
        exceptions = list()
        handle_exception = cls._gen_handle_exception(validate_all, exceptions)

        # Create function for handling a flock of frakkin palins (rogue fields)
        data_fields = set(values.keys())
        class_fields = list()
        handle_class_field = cls._gen_handle_class_field(
            delete_rogues, class_fields)

        # Loop across fields present in model
        for k, v in cls._fields.items():

            # handle common id name
            if k is 'id':
                k = '_id'

            handle_class_field(k)

            # we don't accept internal fields from users
            if k in internal_fields and k in values:
                value_is_default = (values[k] is v.default)
                if not value_is_default:
                    error_msg = 'Overwrite of internal fields attempted'
                    e = TypeException(error_msg, k, v)
                    handle_exception(e)
                    continue

            if field_inspector(k, v):
                datum = values[k]
                # if datum is None, skip
                if datum is None:
                    continue
                # treat empty strings as empty values and skip
                if isinstance(datum, (str, unicode)) and \
                       len(datum.strip()) == 0:
                    continue
                try:
                    v.validate(datum)
                except TypeException, e:
                    handle_exception(e)
Beispiel #7
0
    def validate(self, value):
        """Make sure that a list of valid fields is being used.
        """
        if not isinstance(value, (list, tuple)):
            error_msg = 'Only lists and tuples may be used in a list field'
            raise TypeException(error_msg, self.field_name, value)

        if not self.fields:  # if we want everything to validate
            return

        for item in value:
            try:
                for field in self.fields:
                    field.validate(item)
            except Exception, e:
                raise TypeException('Invalid ListType item',
                                      self.field_name, str(item))
Beispiel #8
0
 def __init__(self, model_type, **kwargs):
     is_embeddable = lambda dt: issubclass(dt, Model)
     if not isinstance(model_type, basestring):
         if not model_type or not is_embeddable(model_type):
             raise TypeException('Invalid model class provided to an '
                                 'ModelType',
                                 self.field_name, model_type)
     self.model_type_obj = model_type
     super(ModelType, self).__init__(**kwargs)
Beispiel #9
0
    def validate(self, value):
        try:
            value = self.number_class(value)
        except:
            raise TypeException('Not %s' % self.number_type, self.field_name,
                                  value)

        if self.min_value is not None and value < self.min_value:
            raise TypeException('%s value below min_value: %s'
                                  % (self.number_type, self.min_value),
                                  self.field_name, value)

        if self.max_value is not None and value > self.max_value:
            raise TypeException('%s value above max_value: %s'
                                  % (self.number_type, self.max_value),
                                  self.field_name, value)

        return value
Beispiel #10
0
    def _validate(self, value):
        # check choices
        if self.choices is not None:
            if value not in self.choices:
                raise TypeException(
                    "Value must be one of %s." % unicode(self.choices),
                    self.field_name, value)

        # check validation argument
        if self.validation is not None:
            if callable(self.validation):
                if not self.validation(value):
                    raise TypeException(
                        'Value does not match custom'
                        'validation method.', self.field_name, value)
            else:
                raise ValueError('validation argument must be a callable.')

        return self.validate(value)
Beispiel #11
0
    def validate(self, value):
        if not isinstance(value, decimal.Decimal):
            if not isinstance(value, basestring):
                value = str(value)
            try:
                value = decimal.Decimal(value)
            except Exception:
                raise TypeException('Could not convert to decimal',
                                      self.field_name, value)

        if self.min_value is not None and value < self.min_value:
            raise TypeException('Decimal value below min_value: %s'
                                  % self.min_value, self.field_name, value)

        if self.max_value is not None and value > self.max_value:
            raise TypeException('Decimal value above max_value: %s'
                                  % self.max_value, self.field_name, value)

        return value
Beispiel #12
0
 def validate(self, value):
     """Make sure that the model instance is an instance of the
     Model subclass provided when the model was defined.
     """
     # Using isinstance also works for subclasses of self.model
     if not isinstance(value, self.model_type):
         raise TypeException('Invalid modeltype instance '
                               'provided to an ModelType',
                               self.field_name, value)
     self.model_type.validate(value)
     return value
Beispiel #13
0
 def validate(self, value):
     """Make sure the value is a valid uuid representation.  See
     http://docs.python.org/library/uuid.html for accepted formats.
     """
     if not isinstance(value, (uuid.UUID,)):
         try:
             value = uuid.UUID(value)
         except ValueError:
             raise TypeException('Not a valid UUID value',
                 self.field_name, value)
     return value
Beispiel #14
0
    def _validate(self, value):
        """This function runs before `validate()` and handles applying the
        global environment parameters.
        """
        # `choices`
        if self.choices is not None:
            if value not in self.choices:
                raise TypeException("Value must be one of %s."
                    % unicode(self.choices), self.field_name, value)

        # `validation` function
        if self.validation is not None:
            if callable(self.validation):
                if not self.validation(value):
                    raise TypeException('Value does not match custom'
                                          'validation method.',
                                           self.field_name, value)
            else:
                raise ValueError('validation argument must be a callable.')

        return self.validate(value)
Beispiel #15
0
class BaseModel(object):
    def __init__(self, **values):
        self._data = {}
        minimized_field_map = {}

        # Assign default values to instance
        for attr_name, attr_value in self._fields.items():
            # Use default value if present
            value = getattr(self, attr_name, None)
            setattr(self, attr_name, value)
            if attr_value.minimized_field_name:
                field_name = attr_value.minimized_field_name
                minimized_field_map[field_name] = attr_value.uniq_field

        # Assign initial values to instance
        for attr_name, attr_value in values.items():
            try:
                if attr_name == '_id':
                    attr_name = 'id'
                setattr(self, attr_name, attr_value)
                if attr_name in minimized_field_map:
                    setattr(self, minimized_field_map[attr_name], attr_value)
            # Put a diaper on the keys that don't belong and send 'em home
            except AttributeError:
                pass

    def validate(self, validate_all=False):
        """Ensure that all fields' values are valid and that required fields
        are present.

        Throws a ModelException if Model is invalid
        """
        # Get a list of tuples of field names and their current values
        fields = [(field, getattr(self, name))
                  for name, field in self._fields.items()]

        # Ensure that each field is matched to a valid value
        errs = []
        for field, value in fields:
            err = None
            # treat empty strings as nonexistent
            if value is not None and value != '':
                try:
                    field._validate(value)
                except TypeException, e:
                    err = e
                except (ValueError, AttributeError, AssertionError):
                    err = TypeException('Invalid value', field.field_name,
                                        value)
            elif field.required:
                err = TypeException('Required field missing', field.field_name,
                                    value)
Beispiel #16
0
 def validate(self, value):
     """Make sure that a geo-value is of type (x, y)
     """
     if not len(value) == 2:
         raise TypeException('Value must be a two-dimensional point',
                               self.field_name, value)
     if isinstance(value, dict):
         for v in value.values():
             if not isinstance(v, (float, int)):
                 error_msg = 'Both values in point must be float or int'
                 raise TypeException(error_msg, self.field_name, value)
     elif isinstance(value, (list, tuple)):
         if (not isinstance(value[0], (float, int)) and
             not isinstance(value[1], (float, int))):
             error_msg = 'Both values in point must be float or int'
             raise TypeException(error_msg, self.field_name, value)
     else:
         raise TypeException('GeoPointType can only accept tuples, '
                               'lists of (x, y), or dicts of {k1: v1, '
                               'k2: v2}',
                               self.field_name, value)
     return value
Beispiel #17
0
 def date_to_iso8601(cls, dt, format):
     """Classmethod that goes the opposite direction of iso8601_to_date.
        Defaults to using isoformat(), but can use the optional format
        argument either as a strftime format string or as a custom
        date formatting function or lambda.
     """
     if isinstance(format, str):
         iso_dt = dt.strftime(format)
     elif hasattr(format, '__call__'):
         iso_dt = format(dt)
     else:
         raise TypeException('DateTimeType format must be a string or callable')
     return iso_dt
Beispiel #18
0
def validate_instance(model, validate_all=False):
    """Ensure that all fields' values are valid and that required fields
    are present.

    Throws a ModelException if Model is invalid
    """
    # Get a list of tuples of field names and their current values
    fields = [(field, getattr(model, name))
              for name, field in model._fields.items()]

    # Ensure that each field is matched to a valid value
    errs = []
    for field, value in fields:
        err = None
        # treat empty strings as nonexistent
        if value is not None and value != '':
            try:
                field._validate(value)
            except TypeException, e:
                err = e
            except (ValueError, AttributeError, AssertionError):
                err = TypeException('Invalid value', field.field_name,
                                    value)
Beispiel #19
0
 def for_python(self, value):
     try:
         return bson.objectid.ObjectId(unicode(value))
     except Exception, e:
         raise TypeException('Invalid ObjectId', self.field_name, value)
Beispiel #20
0
    # Ensure that each field is matched to a valid value
    errs = []
    for field, value in fields:
        err = None
        # treat empty strings as nonexistent
        if value is not None and value != '':
            try:
                field._validate(value)
            except TypeException, e:
                err = e
            except (ValueError, AttributeError, AssertionError):
                err = TypeException('Invalid value', field.field_name,
                                    value)
        elif field.required:
            err = TypeException('Required field missing',
                                field.field_name,
                                value)
        # If validate_all, save errors to a list
        # Otherwise, throw the first error
        if err:
            errs.append(err)
        if err and not validate_all:
            # NB: raising a ModelException in this case would be more
            # consistent, but existing code might expect TypeException
            raise err

    if errs:
        raise ModelException(model._model_name, errs)
    return True

Beispiel #21
0
 def validate(self, value):
     if not EmailType.EMAIL_REGEX.match(value):
         raise TypeException('Invalid email address', self.field_name,
                               value)
     return value
Beispiel #22
0
 def validate(self, value):
     if not isinstance(value, bson.objectid.ObjectId):
         try:
             value = bson.objectid.ObjectId(unicode(value))
         except Exception, e:
             raise TypeException('Invalid ObjectId', self.field_name, value)
Beispiel #23
0
 def validate(self, value):
     if not isinstance(value, bool):
         raise TypeException('Not a boolean', self.field_name, value)
     return value
Beispiel #24
0
 def validate(self, value):
     if not isinstance(value, datetime.datetime):
         raise TypeException('Not a datetime', self.field_name, value)
     return value