Skip to content

Commit

Permalink
Implement a generic way of creating related resources, based on the t…
Browse files Browse the repository at this point in the history
…ype attribute
  • Loading branch information
ppawlak committed Dec 17, 2020
1 parent 82e84e0 commit 0c621cc
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 14 deletions.
22 changes: 20 additions & 2 deletions appstoreconnect/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,27 @@ def _get_resource(self, Resource, resource_id):
payload = self._api_call(url)
return Resource(payload.get('data', {}), self)

def _get_related_resource(self, Resource, full_url):
def _get_resource_from_payload_data(self, payload):
try:
resource_type = resources[payload.get('type')]
except KeyError:
raise APIError("Unsupported resource type %s" % resources[payload.get('type')])

return resource_type(payload, self)

def get_related_resource(self, full_url):
payload = self._api_call(full_url)
return Resource(payload.get('data', {}), self)
data = payload.get('data')
if data is None:
return None
elif type(data) == dict:
return self._get_resource_from_payload_data(data)

def get_related_resources(self, full_url):
payload = self._api_call(full_url)
data = payload.get('data', [])
for resource in data:
yield self._get_resource_from_payload_data(resource)

def _create_resource(self, Resource, args):
attributes = {}
Expand Down
26 changes: 14 additions & 12 deletions appstoreconnect/resources.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import inspect
from abc import ABC, abstractmethod
import sys

Expand All @@ -12,22 +13,16 @@ def __getattr__(self, item):
return self._data.get('id')
if item in self._data.get('attributes', {}):
return self._data.get('attributes', {})[item]
if item in self._data.get('relationships', {}):
def callable():
if item in self.relationships:
def getter():
# Try to fetch relationship
nonlocal item
is_resources = item[-1] == 's'
try:
item_cls = getattr(sys.modules[__name__], item[0].upper() + (item[1:-1] if is_resources else item[1:]))
except AttributeError:
item_cls = Resource
url = self._data.get('relationships', {})[item]['links']['related']
# List of resources
if is_resources:
return self._api._get_resources(item_cls, full_url=url)
if self.relationships[item]['multiple']:
return self._api.get_related_resources(full_url=url)
else:
return self._api._get_related_resource(item_cls, full_url=url)
return callable
return self._api.get_related_resource(full_url=url)
return getter

raise AttributeError('%s have no attributes %s' % (self.type_name, item))

Expand Down Expand Up @@ -211,3 +206,10 @@ class FinanceReport(Resource):
class SalesReport(Resource):
endpoint = '/v1/salesReports'
filters = 'https://developer.apple.com/documentation/appstoreconnectapi/download_sales_and_trends_reports'


# create an index of Resources by type
resources = {}
for name, obj in inspect.getmembers(sys.modules[__name__]):
if inspect.isclass(obj) and issubclass(obj, Resource) and hasattr(obj, 'type') and obj != Resource:
resources[getattr(obj, 'type')] = obj

0 comments on commit 0c621cc

Please sign in to comment.