Skip to content
This repository was archived by the owner on Jun 11, 2024. It is now read-only.

Commit 667373c

Browse files
committed
atomx.Atomx.get also accepts a model class or instance as resource argument
1 parent 069f55d commit 667373c

4 files changed

Lines changed: 41 additions & 20 deletions

File tree

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
- Add :meth:`atomx.models.ScheduledReport.save` to edit ``name`` and ``emails``
1616
of a :class:`atomx.models.ScheduledReport`
17+
- :meth:`atomx.Atomx.get` also accepts a model class or instance as resource argument.
18+
E.g.: ``atomx_api.get(atomx.models.Advertiser)`` or ``atomx_api.get(atomx.models.Advertiser(42))``
1719

1820

1921
1.4

atomx/__init__.py

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
datetime,
55
timedelta,
66
)
7+
from inspect import isclass
78
import requests
89
from atomx.version import API_VERSION, VERSION
910
from atomx import models
@@ -78,7 +79,7 @@ def login(self, email=None, password=None):
7879
raise InvalidCredentials
7980
raise APIError(r.json()['error'])
8081
self.auth_tkt = r.json()['auth_tkt']
81-
self.user = models.User(**r.json()['user'])
82+
self.user = models.User(session=self, **r.json()['user'])
8283

8384
def logout(self):
8485
"""Removes authentication token from session."""
@@ -236,9 +237,9 @@ def report(self, scope=None, groups=None, metrics=None, where=None, from_=None,
236237
self.last_response = r_json
237238

238239
if is_scheduled_report:
239-
return models.ScheduledReport(self, **report)
240+
return models.ScheduledReport(session=self, **report)
240241

241-
return models.Report(self, **report)
242+
return models.Report(session=self, **report)
242243

243244
def report_status(self, report):
244245
"""Get the status for a `report`.
@@ -314,6 +315,8 @@ def get(self, resource, *args, **kwargs):
314315
>>> publisher = atomx.get('publisher/23')
315316
>>>> # or get the same publisher using the id as parameter
316317
>>> publisher = atomx.get('publisher', 23)
318+
>>>> # or use an atomx model
319+
>>> publisher = atomx.get(atomx.models.Publisher(23))
317320
>>> assert publisher.id == 23
318321
>>> assert isinstance(publisher, atomx.models.Publisher)
319322
@@ -347,7 +350,15 @@ def get(self, resource, *args, **kwargs):
347350
348351
:return: a class from :mod:`.models` or a list of models depending on param `resource`
349352
"""
350-
resource = resource.strip('/')
353+
if isclass(resource) and issubclass(resource, models.AtomxModel):
354+
resource = resource._resource_name
355+
elif isinstance(resource, models.AtomxModel):
356+
resource_path = resource._resource_name
357+
if hasattr(resource, 'id'):
358+
resource_path += '/' + str(resource.id)
359+
resource = resource_path
360+
else:
361+
resource = resource.strip('/')
351362
for a in args:
352363
resource += '/' + str(a)
353364
r = self.session.get(self.api_endpoint + resource, params=kwargs)
@@ -363,12 +374,12 @@ def get(self, resource, *args, **kwargs):
363374
model = get_model_name(model_name)
364375
if model and res:
365376
if isinstance(res, list):
366-
return [getattr(models, model)(self, **m) for m in res]
367-
return getattr(models, model)(self, **res)
377+
return [getattr(models, model)(session=self, **m) for m in res]
378+
return getattr(models, model)(session=self, **res)
368379
elif model_name == 'reporting': # special case for `/reports` status
369380
return {
370-
'reports': [models.Report(self, **m) for m in res['reports']],
371-
'scheduled': [models.ScheduledReport(self, **m) for m in res['scheduled']]
381+
'reports': [models.Report(session=self, **m) for m in res['reports']],
382+
'scheduled': [models.ScheduledReport(session=self, **m) for m in res['scheduled']]
372383
}
373384
return res
374385

@@ -394,7 +405,7 @@ def post(self, resource, json, **kwargs):
394405
self.last_response = r_json
395406
model = get_model_name(model_name)
396407
if model and isinstance(res, list):
397-
return [getattr(models, model)(self, **m) for m in res]
408+
return [getattr(models, model)(session=self, **m) for m in res]
398409
return res
399410

400411
def put(self, resource, id, json, **kwargs):

atomx/models.py

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from io import StringIO
99
except ImportError: # py2
1010
from StringIO import StringIO
11+
from atomx.utils import _class_property
1112
from atomx.exceptions import (
1213
NoSessionError,
1314
ModelNotFoundError,
@@ -26,15 +27,11 @@
2627
class AtomxModel(object):
2728
"""A generic atomx model that the other models from :mod:`atomx.models` inherit from.
2829
30+
:param int id: Optional model ID. Can also be passed in via `attributes` as `id`.
2931
:param atomx.Atomx session: The :class:`atomx.Atomx` session to use for the api requests.
3032
:param attributes: model attributes
3133
"""
32-
def __init__(self, session=None, **attributes):
33-
"""Atomx model for {model}. test
34-
:param session: session
35-
:param attributes: attributes
36-
:return: model.{model}
37-
"""
34+
def __init__(self, id=None, session=None, **attributes):
3835
for k, v in attributes.items():
3936
if k.endswith('_at'):
4037
try:
@@ -46,6 +43,8 @@ def __init__(self, session=None, **attributes):
4643
attributes[k] = datetime.strptime(v, '%Y-%m-%d')
4744
except (ValueError, TypeError):
4845
pass
46+
if id is not None:
47+
attributes['id'] = id
4948

5049
super(AtomxModel, self).__setattr__('session', session)
5150
super(AtomxModel, self).__setattr__('_attributes', attributes)
@@ -96,10 +95,10 @@ def __repr__(self):
9695
def __eq__(self, other):
9796
return self.id == getattr(other, 'id', 'INVALID')
9897

99-
@property
100-
def _resource_name(self):
98+
@_class_property
99+
def _resource_name(cls):
101100
from atomx.utils import model_name_to_rest
102-
return model_name_to_rest(self.__class__.__name__)
101+
return model_name_to_rest(cls.__name__)
103102

104103
@property
105104
def _dirty_json(self):
@@ -196,7 +195,7 @@ class ScheduledReport(object):
196195
<https://wiki.atomx.com/reporting#scheduling_reports>`_.
197196
"""
198197

199-
def __init__(self, session, id, name, emails, query, **kwargs):
198+
def __init__(self, id, session, name, emails, query, **kwargs):
200199
self.session = session
201200
self.id = id
202201
self.name = name
@@ -229,7 +228,7 @@ def delete(self, session=None):
229228
class Report(object):
230229
"""Represents a `report` you get back from :meth:`atomx.Atomx.report`."""
231230

232-
def __init__(self, session, query, fast, id, lines, error, link,
231+
def __init__(self, id, session, query, fast, lines, error, link,
233232
started, finished, is_ready, duration, name, **kwargs):
234233
self.session = session
235234
self.query = query

atomx/utils.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,12 @@ def model_name_to_rest(name):
7272
r += '-'
7373
r += name[i]
7474
return r.lower()
75+
76+
77+
class _class_property(object):
78+
"""Decorator to create @classmethod and @property"""
79+
def __init__(self, f):
80+
self.f = f
81+
82+
def __get__(self, obj, owner):
83+
return self.f(owner)

0 commit comments

Comments
 (0)