Source code for sevenbridges.meta.fields

from uuid import UUID
from datetime import datetime

from sevenbridges.errors import ReadOnlyPropertyError, ValidationError


# noinspection PyProtectedMember
[docs]class Field: EMPTY = object() def __init__(self, name=None, read_only=True, validator=None): self.name = name self.read_only = read_only self.validator = validator def __set__(self, instance, value): # using empty as sentinel, value can be only set once - first time if self.read_only and instance._data[self.name] is not Field.EMPTY: raise ReadOnlyPropertyError( f'Property {self.name} is marked as read only!' ) # handle metadata. If metadata is set use _overwrite_metadata to signal # that the resource should be overwritten. if self.name == 'metadata': instance._overwrite_metadata = True if value is None: raise ValidationError('Not a valid dictionary!') value = self.validate(value) try: current_value = instance._data[self.name] if current_value == value: return except KeyError: pass instance._dirty[self.name] = value instance._data[self.name] = value def __get__(self, instance, cls): try: data = instance._data[self.name] return data except (KeyError, AttributeError): return None
[docs] def validate(self, value): if self.validator is not None: return self.validator(value) return value
# noinspection PyProtectedMember
[docs]class CompoundField(Field): def __init__(self, cls, read_only, name=None, validator=None): super().__init__( name=name, read_only=read_only, validator=validator ) self.cls = cls def __get__(self, instance, owner): data = instance._data[self.name] # empty is used for read only fields, None all for others if data is not Field.EMPTY and data is not None: return self.cls(api=instance._api, _parent=instance, **data) else: return None
# noinspection PyProtectedMember
[docs]class CompoundListField(Field): def __init__(self, cls, read_only, name=None): super().__init__(name=name, read_only=read_only) self.cls = cls def __get__(self, instance, owner): data = instance._data[self.name] # empty is used for read only fields, None for all others if data is not Field.EMPTY and data is not None: return [self.cls(api=instance._api, **item) for item in data] else: return []
[docs]class DictField(Field, dict): def __init__(self, read_only, name=None): super().__init__(name=name, read_only=read_only)
[docs]class HrefField(Field): def __init__(self, read_only, name=None): super().__init__(name=name, read_only=read_only)
[docs]class ObjectIdField(Field): def __init__(self, read_only, name=None): super().__init__(name=name, read_only=read_only)
[docs]class IntegerField(Field): def __init__(self, read_only, name=None): super().__init__(name=name, read_only=read_only)
[docs] def validate(self, value): if value and not isinstance(value, int): raise ValidationError( f'{value} is not a valid value for {type(self).__name__}' ) return value
[docs]class FloatField(Field): def __init__(self, read_only, name=None): super().__init__(name=name, read_only=read_only)
[docs] def validate(self, value): try: return float(value) except ValueError: raise ValidationError( f'{value} is not a valid value for {type(self).__name__}' )
[docs]class StringField(Field): def __init__(self, read_only, name=None, max_length=None): super().__init__(name=name, read_only=read_only) self.max_length = max_length
[docs] def validate(self, value): value = super().validate(value) if value and not isinstance(value, str): raise ValidationError( f'{value} is not a valid value for {type(self).__name__}' ) if self.max_length is not None and len(value) > self.max_length: raise ValidationError(f'{self.name}: max length exceeded.') return value
[docs]class DateTimeField(Field): def __init__(self, read_only, name=None): super().__init__(name=name, read_only=read_only) def __get__(self, instance, cls): data = super().__get__(instance, cls) if data: datetime_format = "%Y-%m-%dT%H:%M:%S" if '.' in data: datetime_format += ".%f" if 'Z' in data: datetime_format += "Z" return datetime.strptime(data, datetime_format)
[docs]class BooleanField(Field): def __init__(self, read_only, name=None): super().__init__(name=name, read_only=read_only)
[docs] def validate(self, value): if value and not isinstance(value, bool): raise ValidationError( '{value} is not a valid value for {type(self).__name__}' ) return value
[docs]class UuidField(Field): def __init__(self, read_only, name=None): super().__init__(name=name, read_only=read_only)
[docs] def validate(self, value): value = super().validate(value) try: UUID(value, version=4) return value except ValueError: raise ValidationError( f'{value} is not a valid value for {type(self).__name__}' )
[docs]class BasicListField(Field): def __init__(self, read_only, name=None, max_length=None): super().__init__(name=name, read_only=read_only) self.max_length = max_length
[docs] def validate(self, value): value = super().validate(value) if value and not isinstance(value, list): raise ValidationError('Validation failed, not a list.') if self.max_length is not None and len(value) > self.max_length: raise ValidationError( f'Exceeded {self.max_length} allowed elements.' ) return value