-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy path__api_response.py
More file actions
101 lines (89 loc) · 3.9 KB
/
Copy path__api_response.py
File metadata and controls
101 lines (89 loc) · 3.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
"""
--------------------------------------------------------------------------------
------------------------- Mist API Python CLI Session --------------------------
Written by: Thomas Munzer (tmunzer@juniper.net)
Github : https://github.com/tmunzer/mistapi_python
This package is licensed under the MIT License.
--------------------------------------------------------------------------------
This module manages API responses
"""
from requests import Response
from requests.structures import CaseInsensitiveDict
from mistapi.__logger import console, logger
class APIResponse:
"""
Class used to pass API Responses
"""
def __init__(
self, response: Response | None, url: str, proxy_error: bool = False
) -> None:
"""
PARAMS
-----------
response : requests.Response
Response from the request
url : str
URL of the HTTP Request
"""
self.raw_data: str = ""
self.data: dict | list = {}
self.url: str = url
self.next: str | None = None
self.headers: CaseInsensitiveDict[str] | None = None
self.status_code: int | None = None
self.proxy_error: bool = proxy_error
if response is not None:
self.headers = response.headers
self.status_code = response.status_code
logger.info(
f"apiresponse:__init__:response status code: {response.status_code}"
)
console.debug(f"Response Status Code: {response.status_code}")
try:
self.raw_data = response.text
self.data = response.json()
self._check_next()
logger.debug("apiresponse:__init__:HTTP response processed")
if self.status_code >= 400 or (
isinstance(self.data, dict) and self.data.get("error")
):
logger.error(f"apiresponse:__init__:response = {response}")
console.debug(f"Response: {self.data}")
except Exception as err:
logger.error(
f"apiresponse:__init__:unable to process HTTP Response: \r\n{err}"
)
def _check_next(self) -> None:
logger.debug("apiresponse:_check_next")
if isinstance(self.data, dict) and "next" in self.data:
self.next = self.data["next"]
logger.debug(f"apiresponse:_check_next:set next to {self.next}")
elif self.headers:
total_str = self.headers.get("X-Page-Total")
limit_str = self.headers.get("X-Page-Limit")
page_str = self.headers.get("X-Page-Page")
if total_str and limit_str and page_str:
try:
total = int(total_str)
limit = int(limit_str)
page = int(page_str)
if limit * page < total:
uri = f"/api/{self.url.split('/api/')[1]}"
if "page=" not in uri:
separator = "&" if "?" in uri else "?"
self.next = f"{uri}{separator}page={page + 1}"
else:
self.next = uri.replace(f"page={page}", f"page={page + 1}")
logger.debug(f"apiresponse:_check_next:set next to {self.next}")
except ValueError:
logger.error(
f"apiresponse:_check_next:"
f"unable to convert total({total_str})/limit({limit_str})/page({page_str}) to int"
)
logger.error(
"apiresponse:_check_next:Exception occurred", exc_info=True
)
console.error(
f"Unable to convert total "
f"({total_str})/limit({limit_str})/page({page_str}) to int"
)