Skip to content

Commit cf6c5cb

Browse files
committed
Adding some type hints; Adding owner to search parameters; Fixed fire-and-forget functionality for inventory.
1 parent aae61e1 commit cf6c5cb

File tree

4 files changed

+30
-22
lines changed

4 files changed

+30
-22
lines changed

c8y_api/__init__.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222

2323
class CumulocityRestApi:
2424

25+
ACCEPT_MANAGED_OBJECT = 'application/vnd.com.nsn.cumulocity.managedobject+json'
26+
2527
def __init__(self, base_url, tenant_id, username, password, tfa_token=None, application_key=None):
2628
self.base_url = base_url
2729
self.tenant_id = tenant_id
@@ -70,7 +72,8 @@ def post(self, resource, json, accept='application/json', content_type=None):
7072
raise SyntaxError(f"Invalid POST request. Status: {r.status_code} Response:\n" + r.text)
7173
if r.status_code != 201 and r.status_code != 200:
7274
raise ValueError(f"Unable to perform POST request. Status: {r.status_code} Response:\n" + r.text)
73-
return r.json()
75+
if r.content:
76+
return r.json()
7477

7578
def post_file(self, resource, file, binary_meta_information):
7679
assert isinstance(binary_meta_information, Binary)
@@ -106,7 +109,8 @@ def put(self, resource, json, accept='application/json', content_type=None):
106109
raise SyntaxError(f"Invalid PUT request. Status: {r.status_code} Response:\n" + r.text)
107110
if r.status_code != 200:
108111
raise ValueError(f"Unable to perform PUT request. Status: {r.status_code} Response:\n" + r.text)
109-
return r.json()
112+
if r.content:
113+
return r.json()
110114

111115
def put_file(self, resource, file, media_type):
112116
headers = {'Content-Type': media_type, **self.__default_headers}

c8y_api/model/_util.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -444,7 +444,7 @@ def __prepare_resource(resource: str):
444444
return '/' + resource.strip('/')
445445

