class FileSchema(Schema): """Schema for records v1 in JSON.""" class Meta: """Meta class to reject unknown fields.""" unknown = EXCLUDE key = SanitizedUnicode(dump_only=True) created = Str(dump_only=True) updated = Str(dump_only=True) status = GenMethod('dump_status') metadata = Dict(dump_only=True) checksum = Str(dump_only=True, attribute='file.checksum') storage_class = Str(dump_only=True, attribute='file.storage_class') mimetype = Str(dump_only=True, attribute='file.mimetype') size = Number(attribute='file.size') version_id = UUID(attribute='file.version_id') file_id = UUID(attribute='file.file_id') bucket_id = UUID(attribute='file.bucket_id') links = Links() def dump_status(self, obj): """Dump file status.""" return 'completed' if obj.file else 'pending'
class Cart(Schema): class Meta: ordered = True _id = UUID(required=False, allow_none=False, missing=uuid.uuid4) products = List(Nested(Product()), required=False, missing=[]) customer_id = UUID(required=True) created_at = DateTime(required=False, allow_none=True, description='Criado em.', missing=datetime.now, format=DATETIME_FORMAT) updated_at = DateTime(required=False, allow_none=True, description='Atualizado em.', format=DATETIME_FORMAT)
class Product(Schema): class Meta: ordered = True _id = UUID(required=False, allow_none=False, missing=uuid.uuid4) name = String(required=True, description='Nome do produto.', validate=Length(min=1, max=1000)) description = String(required=True, description='Descrição do produto.', validate=Length(min=1, max=1000)) price = Float(required=True, description='Valor do produto.') enabled = Bool(required=False, description='Se o produto está ativado ou desativado.', missing=True) created_at = DateTime(required=False, allow_none=True, description='Criado em.', missing=datetime.now, format=DATETIME_FORMAT) updated_at = DateTime(required=False, allow_none=True, description='Atualizado em.', format=DATETIME_FORMAT) deleted_at = DateTime(required=False, allow_none=True, description='Deletado em.', format=DATETIME_FORMAT)
class BillSchema(ModelSchema): place = String(required=True, validate=not_blank) billed_at = Date(required=True) wallet_uid = UUID(required=True, allow_none=False) items = Nested( BillItemSchema, many=True, only=("uid", "name", "quantity", "value", "group_uid"), ) @pre_dump def make_dict(self, obj): return dict( uid=obj.uid, place=obj.place, billed_at=_to_date(obj.billed_at), wallet_uid=obj.wallet_uid, items=[item for item in obj.items], ) @post_load def make_model(self, data): return Bill( uid=data.get("uid"), place=data.get("place"), billed_at=data.get("billed_at"), wallet_uid=data.get("wallet_uid"), items=[item for item in data.get("items", [])], total=data.get("total"), )
class ResourceSchema(ResourceMixin, Schema): mimetype = Str(allow_none=True) cache_last_updated = Str(allow_none=True) cache_url = Str(allow_none=True) created = DateTime() description = Str() hash = Str() ext_ident = Str(data_key='id', validate=validate.Length(max=36)) modified = DateTime(data_key='last_modified', allow_none=True) mimetype_inner = Str(allow_none=True) title = Str(data_key='name') format = Str() link = URL(data_key='url') datastore_active = Bool() package_id = UUID() position = Int() resource_type = Str(allow_none=True) revision_id = UUID() size = Str(allow_none=True) state = Str() url_type = Str(allow_none=True) class Meta: fields = ('created', 'modified', 'ext_ident', 'title', 'description', 'link', 'format') unknown = EXCLUDE def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # TODO: Does it makes sense to validate format here? Disabled for now. self.format_validation = False @validates_schema def validate_format(self, data, **kwargs): value = data.get('format') if self.format_validation and value and value not in SUPPORTED_RESOURCE_FORMATS: error = _('Unsupported format: %(format)s.') % {'format': value} raise ValidationError(error, field_name='format') @pre_load def prepare_data(self, data, **kwargs): if 'format' in data: value = data['format'].lower() if value not in SUPPORTED_RESOURCE_FORMATS: value = '' data['format'] = value return data
class BillItemSchema(ModelSchema): _decimal_error_messages = {"invalid": "Wymagana jest liczba"} uid = UUID(required=False, allow_none=True) name = String(required=True, validate=not_blank) quantity = Decimal( as_string=True, required=True, places=2, allow_none=False, error_messages=_decimal_error_messages, ) value = Decimal( as_string=True, required=True, places=2, allow_none=False, error_messages=_decimal_error_messages, ) bill_uid = UUID(required=True, allow_none=False) group_uid = UUID( required=True, allow_none=False, error_messages={"invalid_uuid": "Wybierz grupę"}, ) @pre_dump def make_dict(self, obj): return dict( uid=obj.uid, name=obj.name, quantity=obj.quantity, value=obj.value, bill_uid=obj.bill_uid, group_uid=obj.group_uid, ) @post_load def make_model(self, data): return BillItem( uid=data.get("uid"), name=data.get("name"), quantity=data.get("quantity"), value=data.get("value"), bill_uid=data.get("bill_uid"), group_uid=data.get("group_uid"), )
class TagSchema(Schema): uuid = UUID(data_key='id') name = Str() status = Str(data_key='state', validate=validate.OneOf(choices=['active'])) class Meta: fields = ('name', 'uuid') unknown = EXCLUDE
class ProductSchema(ma.SQLAlchemyAutoSchema): name = String(required=True) count = String(required=True) category_id = UUID(required=True) class Meta: model = Product load_instance=True
class DatasetSchema(Schema): author = Str() author_email = Str() creator_user_id = UUID() extras = Nested(ExtraSchema, many=True) groups = Nested(CategorySchema, many=True) license_id = Str() license_title = Str() license_url = URL() maintainer = Str() maintainer_email = Str() created = DateTime(data_key='metadata_created') modified = DateTime(data_key='metadata_modified', allow_none=True) slug = Str(data_key='name') notes = Str() num_resources = Int() num_tags = Int() ext_ident = Str(data_key='id', validate=validate.Length(max=36)) isopen = Bool() organization = Nested(OrganizationSchema, many=False) owner_org = UUID() private = Bool() relationships_as_object = Nested(RelationshipObjectSchema, many=True) relationships_as_subject = Nested(RelationshipSubjectSchema, many=True) resources = Nested(ResourceSchema, many=True) revision_id = UUID() status = Str(data_key='state') tags = Nested(TagSchema, many=True) title = Str() type = Str() url = Str() version = Str() class Meta: exclude = [ 'author', 'author_email', 'creator_user_id', 'extras', 'groups', 'license_title', 'license_url', 'maintainer', 'maintainer_email', 'num_resources', 'num_tags', 'isopen', 'owner_org', 'private', 'relationships_as_object', 'relationships_as_subject', 'revision_id', 'type', 'status', 'url', 'version' ] ordered = True unknown = EXCLUDE
class CategorySchema(Schema): description = Str() display_name = Str() uuid = UUID() image_url = URL(data_key='image_display_url') name = Str() title = Str() class Meta: fields = ('title', 'description', 'uuid', 'image_url') unknown = EXCLUDE
class Customer(Schema): class Meta: ordered = True _id = UUID(required=False, allow_none=False, missing=uuid.uuid4) name = String(required=True, description='Nome do cliente.', validate=Length(min=1, max=100)) email = Email(required=True, description='Email do client') password = String(required=True, description='Senha do cliente.', validate=Length(min=1, max=100)) document = String(required=True, description='Documento do cliente.', validate=Length(min=1, max=100)) created_at = DateTime(required=False, allow_none=True, description='Criado em.', missing=datetime.now, format=DATETIME_FORMAT) updated_at = DateTime(required=False, allow_none=True, description='Atualizado em.', format=DATETIME_FORMAT)
class Computer(Device): __doc__ = m.Computer.__doc__ # TODO TimeOut 1. Comment components if there are time out. components = NestedOn( 'Component', many=True, dump_only=True, collection_class=OrderedSet, description='The components that are inside this computer.') chassis = EnumField(enums.ComputerChassis, description=m.Computer.chassis.comment) ram_size = Integer(dump_only=True, data_key='ramSize', description=m.Computer.ram_size.__doc__) data_storage_size = Integer( dump_only=True, data_key='dataStorageSize', description=m.Computer.data_storage_size.__doc__) processor_model = Str(dump_only=True, data_key='processorModel', description=m.Computer.processor_model.__doc__) graphic_card_model = Str(dump_only=True, data_key='graphicCardModel', description=m.Computer.graphic_card_model.__doc__) network_speeds = List(Integer(dump_only=True), dump_only=True, data_key='networkSpeeds', description=m.Computer.network_speeds.__doc__) privacy = NestedOn('Action', many=True, dump_only=True, collection_class=set, description=m.Computer.privacy.__doc__) amount = Integer(validate=f.validate.Range(min=0, max=100), description=m.Computer.amount.__doc__) # author_id = NestedOn(s_user.User, only_query='author_id') owner_id = UUID(data_key='ownerID') transfer_state = EnumField(enums.TransferState, description=m.Computer.transfer_state.comment) receiver_id = UUID(data_key='receiverID')
class Event(Thing): id = UUID(dump_only=True) name = String(default='', validate=Length(STR_BIG_SIZE), description=m.Event.name.comment) date = DateTime('iso', description=m.Event.date.comment) error = Boolean(default=False, description=m.Event.error.comment) incidence = Boolean(default=False, description=m.Event.incidence.comment) snapshot = NestedOn('Snapshot', dump_only=True) components = NestedOn(Component, dump_only=True, many=True) description = String(default='', description=m.Event.description.comment) author = NestedOn(User, dump_only=True, exclude=('token', )) closed = Boolean(missing=True, description=m.Event.closed.comment)
class JobsSerializer(Schema): company = Str(required=True) company_logo = Str(required=True) company_url = Str(required=True) created_at = Str(required=True) description = Str(required=True) fulltime = Bool(required=True) how_to_apply = Str(required=True) id = UUID(required=True) location = Str(required=True) title = Str(required=True) fulltime = Function(lambda obj: obj["type"] == "Full Time", data_key="fulltime")
class GroupSchema(ModelSchema): name = String(required=True, validate=not_blank) wallet_uid = UUID(required=True, allow_none=False) @pre_dump def make_dict(self, obj): return dict(uid=obj.uid, name=obj.name, wallet_uid=obj.wallet_uid) @post_load def make_model(self, data): return Group( uid=data.get("uid"), name=data.get("name"), wallet_uid=data.get("wallet_uid"), )
class FileSchema(Schema): """Service schema for files.""" key = SanitizedUnicode(dump_only=True) created = TZDateTime(timezone=timezone.utc, format='iso', dump_only=True) updated = TZDateTime(timezone=timezone.utc, format='iso', dump_only=True) status = GenMethod('dump_status') metadata = Dict(dump_only=True) checksum = Str(dump_only=True, attribute='file.checksum') storage_class = Str(dump_only=True, attribute='file.storage_class') mimetype = Str(dump_only=True, attribute='file.mimetype') size = Number(attribute='file.size') version_id = UUID(attribute='file.version_id') file_id = UUID(attribute='file.file_id') bucket_id = UUID(attribute='file.bucket_id') links = Links() def dump_status(self, obj): """Dump file status.""" return 'completed' if obj.file else 'pending'
class Snapshot(EventWithOneDevice): """ The Snapshot updates the state of the device with information about its components and events performed at them. See docs for more info. """ uuid = UUID(required=True) software = EnumField( SnapshotSoftware, required=True, description='The software that generated this Snapshot.') version = Version(required=True, description='The version of the software.') events = NestedOn(Event, many=True, dump_only=True) expected_events = List( EnumField(SnapshotExpectedEvents), data_key='expectedEvents', description='Keep open this Snapshot until the following events' 'are performed. Setting this value will activate' 'the async Snapshot.') device = NestedOn(Device) elapsed = TimeDelta(precision=TimeDelta.SECONDS, required=True) components = NestedOn( Component, many=True, description='A list of components that are inside of the device' 'at the moment of this Snapshot.' 'Order is preserved, so the component num 0 when' 'submitting is the component num 0 when returning it back.') @validates_schema def validate_workbench_version(self, data: dict): if data['software'] == SnapshotSoftware.Workbench: if data['version'] < app.config['MIN_WORKBENCH']: raise ValidationError( 'Min. supported Workbench algorithm_version is ' '{}'.format(app.config['MIN_WORKBENCH']), field_names=['version']) @validates_schema def validate_components_only_workbench(self, data: dict): if data['software'] != SnapshotSoftware.Workbench: if data['components'] is not None: raise ValidationError('Only Workbench can add component info', field_names=['components'])
class BillSummarySchema(ModelSchema): place = String(required=True, validate=not_blank) billed_at = Date(required=True) wallet_uid = UUID(required=True, allow_none=False) items = Nested( BillItemSchema, many=True, only=("uid", "name", "quantity", "value", "group_uid"), ) total = Decimal(as_string=True, required=False, places=2, allow_none=True) @pre_dump def make_dict(self, obj): return dict( uid=obj.uid, place=obj.place, billed_at=_to_date(obj.billed_at), wallet_uid=obj.wallet_uid, total=obj.total, )
class WalletSchema(ModelSchema): name = String(required=True, validate=not_blank) type = String(required=True, validate=not_blank) owner_uid = UUID(required=True, allow_none=False) @pre_dump def make_dict(self, obj): return dict(uid=obj.uid, name=obj.name, type=obj.type, owner_uid=obj.owner_uid) @post_load def make_model(self, data): return Wallet( uid=data.get("uid"), name=data.get("name"), type=data.get("type"), owner_uid=data.get("owner_uid"), )
class Event(Thing): __doc__ = m.Event.__doc__ id = UUID(dump_only=True) name = SanitizedStr(default='', validate=Length(max=STR_BIG_SIZE), description=m.Event.name.comment) closed = Boolean(missing=True, description=m.Event.closed.comment) severity = EnumField(Severity, description=m.Event.severity.comment) description = SanitizedStr(default='', description=m.Event.description.comment) start_time = DateTime(data_key='startTime', description=m.Event.start_time.comment) end_time = DateTime(data_key='endTime', description=m.Event.end_time.comment) snapshot = NestedOn('Snapshot', dump_only=True) agent = NestedOn(s_agent.Agent, description=m.Event.agent_id.comment) author = NestedOn(s_user.User, dump_only=True, exclude=('token', )) components = NestedOn(s_device.Component, dump_only=True, many=True) parent = NestedOn(s_device.Computer, dump_only=True, description=m.Event.parent_id.comment) url = URL(dump_only=True, description=m.Event.url.__doc__)
class User(Thing): id = UUID(dump_only=True) email = Email(required=True) password = SanitizedStr(load_only=True, required=True) individuals = NestedOn(Individual, many=True, dump_only=True) name = SanitizedStr() token = String( dump_only=True, description= 'Use this token in an Authorization header to access the app.' 'The token can change overtime.') inventories = NestedOn(Inventory, many=True, dump_only=True) code = String(dump_only=True, description='Code of inactive accounts') def __init__(self, only=None, exclude=('token', ), prefix='', many=False, context=None, load_only=(), dump_only=(), partial=False): """Instantiates the User. By default we exclude token from both load/dump so they are not taken / set in normal usage by mistake. """ super().__init__(only, exclude, prefix, many, context, load_only, dump_only, partial) @post_dump def base64encode_token(self, data: dict): """Encodes the token to base64 so clients don't have to.""" if 'token' in data: # In many cases we don't dump the token (ex. relationships) # Framework needs ':' at the end data['token'] = auth.Auth.encode(data['token']) return data
class SiaNode(Schema): id = UUID(title="id", description="Sia unique identifier.", required=True, dump_only=True) accepting_contracts = Boolean( title="accepting_contracts", description="True if the host is accepting new contracts.") max_download_batch_size = Integer( title="max_download_batch_size", description= "Maximum number of bytes that the host will allow to be requested by a single download request", ) max_duration = Integer( title="max_duration", description= "Maximum duration in blocks that a host will allow for a file contract. The host commits to " "keeping files for the full duration under the threat of facing a large penalty for losing or " "dropping data before the duration is complete. The storage proof window of an incoming file " "contract must end before the current height + maxduration.", ) max_revise_batch_size = Integer( title="max_revise_batch_size", description= "Maximum size in bytes of a single batch of file contract revisions. Larger batch sizes allow for " "higher throughput as there is significant communication overhead associated with performing a " "batch upload.", ) net_address = String( title="net_address", description= "Remote address of the host. It can be an IPv4, IPv6, or hostname, along with the port. IPv6 " "addresses are enclosed in square brackets.", ) remaining_storage = Integer( title="remaining_storage", description="Unused storage capacity the host claims it has.") sector_size = Integer( title="sector_size", description= "Smallest amount of data in bytes that can be uploaded or downloaded to or from the host.", ) total_storage = Integer( title="total_storage", description="Total amount of storage capacity the host claims it has.") unlock_hash = String( title="unlock_hash", description= "Address at which the host can be paid when forming file contracts.") window_size = Integer( title="window_size", description= "A storage proof window is the number of blocks that the host has to get a storage proof onto the " "blockchain. The window size is the minimum size of window that the host will accept in a file " "contract.", ) collateral = String( title="collateral", description= "The maximum amount of money that the host will put up as collateral for storage that is contracted" " by the renter.", ) max_collateral = String( title="max_collateral", description= "The maximum amount of collateral that the host will put into a single file contract.", ) contract_price = String( title="contract_price", description= "The price that a renter has to pay to create a contract with the host. The payment is intended " "to cover transaction fees for the file contract revision and the storage proof that the host will " "be submitting to the blockchain.", ) download_bandwidth_price = String( title="download_bandwidth_price", description= "The price that a renter has to pay when downloading data from the host.", ) storage_price = String( title="storage_price", description= "The price that a renter has to pay to store files with the host.") upload_bandwidth_price = String( title="upload_bandwidth_price", description= "The price that a renter has to pay when uploading data to the host.", ) revision_number = Integer( title="revision_number", description= "The revision number indicates to the renter what iteration of settings the host is currently at. " "Settings are generally signed. If the renter has multiple conflicting copies of settings from " "the host, the renter can expect the one with the higher revision number to be more recent.", ) version = String(title="version", description="The version of the host.") first_seen = Integer( title="first_seen", description= "Firstseen is the last block height at which this host was announced.") historic_downtime = Integer( title="historic_downtime", description="Total amount of time the host has been offline.") historic_uptime = Integer( title="historic_uptime", description="Total amount of time the host has been online.") historic_failed_interactions = Integer( title="historic_failed_interactions", description="Number of historic failed interactions with the host.") historic_successful_interactions = Integer( title="historic_successful_interactions", description="Number of historic successful interactions with the host.", ) recent_failed_interactions = Integer( title="recent_failed_interactions", description="Number of recent failed interactions with the host.") recent_successful_interactions = Integer( title="recent_successful_interactions", description="Number of recent successful interactions with the host.") last_historic_update = Integer( title="last_historic_update", description= "The last time that the interactions within scanhistory have been compressed into the historic " "ones.", ) public_key_string = String( title="public_key_string", description= "The string representation of the full public key, used when calling /hostdb/hosts.", ) ipnets = List( String(), title="ipnets", description= "List of IP subnet masks used by the host. For IPv4 the /24 and for IPv6 the /54 subnet mask is " "used. A host can have either one IPv4 or one IPv6 subnet or one of each. E.g. these lists are " 'valid: [ "IPv4" ], [ "IPv6" ] or [ "IPv4", "IPv6" ]. The following lists are invalid: [ "IPv4", ' '"IPv4" ], [ "IPv4", "IPv6", "IPv6" ]. Hosts with an invalid list are ignored.', ) address = String(title="address", description="The full address of the node.") country = String(title="country", description="The country where the node can be found.") city = String(title="city", description="The city where the node can be found.") latitude = Float(title="latitude", description="Geolocation latitude coordinate") longitude = Float(title="longitude", description="Geolocation longitude coordinate")
else: id = queue_push(params) return _process(config=app_config['register'], params=params, id=id) else: # Without double opt-in return _process(config=app_config['register'], params=params, store=app_config.get('store')) # ============================================================================= # Confirmation endpoint # ============================================================================= confirm_parameters = {"id": UUID(required=True)} @use_kwargs(confirm_parameters, location="query") def confirm(id): params = queue_pop(id) app_config = _find_app_config(params['appid']) if "cd" in app_config: response = subscribe(app_config["cd"], params) # If the FSFE Community Database has yielded an error message, display # it unchanged. if response: return response
class Device(Thing): __doc__ = m.Device.__doc__ id = Integer(description=m.Device.id.comment, dump_only=True) hid = SanitizedStr(lower=True, description=m.Device.hid.comment) tags = NestedOn('Tag', many=True, collection_class=OrderedSet, description='A set of tags that identify the device.') model = SanitizedStr(lower=True, validate=Length(max=STR_BIG_SIZE), description=m.Device.model.comment) manufacturer = SanitizedStr(lower=True, validate=Length(max=STR_SIZE), description=m.Device.manufacturer.comment) serial_number = SanitizedStr(lower=True, validate=Length(max=STR_BIG_SIZE), data_key='serialNumber') brand = SanitizedStr(validate=Length(max=STR_BIG_SIZE), description=m.Device.brand.comment) generation = Integer(validate=Range(1, 100), description=m.Device.generation.comment) version = SanitizedStr(description=m.Device.version) weight = Float(validate=Range(0.1, 5), unit=UnitCodes.kgm, description=m.Device.weight.comment) width = Float(validate=Range(0.1, 5), unit=UnitCodes.m, description=m.Device.width.comment) height = Float(validate=Range(0.1, 5), unit=UnitCodes.m, description=m.Device.height.comment) depth = Float(validate=Range(0.1, 5), unit=UnitCodes.m, description=m.Device.depth.comment) # TODO TimeOut 2. Comment actions and lots if there are time out. actions = NestedOn('Action', many=True, dump_only=True, description=m.Device.actions.__doc__) # TODO TimeOut 2. Comment actions_one and lots if there are time out. actions_one = NestedOn('Action', many=True, load_only=True, collection_class=OrderedSet) problems = NestedOn('Action', many=True, dump_only=True, description=m.Device.problems.__doc__) url = URL(dump_only=True, description=m.Device.url.__doc__) # TODO TimeOut 2. Comment actions and lots if there are time out. lots = NestedOn( 'Lot', many=True, dump_only=True, description='The lots where this device is directly under.') rate = NestedOn('Rate', dump_only=True, description=m.Device.rate.__doc__) price = NestedOn('Price', dump_only=True, description=m.Device.price.__doc__) tradings = Dict(dump_only=True, description='') physical = EnumField(states.Physical, dump_only=True, description=m.Device.physical.__doc__) traking = EnumField(states.Traking, dump_only=True, description=m.Device.physical.__doc__) usage = EnumField(states.Usage, dump_only=True, description=m.Device.physical.__doc__) revoke = UUID(dump_only=True) physical_possessor = NestedOn('Agent', dump_only=True, data_key='physicalPossessor') production_date = DateTime('iso', description=m.Device.updated.comment, data_key='productionDate') working = NestedOn('Action', many=True, dump_only=True, description=m.Device.working.__doc__) variant = SanitizedStr(description=m.Device.variant.comment) sku = SanitizedStr(description=m.Device.sku.comment) image = URL(description=m.Device.image.comment) allocated = Boolean(description=m.Device.allocated.comment) devicehub_id = SanitizedStr(data_key='devicehubID', description=m.Device.devicehub_id.comment) @pre_load def from_actions_to_actions_one(self, data: dict): """ Not an elegant way of allowing submitting actions to a device (in the context of Snapshots) without creating an ``actions`` field at the model (which is not possible). :param data: :return: """ # Note that it is secure to allow uploading actions_one # as the only time an user can send a device object is # in snapshots. data['actions_one'] = data.pop('actions', []) return data @post_load def validate_snapshot_actions(self, data): """Validates that only snapshot-related actions can be uploaded.""" from ereuse_devicehub.resources.action.models import EraseBasic, Test, Rate, Install, \ Benchmark for action in data['actions_one']: if not isinstance(action, (Install, EraseBasic, Rate, Test, Benchmark)): raise ValidationError('You cannot upload {}'.format(action), field_names=['actions'])
def dog(id: UUID()) -> Dog.Schema(): """A fake dog resource that echos and randomly generates a dog.""" name = random.choice(list(DOG_TYPES_TO_ABBREVIATIONS)) abbrev = DOG_TYPES_TO_ABBREVIATIONS[name] return Dog(id=id, name=name, abbreviation=abbrev)
class Schema: uuid = UUID(required=True) foo = String()
class Snapshot(EventWithOneDevice): __doc__ = m.Snapshot.__doc__ """ The Snapshot updates the state of the device with information about its components and events performed at them. See docs for more info. """ uuid = UUID() software = EnumField( SnapshotSoftware, required=True, description='The software that generated this Snapshot.') version = Version(required=True, description='The version of the software.') events = NestedOn(Event, many=True, dump_only=True) expected_events = List( EnumField(SnapshotExpectedEvents), data_key='expectedEvents', description='Keep open this Snapshot until the following events' 'are performed. Setting this value will activate' 'the async Snapshot.') elapsed = TimeDelta(precision=TimeDelta.SECONDS) components = NestedOn( s_device.Component, many=True, description='A list of components that are inside of the device' 'at the moment of this Snapshot.' 'Order is preserved, so the component num 0 when' 'submitting is the component num 0 when returning it back.') @validates_schema def validate_workbench_version(self, data: dict): if data['software'] == SnapshotSoftware.Workbench: if data['version'] < app.config['MIN_WORKBENCH']: raise ValidationError('Min. supported Workbench version is ' '{} but yours is {}.'.format( app.config['MIN_WORKBENCH'], data['version']), field_names=['version']) @validates_schema def validate_components_only_workbench(self, data: dict): if data['software'] != SnapshotSoftware.Workbench: if data.get('components', None) is not None: raise ValidationError('Only Workbench can add component info', field_names=['components']) @validates_schema def validate_only_workbench_fields(self, data: dict): """Ensures workbench has ``elapsed`` and ``uuid`` and no others.""" # todo test if data['software'] == SnapshotSoftware.Workbench: if not data.get('uuid', None): raise ValidationError( 'Snapshots from Workbench must have uuid', field_names=['uuid']) if data.get('elapsed', None) is None: raise ValidationError( 'Snapshots from Workbench must have elapsed', field_names=['elapsed']) else: if data.get('uuid', None): raise ValidationError( 'Only Snapshots from Workbench can have uuid', field_names=['uuid']) if data.get('elapsed', None): raise ValidationError( 'Only Snapshots from Workbench can have elapsed', field_names=['elapsed'])
class Dog: """Dog type contract.""" id: str = field(metadata={'marshmallow_field': UUID()}) name: str abbreviation: Optional[str] Schema: ClassVar[Type[mm.Schema]]
def dog(id: UUID()) -> Dog.Schema(): name = random.choice(list(DOG_TYPES_TO_ABBREVIATIONS)) abbrev = DOG_TYPES_TO_ABBREVIATIONS[name] return Dog(id=id, name=name, abbreviation=abbrev)
class ModelSchema(BaseSchema): uid = UUID(required=True, allow_none=False)