From b73890b9269772b213c44f3b35b340742e2f8a82 Mon Sep 17 00:00:00 2001 From: geuben Date: Wed, 17 Jun 2020 16:06:27 +0100 Subject: [PATCH] Support TicketIntegration --- livestyled/client.py | 2 + livestyled/models/__init__.py | 2 + livestyled/models/ticket.py | 18 +++- livestyled/models/ticket_integration.py | 88 +++++++++++++++++++ livestyled/resource_client.py | 21 +++++ livestyled/schemas/__init__.py | 2 + .../tests/fixtures/example_ticket.json | 20 ++++- .../fixtures/example_ticket_integration.json | 18 ++++ livestyled/schemas/tests/test_ticket.py | 15 ++++ .../schemas/tests/test_ticket_integration.py | 26 ++++++ livestyled/schemas/ticket.py | 4 +- livestyled/schemas/ticket_integration.py | 23 +++++ 12 files changed, 236 insertions(+), 3 deletions(-) create mode 100644 livestyled/models/ticket_integration.py create mode 100644 livestyled/schemas/tests/fixtures/example_ticket_integration.json create mode 100644 livestyled/schemas/tests/test_ticket_integration.py create mode 100644 livestyled/schemas/ticket_integration.py diff --git a/livestyled/client.py b/livestyled/client.py index 96bbf3c..ec78233 100644 --- a/livestyled/client.py +++ b/livestyled/client.py @@ -115,6 +115,8 @@ def _api_post( }, data=json.dumps(data) ) + if response.status_code >= 400: + print(response.json()) response.raise_for_status() return response.json() diff --git a/livestyled/models/__init__.py b/livestyled/models/__init__.py index dc2acb4..810653f 100644 --- a/livestyled/models/__init__.py +++ b/livestyled/models/__init__.py @@ -31,6 +31,7 @@ from livestyled.models.sport_venue import SportVenue from livestyled.models.team import Team from livestyled.models.ticket import Ticket +from livestyled.models.ticket_integration import TicketIntegration from livestyled.models.user import User, UserInfo, UserSSO __all__ = [ @@ -65,6 +66,7 @@ SportVenue, Team, Ticket, + TicketIntegration, UserInfo, User, UserSSO diff --git a/livestyled/models/ticket.py b/livestyled/models/ticket.py index 6e094aa..e1631ca 100644 --- a/livestyled/models/ticket.py +++ b/livestyled/models/ticket.py @@ -1,3 +1,4 @@ +from livestyled.models.ticket_integration import TicketIntegration from livestyled.models.user import User @@ -42,6 +43,7 @@ def __init__( legal_short_text=None, map_url=None, map_image_url=None, + ticket_integration=None ): self.id = id self.external_ticket_id = external_ticket_id @@ -96,6 +98,13 @@ def __init__( self.legal_short_text = legal_short_text self.map_url = map_url self.map_image_url = map_image_url + if ticket_integration: + if isinstance(ticket_integration, dict): + self._ticket_integration = TicketIntegration(**ticket_integration) + elif isinstance(ticket_integration, (int, str)): + self._ticket_integration = TicketIntegration.placeholder(ticket_integration) + else: + self._ticket_integration = None @classmethod def placeholder( @@ -141,6 +150,7 @@ def placeholder( legal_short_text=None, map_url=None, map_image_url=None, + ticket_integration=None ) @classmethod @@ -181,6 +191,7 @@ def create_new( legal_short_text=None, map_url=None, map_image_url=None, + ticket_integration=None ): ticket = Ticket( id=None, @@ -221,6 +232,7 @@ def create_new( legal_short_text=legal_short_text, map_url=map_url, map_image_url=map_image_url, + ticket_integration=ticket_integration ) if isinstance(user, (str, int)): user = User.placeholder(id=user) @@ -273,6 +285,10 @@ def sharer(self): def parent_ticket(self): return self._parent_ticket + @property + def ticket_integration(self): + return self._ticket_integration + def __repr__(self): return ''.format(self=self) @@ -283,7 +299,7 @@ def diff(self, other): 'barcode', 'sector_name', 'venue_name', 'venue_room', 'client_name', 'premium', 'client_email', 'price', 'status', 'can_share', 'sharer_email', 'redeemed_at', 'redeemer_id', 'share_code', 'redeemer_email', 'parent_ticket', 'shared_at', 'legal_long_text', 'legal_short_text', 'map_url', - 'map_image_url' + 'map_image_url', 'ticket_integration' ) for field in fields: if getattr(self, field) != getattr(other, field): diff --git a/livestyled/models/ticket_integration.py b/livestyled/models/ticket_integration.py new file mode 100644 index 0000000..48d0de6 --- /dev/null +++ b/livestyled/models/ticket_integration.py @@ -0,0 +1,88 @@ +class TicketIntegration: + def __init__( + self, + id, + label, + name, + adapter, + config_payload, + endpoint_url, + auth_required, + module, + login_request, + default, + can_share + ): + self.id = id + self.label = label + self.name = name + self.adapter = adapter + self.config_payload = config_payload + self.endpoint_url = endpoint_url + self.auth_required = auth_required + self.module = module + self.login_request = login_request + self.default = default + self.can_share = can_share + + @classmethod + def placeholder( + cls, + id + ): + return cls( + id=id, + label=None, + name=None, + adapter=None, + config_payload=None, + endpoint_url=None, + auth_required=None, + module=None, + login_request=None, + default=None, + can_share=None + ) + + @classmethod + def create_new( + cls, + endpoint_url, + login_request, + adapter, + label=None, + name=None, + config_payload=None, + auth_required=None, + module=None, + default=None, + can_share=None + ): + ticket_integration = TicketIntegration( + id=None, + label=label, + name=name, + adapter=adapter, + config_payload=config_payload, + endpoint_url=endpoint_url, + auth_required=auth_required, + module=module, + login_request=login_request, + default=default, + can_share=can_share + ) + return ticket_integration + + def __repr__(self): + return ''.format(self=self) + + def diff(self, other): + differences = {} + fields = ( + 'label', 'name', 'endpoint_url', 'adapter', 'config_payload', + 'auth_required', 'module', 'login_request', 'default', 'can_share' + ) + for field in fields: + if getattr(self, field) != getattr(other, field): + differences[field] = getattr(self, field) + return differences diff --git a/livestyled/resource_client.py b/livestyled/resource_client.py index 6cf6a54..427e799 100644 --- a/livestyled/resource_client.py +++ b/livestyled/resource_client.py @@ -27,6 +27,7 @@ SportVenue, Team, Ticket, + TicketIntegration, User, UserInfo, UserSSO, @@ -52,6 +53,7 @@ SeasonSchema, SportVenueSchema, TeamSchema, + TicketIntegrationSchema, TicketSchema, UserCreateSchema, UserInfoSchema, @@ -811,3 +813,22 @@ def get_product_categories( self, ) -> Generator[ProductCategory, None, None]: return self._get_resource_list(ProductCategorySchema) + + # ---- TICKET INTEGRATIONS + + def get_ticket_integrations( + self, + ) -> Generator[TicketIntegration, None, None]: + return self._get_resource_list(TicketIntegrationSchema) + + def get_ticket_integration( + self, + id + ) -> TicketIntegration: + return self._get_resource_by_id(TicketIntegrationSchema, id) + + def create_ticket_integration( + self, + ticket_integration: TicketIntegration + ) -> TicketIntegration: + return self._create_resource(TicketIntegrationSchema, ticket_integration) diff --git a/livestyled/schemas/__init__.py b/livestyled/schemas/__init__.py index 8ea6124..084ee9a 100644 --- a/livestyled/schemas/__init__.py +++ b/livestyled/schemas/__init__.py @@ -22,6 +22,7 @@ from livestyled.schemas.sport_venue import SportVenueSchema from livestyled.schemas.team import TeamSchema from livestyled.schemas.ticket import TicketSchema +from livestyled.schemas.ticket_integration import TicketIntegrationSchema from livestyled.schemas.user import UserCreateSchema, UserInfoSchema, UserSchema, UserSSOSchema __all__ = [ @@ -50,6 +51,7 @@ SeasonSchema, SportVenueSchema, TeamSchema, + TicketIntegrationSchema, TicketSchema, UserCreateSchema, UserInfoSchema, diff --git a/livestyled/schemas/tests/fixtures/example_ticket.json b/livestyled/schemas/tests/fixtures/example_ticket.json index 99a23a2..b7c51e2 100644 --- a/livestyled/schemas/tests/fixtures/example_ticket.json +++ b/livestyled/schemas/tests/fixtures/example_ticket.json @@ -19,5 +19,23 @@ "canShare": true, "status": "active", "legalLongText": "this is the legal long text this is the legal long text this is the legal long text this is the legal long text this is the legal long text this is the legal long text this is the legal long text this is the legal long text this is the legal long text this is the legal long text this is the legal long text this is the legal long text this is the legal long text this is the legal long text", - "legalShortText": "More information or questions regarding the ADA ticket" + "legalShortText": "More information or questions regarding the ADA ticket", + "ticketIntegration": { + "@context": "/v4/contexts/TicketIntegration", + "@id": "/v4/ticket_integrations/17", + "@type": "TicketIntegration", + "id": 17, + "endpointUrl": "XXXXXXsd", + "label": "XXXXXXdsds", + "name": "SeatGeek", + "loginRequest": "XXXXXXXdsds", + "adapter": "XXXXXXds", + "default": false, + "createdAt": "2018-07-19T15:10:00+00:00", + "updatedAt": "2020-01-27T14:57:57+00:00", + "module": "SHARE", + "authRequired": false, + "canShare": false, + "app": "/v4/apps/27" + } } \ No newline at end of file diff --git a/livestyled/schemas/tests/fixtures/example_ticket_integration.json b/livestyled/schemas/tests/fixtures/example_ticket_integration.json new file mode 100644 index 0000000..8f2785e --- /dev/null +++ b/livestyled/schemas/tests/fixtures/example_ticket_integration.json @@ -0,0 +1,18 @@ +{ + "@context": "/v4/contexts/TicketIntegration", + "@id": "/v4/ticket_integrations/17", + "@type": "TicketIntegration", + "id": 17, + "endpointUrl": "XXXXXXsd", + "label": "XXXXXXdsds", + "name": "SeatGeek", + "loginRequest": "XXXXXXXdsds", + "adapter": "XXXXXXds", + "default": false, + "createdAt": "2018-07-19T15:10:00+00:00", + "updatedAt": "2020-01-27T14:57:57+00:00", + "module": "SHARE", + "authRequired": false, + "canShare": false, + "app": "/v4/apps/27" +} \ No newline at end of file diff --git a/livestyled/schemas/tests/test_ticket.py b/livestyled/schemas/tests/test_ticket.py index 8eed6c3..91aa1f7 100644 --- a/livestyled/schemas/tests/test_ticket.py +++ b/livestyled/schemas/tests/test_ticket.py @@ -57,6 +57,19 @@ def test_deserialize_ticket(): 'legal_short_text': 'More information or questions regarding the ADA ticket', 'map_url': None, 'map_image_url': None, + 'ticket_integration': { + 'adapter': 'XXXXXXds', + 'auth_required': False, + 'can_share': False, + 'config_payload': None, + 'default': False, + 'endpoint_url': 'XXXXXXsd', + 'id': 17, + 'label': 'XXXXXXdsds', + 'login_request': 'XXXXXXXdsds', + 'module': 'SHARE', + 'name': 'SeatGeek' + }, } @@ -103,6 +116,7 @@ def test_deserialize_ticket_shared(): 'legal_short_text': None, 'map_url': None, 'map_image_url': None, + 'ticket_integration': None } @@ -149,4 +163,5 @@ def test_deserialize_ticket_shared_redeemed(): 'legal_short_text': None, 'map_url': None, 'map_image_url': None, + 'ticket_integration': None } diff --git a/livestyled/schemas/tests/test_ticket_integration.py b/livestyled/schemas/tests/test_ticket_integration.py new file mode 100644 index 0000000..114812e --- /dev/null +++ b/livestyled/schemas/tests/test_ticket_integration.py @@ -0,0 +1,26 @@ +import os + +from livestyled.schemas.ticket_integration import TicketIntegrationSchema + + +FIXTURES_DIR = os.path.join(os.path.dirname(__file__), 'fixtures') +TEST_API_DOMAIN = 'test.livestyled.com' + + +def test_deserialize_ticket_integration(): + with open(os.path.join(FIXTURES_DIR, 'example_ticket_integration.json'), 'r') as fixture_file: + ticket_integration = fixture_file.read() + deserialized_ticket_integration = TicketIntegrationSchema().loads(ticket_integration) + assert deserialized_ticket_integration == { + 'adapter': 'XXXXXXds', + 'auth_required': False, + 'can_share': False, + 'config_payload': None, + 'endpoint_url': 'XXXXXXsd', + 'id': 17, + 'default': False, + 'label': 'XXXXXXdsds', + 'login_request': 'XXXXXXXdsds', + 'module': 'SHARE', + 'name': 'SeatGeek', + } diff --git a/livestyled/schemas/ticket.py b/livestyled/schemas/ticket.py index 7eb7fa2..069ef06 100644 --- a/livestyled/schemas/ticket.py +++ b/livestyled/schemas/ticket.py @@ -2,7 +2,8 @@ from marshmallow_polyfield import PolyField from livestyled.models.ticket import Ticket -from livestyled.schemas.fields import RelatedResourceLinkField +from livestyled.schemas.fields import RelatedResourceField, RelatedResourceLinkField +from livestyled.schemas.ticket_integration import TicketIntegrationSchema from livestyled.schemas.user import UserSchema @@ -64,3 +65,4 @@ class Meta: legal_long_text = fields.String(data_key='legalLongText', required=False, allow_none=True, missing=None) map_url = fields.String(data_key='mapUrl', required=False, allow_none=True, missing=None) map_image_url = fields.String(data_key='mapImageUrl', required=False, allow_none=True, missing=None) + ticket_integration = RelatedResourceField(schema=TicketIntegrationSchema, required=False, missing=None, data_key='ticketIntegration') diff --git a/livestyled/schemas/ticket_integration.py b/livestyled/schemas/ticket_integration.py new file mode 100644 index 0000000..973086a --- /dev/null +++ b/livestyled/schemas/ticket_integration.py @@ -0,0 +1,23 @@ +from marshmallow import EXCLUDE, fields, Schema + +from livestyled.models.ticket_integration import TicketIntegration + + +class TicketIntegrationSchema(Schema): + class Meta: + unknown = EXCLUDE + api_type = 'ticket_integrations' + url = 'v4/ticket_integrations' + model = TicketIntegration + + id = fields.Int() + label = fields.String(required=False, missing=None) + name = fields.String(required=False, missing=None) + adapter = fields.String(required=False, missing=None) + endpoint_url = fields.String(required=False, missing=None, data_key='endpointUrl') + config_payload = fields.String(required=False, missing=None, data_key='configPayload') + auth_required = fields.Boolean(required=False, missing=None, data_key='authRequired') + module = fields.String(required=False, missing=None) + login_request = fields.String(required=False, missing=None, data_key='loginRequest') + default = fields.Boolean(required=False, missing=None, data_key='default') + can_share = fields.Boolean(required=False, missing=None, data_key='canShare')