from apollo_utils.service.schemas.fields.enum import EnumField from marshmallow import EXCLUDE, Schema, fields, post_load, validate from apollo_delphi_events.config import DSP, INPUT_DT_FORMAT, MAX_INPUT_TTL from apollo_delphi_events.constants import DELPHI_TO_APOLLO_DSP, DOMAIN, EventType class MetaExcludeUnknown(Schema): """Schema to exclude unknown fields to have a predicted structure of event/message""" class Meta: unknown = EXCLUDE class MetaItem(MetaExcludeUnknown): domain = fields.Str(required=True, validate=validate.OneOf([DOMAIN])) event_type = EnumField(EventType, required=True) dsp = fields.Str(required=True, validate=validate.OneOf(DSP)) country_code = fields.List(fields.Str(required=True), missing=[]) top_country_code = fields.List(fields.Str(required=True), missing=[]) @post_load def map_dsp(self, in_data, **kwargs): in_data["dsp"] = DELPHI_TO_APOLLO_DSP[in_data["dsp"]] return in_data class Playlist(MetaExcludeUnknown): id = fields.Str(required=True) name = fields.Str(required=True) last_updated_at = fields.DateTime(required=True, format=INPUT_DT_FORMAT) class Artist(MetaExcludeUnknown): id = fields.Str(required=True) name = fields.Str(required=True) order = fields.Int() class Track(MetaExcludeUnknown): id = fields.Str(required=True) isrc = fields.Str(required=True) name = fields.Str(required=True) image_url = fields.Str(required=True) artists = fields.List(fields.Nested(Artist, required=True), required=True, validate=validate.Length(min=1)) class PlaylistAdditionContent(MetaExcludeUnknown): track = fields.Nested(Track, required=True) playlist = fields.Nested(Playlist, required=True) current_position = fields.Int(required=True) class PlaylistUpdateContent(MetaExcludeUnknown): playlist = fields.Nested(Playlist, required=True) class InputEventBase(MetaExcludeUnknown): id = fields.Str(required=True) created_at = fields.DateTime(required=True, format=INPUT_DT_FORMAT) ttl = fields.Integer(missing=MAX_INPUT_TTL) meta = fields.Nested(MetaItem, required=True) class PlaylistAdditionEvent(InputEventBase): class Data(MetaExcludeUnknown): content = fields.Nested(PlaylistAdditionContent, required=True) data = fields.Nested(Data, required=True) class PlaylistUpdateEvent(InputEventBase): class Data(Schema): content = fields.Nested(PlaylistUpdateContent, required=True) data = fields.Nested(Data, required=True) class PlaylistDropContent(MetaExcludeUnknown): track = fields.Nested(Track, required=True) playlist = fields.Nested(Playlist, required=True) previous_position = fields.Int(required=True) class PlaylistDropEvent(InputEventBase): class Data(MetaExcludeUnknown): content = fields.Nested(PlaylistDropContent, required=True) data = fields.Nested(Data, required=True) class PlaylistMajorMoveContent(MetaExcludeUnknown): track = fields.Nested(Track, required=True) playlist = fields.Nested(Playlist, required=True) current_position = fields.Int(required=True) previous_position = fields.Int(required=True) class PlaylistMajorMoveEvent(InputEventBase): class Data(MetaExcludeUnknown): content = fields.Nested(PlaylistMajorMoveContent, required=True) data = fields.Nested(Data, required=True) EVENT_TYPE_TO_INPUT_SCHEMA = { EventType.ADDITION: PlaylistAdditionEvent(), EventType.UPDATE: PlaylistUpdateEvent(), EventType.DROP: PlaylistDropEvent(), EventType.MAJOR_MOVE: PlaylistMajorMoveEvent() }