|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
5 | 5 | import json as json_lib |
| 6 | +import logging |
6 | 7 | from typing import Union, Dict, BinaryIO |
7 | 8 |
|
8 | 9 | import collections |
@@ -75,6 +76,8 @@ class CumulocityRestApi: |
75 | 76 | CONTENT_MANAGED_OBJECT = 'application/vnd.com.nsn.cumulocity.managedobject+json' |
76 | 77 | CONTENT_MEASUREMENT_COLLECTION = 'application/vnd.com.nsn.cumulocity.measurementcollection+json' |
77 | 78 |
|
| 79 | + log = logging.getLogger(__name__ + '.CumulocityRestApi') |
| 80 | + |
78 | 81 | def __init__(self, base_url: str, tenant_id: str, username: str = None, password: str = None, |
79 | 82 | auth: AuthBase = None, application_key: str = None, processing_mode: str = None): |
80 | 83 | """Build a CumulocityRestApi instance. |
@@ -204,6 +207,8 @@ def get(self, resource: str, params: dict = None, accept: str = None, ordered: b |
204 | 207 | """ |
205 | 208 | additional_headers = self._prepare_headers(accept=accept) |
206 | 209 | r = self.session.get(self.base_url + resource, params=params, headers=additional_headers) |
| 210 | + if self.log.isEnabledFor(logging.DEBUG): |
| 211 | + self.log.debug(f'GET {resource} {self._format_params(params)} {r.status_code}') |
207 | 212 | if r.status_code == 401: |
208 | 213 | raise UnauthorizedError(self.METHOD_GET, self.base_url + resource) |
209 | 214 | if r.status_code == 403: |
@@ -237,6 +242,8 @@ def get_file(self, resource: str, params: dict = None) -> bytes: |
237 | 242 | (only 200 is accepted). |
238 | 243 | """ |
239 | 244 | r = self.session.get(self.base_url + resource, params=params) |
| 245 | + if self.log.isEnabledFor(logging.DEBUG): |
| 246 | + self.log.debug(f'GET {resource} {self._format_params(params)} {r.status_code}') |
240 | 247 | if r.status_code == 401: |
241 | 248 | raise UnauthorizedError(self.METHOD_GET, self.base_url + resource) |
242 | 249 | if r.status_code == 403: |
@@ -273,6 +280,8 @@ def post(self, resource: str, json: dict, accept: str = None, content_type: str |
273 | 280 | assert isinstance(json, dict) |
274 | 281 | additional_headers = self._prepare_headers(accept=accept, content_type=content_type) |
275 | 282 | r = self.session.post(self.base_url + resource, json=json, headers=additional_headers) |
| 283 | + if self.log.isEnabledFor(logging.DEBUG): |
| 284 | + self.log.debug(f"POST {resource} '{json_lib.dumps(json)}' {r.status_code}") |
276 | 285 | if r.status_code == 401: |
277 | 286 | raise UnauthorizedError(self.METHOD_POST, self.base_url + resource, message=r.json()['message']) |
278 | 287 | if r.status_code == 403: |
@@ -324,6 +333,9 @@ def perform_post(open_file): |
324 | 333 | else: |
325 | 334 | r = perform_post(file) |
326 | 335 |
|
| 336 | + if self.log.isEnabledFor(logging.DEBUG): |
| 337 | + self.log.debug(f"POST {resource} '{file}' {self._format_params(object)} {r.status_code}") |
| 338 | + |
327 | 339 | if r.status_code == 401: |
328 | 340 | raise UnauthorizedError(self.METHOD_POST, self.base_url + resource) |
329 | 341 | if r.status_code == 403: |
@@ -362,6 +374,8 @@ def put(self, resource: str, json: dict, params: dict = None, |
362 | 374 | assert isinstance(json, dict) |
363 | 375 | additional_headers = self._prepare_headers(accept=accept, content_type=content_type) |
364 | 376 | r = self.session.put(self.base_url + resource, json=json, params=params, headers=additional_headers) |
| 377 | + if self.log.isEnabledFor(logging.DEBUG): |
| 378 | + self.log.debug(f"PUT {resource} {self._format_params(params)} '{json_lib.dumps(json)}' {r.status_code}") |
365 | 379 | if r.status_code == 401: |
366 | 380 | raise UnauthorizedError(self.METHOD_PUT, self.base_url + resource) |
367 | 381 | if r.status_code == 403: |
@@ -413,6 +427,8 @@ def read_file_data(f): |
413 | 427 | additional_headers = self._prepare_headers(accept=accept, content_type=content_type) |
414 | 428 | data = read_file_data(file) |
415 | 429 | r = self.session.put(self.base_url + resource, data=data, headers=additional_headers) |
| 430 | + if self.log.isEnabledFor(logging.DEBUG): |
| 431 | + self.log.debug(f"PUT {resource} '{file}' {r.status_code}") |
416 | 432 | if r.status_code == 401: |
417 | 433 | raise UnauthorizedError(self.METHOD_PUT, self.base_url + resource) |
418 | 434 | if r.status_code == 403: |
@@ -448,6 +464,8 @@ def delete(self, resource: str, json: dict = None, params: dict = None): |
448 | 464 | if json: |
449 | 465 | assert isinstance(json, dict) |
450 | 466 | r = self.session.delete(self.base_url + resource, json=json, params=params, headers={'Accept': None}) |
| 467 | + if self.log.isEnabledFor(logging.DEBUG): |
| 468 | + self.log.debug(f"DELETE {resource} {self._format_params(params)} '{json_lib.dumps(json)}' {r.status_code}") |
451 | 469 | if r.status_code == 401: |
452 | 470 | raise UnauthorizedError(self.METHOD_DELETE, self.base_url + resource) |
453 | 471 | if r.status_code == 403: |
@@ -496,6 +514,14 @@ def format_value(value): |
496 | 514 |
|
497 | 515 | return {cls._format_header_key(key): format_value(value) for key, value in kwargs.items() if value is not None} |
498 | 516 |
|
| 517 | + @staticmethod |
| 518 | + def _format_params(params): |
| 519 | + if not params: |
| 520 | + return '-' |
| 521 | + return ', '.join( |
| 522 | + [f"{k}={v}" for k, v in params.items()] |
| 523 | + ) |
| 524 | + |
499 | 525 | @staticmethod |
500 | 526 | def _format_header_key(key: str) -> str: |
501 | 527 | """Format a snake_case argument name into a proper Header-Name. |
|
0 commit comments