446446
@staticmethod
447-
def __prepare_query_parameters(type=None, name=None, fragment=None, source=None,
447+
def __prepare_query_parameters(type=None, name=None, fragment=None, source=None, owner=None,
448448
before=None, after=None, min_age=None, max_age=None,
449449
reverse=None, page_size=None, **kwargs):
450450
# min_age/max_age should be timedelta objects that can be used for
@@ -465,7 +465,7 @@ def __prepare_query_parameters(type=None, name=None, fragment=None, source=None,
465465
before = _DateUtil.ensure_timestring(before)
466466
after = _DateUtil.ensure_timestring(after)
467467

468-
params = {k: v for k, v in {'type': type, 'name': name,
468+
params = {k: v for k, v in {'type': type, 'name': name, 'owner': owner,
469469
'source': source, 'fragmentType': fragment,
470470
'dateFrom': after, 'dateTo': before, 'revert': str(reverse),
471471
'pageSize': page_size}.items() if v}
@@ -506,20 +506,21 @@ def _iterate(self, base_query, limit, parse_func):
506506

507507
def _create(self, jsonify_func, *objects):
508508
for o in objects:
509-
self.c8y.post(self.resource, jsonify_func(o))
509+
self.c8y.post(self.resource, json=jsonify_func(o), accept=None)
510510

511511
def _create_bulk(self, jsonify_func, collection_name, content_type, *objects):
512512
bulk_json = {collection_name: [jsonify_func(o) for o in objects]}
513513
self.c8y.post(self.resource, bulk_json, content_type=content_type)
514514

515515
def _update(self, jsonify_func, *objects):
516516
for o in objects:
517-
self.c8y.put(self.resource + '/' + str(o.id), jsonify_func(o))
517+
self.c8y.put(self.resource + '/' + str(o.id), json=jsonify_func(o), accept=None)
518518

519519
def _apply_to(self, jsonify_func, model, *object_ids):
520520
model_json = jsonify_func(model)
521+
print(model_json)
521522
for object_id in object_ids:
522-
self.c8y.put(self.resource + '/' + str(object_id), model_json)
523+
self.c8y.put(self.resource + '/' + str(object_id), model_json, accept=None)
523524

524525
def delete(self, *objects):
525526
""" Delete one or more objects within the database.

c8y_api/model/administration.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -713,7 +713,7 @@ def select(self, username=None, page_size=5):
713713
"""
714714
if username:
715715
# select by username
716-
query = f'user/{self.c8y.tenant_id}/users/{username}/groups?pageSize={page_size}&currentPage='
716+
query = f'/user/{self.c8y.tenant_id}/users/{username}/groups?pageSize={page_size}&currentPage='
717717
page_number = 1
718718
while True:
719719
response_json = self.c8y.get(query + str(page_number))

c8y_api/model/inventory.py

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def __getattr__(self, name):
8989
item = self.items[name]
9090
return item if not isinstance(item, dict) else _DictWrapper(item)
9191

92-
def has(self, name):
92+
def has(self, name) -> bool:
9393
""" Check whether a specific element is defined.
9494
9595
:param name: Name of the element
@@ -232,7 +232,7 @@ def from_json(cls, object_json):
232232
def _parse_references(cls, base_json):
233233
return [NamedObject.from_json(j['managedObject']) for j in base_json['references']]
234234

235-
def to_json(self):
235+
def to_json(self) -> dict:
236236
""" Convert the instance to JSON.
237237
238238
The JSON format produced by this function is what is used by the
@@ -245,7 +245,7 @@ def to_json(self):
245245
"""
246246
return self._parser.to_full_json(self)
247247

248-
def to_diff_json(self):
248+
def to_diff_json(self) -> dict:
249249
""" Convert the changes made to this instance to a JSON representation.
250250
251251
The JSON format produced by this function is what is used by the
@@ -287,7 +287,8 @@ def create(self):
287287
See also function Inventory.create which doesn't parse the result.
288288
"""
289289
super()._assert_c8y()
290-
result_json = self.c8y.post(self.__RESOURCE, self.to_json())
290+
result_json = self.c8y.post(self.__RESOURCE,
291+
json=self.to_json(), accept=self.c8y.ACCEPT_MANAGED_OBJECT)
291292
result = ManagedObject.from_json(result_json)
292293
result.c8y = self.c8y
293294
return result
@@ -302,7 +303,8 @@ def update(self):
302303
"""
303304
super()._assert_c8y()
304305
super()._assert_id()
305-
result_json = self.c8y.put(self._build_object_path(), self.to_diff_json())
306+
result_json = self.c8y.put(self._build_object_path(),
307+
json=self.to_diff_json(), accept=self.c8y.ACCEPT_MANAGED_OBJECT)
306308
result = ManagedObject.from_json(result_json)
307309
result.c8y = self.c8y
308310
return result
@@ -312,14 +314,15 @@ def apply_to(self, other_id):
312314
database.
313315
314316
:param other_id: Database ID of the event to update.
315-
:returns: A fresh ManagedObject instance representing the updated
317+
:return: A fresh :class:ManagedObject instance representing the updated
316318
object within the database.
317319
318-
See also function Inventory.apply_to which doesn't parse the result.
320+
See also function :class:Inventory.apply_to which doesn't parse the result.
319321
"""
320322
self._assert_c8y()
321323
# put diff json to another object (by ID)
322-
result_json = self.c8y.put(self.__RESOURCE + other_id, self.to_diff_json())
324+
result_json = self.c8y.put(self.__RESOURCE + str(other_id),
325+
json=self.to_diff_json(), accept=self.c8y.ACCEPT_MANAGED_OBJECT)
323326
result = ManagedObject.from_json(result_json)
324327
result.c8y = self.c8y
325328
return result
@@ -640,7 +643,7 @@ class Inventory(_Query):
640643
def __init__(self, c8y):
641644
super().__init__(c8y, 'inventory/managedObjects')
642645

643-
def get(self, id): # noqa (id)
646+
def get(self, id) -> ManagedObject: # noqa (id)
644647
""" Retrieve a specific managed object from the database.
645648
646649
:param id: ID of the managed object
@@ -651,7 +654,7 @@ def get(self, id): # noqa (id)
651654
managed_object.c8y = self.c8y # inject c8y connection into instance
652655
return managed_object
653656

654-
def get_all(self, type=None, fragment=None, name=None, limit=None, page_size=1000): # noqa (type)
657+
def get_all(self, type=None, fragment=None, name=None, owner=None, limit=None, page_size=1000): # noqa (type)
655658
""" Query the database for managed objects and return the results
656659
as list.
657660
@@ -662,7 +665,7 @@ def get_all(self, type=None, fragment=None, name=None, limit=None, page_size=100
662665
"""
663666
return [x for x in self.select(type=type, fragment=fragment, name=name, limit=limit, page_size=page_size)]
664667

665-
def select(self, type=None, fragment=None, name=None, limit=None, page_size=1000): # noqa (type)
668+
def select(self, type=None, fragment=None, name=None, owner=None, limit=None, page_size=1000): # noqa (type)
666669
""" Query the database for managed objects and iterate over the
667670
results.
668671
@@ -680,7 +683,7 @@ def select(self, type=None, fragment=None, name=None, limit=None, page_size=1000
680683
:param page_size: Define the number of events which are read (and
681684
parsed in one chunk). This is a performance related setting.
682685
683-
:returns: Generator of ManagedObject instances
686+
:yield: ManagedObject instances
684687
"""
685688
query = None
686689
if name:
@@ -769,7 +772,7 @@ def select(self, type=None, name=None, limit=None, page_size=100): # noqa (type
769772
:param page_size: Define the number of events which are read (and
770773
parsed in one chunk). This is a performance related setting.
771774
772-
:returns: Generator of Device objects
775+
:yield: Device objects
773776
"""
774777
return super().select(type=type, fragment='c8y_IsDevice', name=name, limit=limit, page_size=page_size)
775778

@@ -828,7 +831,7 @@ def select(self, fragment=None, name=None, page_size=100): # noqa
828831
:param name: name string of the objects to select; no partial
829832
matching/patterns are supported
830833
:param page_size: number of objects to fetch per request
831-
:return: Generator of ManagedObject instances
834+
:yield: ManagedObject instances
832835
"""
833836
query = None
834837
if name:

0 commit comments

Comments
 (0)