from marshmallow import Schema, EXCLUDE, fields from charts_push_messages.constants import FeedMessageFields class MetaExcludeUnknown(Schema): """Schema to exclude unknown fields to have a predicted structure of incoming event/message""" class Meta: unknown = EXCLUDE class MetaNested(MetaExcludeUnknown): """Schema for nested meta ex: { "domain": "feed_message", "dsp": "spotify"/"apple", "country_code": any country code (ex: "us") "type": One Of : ("starred_track_top_chart_entry", "starred_track_top_chart_exit", "starred_track_top_chart_move") } """ domain = fields.String() dsp = fields.String() country_code = fields.String() type = fields.String() subject = fields.String(required=True) class FeedMessageCreatedSchema(MetaExcludeUnknown): """Schema for FeedMessageCreated event/message ex: { "id": str # feed message db_record id "app": str = "apollo" "code": str = "feed_messages_created" "ttl": int # period (sec) during the event is actual "created_at": datetime "meta": { "domain": "feed_message", "dsp": str = "spotify"/"apple", "country_code": str = "us", "type": One Of: "starred_track_top_chart_entry", "starred_track_top_chart_exit", "starred_track_top_chart_move" } "publisher": { "id": str = "user_data_api_ecs_web_test", "owner": str = "apollo", "type": str = "ecs_web" "instance": str = "ecs:test86876" "env": str = "test" } } """ id = fields.Integer(required=True) app = fields.String() code = fields.String() ttl = fields.Integer(required=True) created_at = fields.DateTime(required=True) meta = fields.Nested(MetaNested) class DataNested(MetaExcludeUnknown): """Schema for Feed Message nested field ex: { "recipient": { "devices": [ { "expo_token": "djfjglfd", "id": "123" }, ] }, "content": { "track": { "id": "test_track_id", "isrc": "test_track_isrc", "name": "test_track_name", "image_url": "test_track_image_url", "artists": [ { "id": "some_test_artists_id", "name": "some_name" } ], "favorites_id": "123", }, "chart": { "name": "Spotify Daily Top 200 Chart" }, "current_position": None, "previous_position": 999, "body": "I am a body message", "title": "" }, }, """ class DataResipientNested(MetaExcludeUnknown): class DataResipientDeviceNested(MetaExcludeUnknown): expo_token = fields.String(required=True) id = fields.Integer(required=True) devices = fields.List(fields.Nested(DataResipientDeviceNested)) class DataContentNested(MetaExcludeUnknown): class DataContentTrackNested(MetaExcludeUnknown): class DataContentTrackArtistsNested(MetaExcludeUnknown): id = fields.String(required=True) name = fields.String(required=True) id = fields.String(required=True) isrc = fields.String(required=True) name = fields.String(required=True) image_url = fields.String(required=True) artists = fields.List(fields.Nested(DataContentTrackArtistsNested)) favorites_id = fields.Integer() class DataContentChartNested(MetaExcludeUnknown): name = fields.String(required=True) track = fields.Nested(DataContentTrackNested) chart = fields.Nested(DataContentChartNested) current_position = fields.Integer(required=True, allow_none=True) previous_position = fields.Integer(required=True, allow_none=True) body = fields.String(required=True) title = fields.String(load_default="") recipient = fields.Nested(DataResipientNested) content = fields.Nested(DataContentNested) class FeedMessageCreatedWithDataSchema(FeedMessageCreatedSchema): """Schema for Feed Message with and fields ex: { "id": int, "ttl": int, "status": True, "created_at": datetime, "updated_at": datetime, "event_id": int, "account_id": int, "message_id": int, "meta": { "domain": str "feed_message", "dsp": str "spotify"/"apple", "country_code": str any country code (ex: "us") "type": str One of ("starred_track_top_chart_entry", "starred_track_top_chart_exit", "starred_track_top_chart_move") }, "data": { "recipient": { "devices": [ { "expo_token": str "djfjglfd", "id": int }, ] }, "content": { "track": { "id": "track_id", "isrc": "track_isrc", "name": "track_name", "image_url": "test_track_image_url", "artists": [ { "id": "some_artists_id", "name": "some_artists_name" } ], "favorites_id": Optional[int], }, "chart": { "name": str One of: "Spotify Daily Top 200 Chart"/"Apple Music Top 100 Chart" }, "current_position": int or None based on meta.type, "previous_position": int or None based on meta.type, "body": "User friendly message about wht exactly happened in the chart", "title": str "" for our case probably should be an emptu string }, }, } """ class Meta: exclude = FeedMessageFields.EXCLUDE.value unknown = EXCLUDE status = fields.Bool() updated_at = fields.DateTime(required=True) event_id = fields.Integer(required=True) account_id = fields.Integer() message_id = fields.Integer(required=True) data = fields.Nested(DataNested)