neris-api-client 1.3.5__tar.gz → 1.4.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {neris_api_client-1.3.5/src/neris_api_client.egg-info → neris_api_client-1.4.0}/PKG-INFO +1 -1
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/pyproject.toml +1 -1
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/src/neris_api_client/client.py +88 -17
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/src/neris_api_client/models.py +1380 -916
- {neris_api_client-1.3.5 → neris_api_client-1.4.0/src/neris_api_client.egg-info}/PKG-INFO +1 -1
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/LICENSE +0 -0
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/README.md +0 -0
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/setup.cfg +0 -0
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/src/neris_api_client/__init__.py +0 -0
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/src/neris_api_client/config.py +0 -0
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/src/neris_api_client.egg-info/SOURCES.txt +0 -0
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/src/neris_api_client.egg-info/dependency_links.txt +0 -0
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/src/neris_api_client.egg-info/requires.txt +0 -0
- {neris_api_client-1.3.5 → neris_api_client-1.4.0}/src/neris_api_client.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neris_api_client
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0
|
|
4
4
|
Summary: NERIS API Client
|
|
5
5
|
Author-email: Ben Coleman <ben.coleman@ul.org>, Tommy Messbauer <thomas.messbauer@ul.org>, Joseph Pagani <joseph.pagani@ul.org>
|
|
6
6
|
Project-URL: Homepage, https://github.com/ulfsri/neris-api-client
|
|
@@ -2,7 +2,7 @@ import base64
|
|
|
2
2
|
from http import HTTPStatus
|
|
3
3
|
import json
|
|
4
4
|
from uuid import UUID
|
|
5
|
-
from typing import List, Optional, Dict, Any
|
|
5
|
+
from typing import List, Optional, Dict, Any, Literal
|
|
6
6
|
from datetime import datetime, timedelta
|
|
7
7
|
|
|
8
8
|
import requests
|
|
@@ -13,13 +13,15 @@ from .config import Config, GrantType, TokenSet
|
|
|
13
13
|
from .models import (
|
|
14
14
|
IncidentPayload,
|
|
15
15
|
PatchUnitPayload,
|
|
16
|
+
CreateUnitPayload,
|
|
16
17
|
CreateUserPayload,
|
|
17
18
|
DepartmentPayload,
|
|
18
19
|
UpdateUserPayload,
|
|
20
|
+
PatchIncidentAction,
|
|
19
21
|
PatchStationPayload,
|
|
22
|
+
CreateStationPayload,
|
|
20
23
|
PatchDepartmentPayload,
|
|
21
24
|
CreateDepartmentPayload,
|
|
22
|
-
PatchIncidentAction,
|
|
23
25
|
TypeIncidentStatusValue,
|
|
24
26
|
)
|
|
25
27
|
|
|
@@ -47,12 +49,14 @@ class _NerisApiClient:
|
|
|
47
49
|
case GrantType.CLIENT_CREDENTIALS:
|
|
48
50
|
assert config.client_id is not None
|
|
49
51
|
assert config.client_secret is not None
|
|
50
|
-
self.client_creds = base64.b64encode(
|
|
52
|
+
self.client_creds = base64.b64encode(
|
|
53
|
+
f"{config.client_id}:{config.client_secret}".encode("utf-8")
|
|
54
|
+
).decode("utf-8")
|
|
51
55
|
case GrantType.PASSWORD:
|
|
52
56
|
assert config.username is not None
|
|
53
57
|
assert config.password is not None
|
|
54
58
|
case _:
|
|
55
|
-
raise Exception(
|
|
59
|
+
raise Exception('Bad grant type. Must be "password" or "client_credentials"')
|
|
56
60
|
|
|
57
61
|
self.config = config
|
|
58
62
|
|
|
@@ -65,7 +69,7 @@ class _NerisApiClient:
|
|
|
65
69
|
case GrantType.PASSWORD:
|
|
66
70
|
res = self._session.post(
|
|
67
71
|
token_url,
|
|
68
|
-
headers={
|
|
72
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
69
73
|
data={
|
|
70
74
|
"grant_type": GrantType.PASSWORD,
|
|
71
75
|
"username": self.config.username,
|
|
@@ -76,7 +80,10 @@ class _NerisApiClient:
|
|
|
76
80
|
case GrantType.CLIENT_CREDENTIALS:
|
|
77
81
|
res = self._session.post(
|
|
78
82
|
token_url,
|
|
79
|
-
headers={
|
|
83
|
+
headers={
|
|
84
|
+
"Authorization": f"Basic {self.client_creds}",
|
|
85
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
86
|
+
},
|
|
80
87
|
data={"grant_type": GrantType.CLIENT_CREDENTIALS},
|
|
81
88
|
)
|
|
82
89
|
|
|
@@ -97,7 +104,10 @@ class _NerisApiClient:
|
|
|
97
104
|
res = self._session.post(
|
|
98
105
|
token_url,
|
|
99
106
|
# Basic auth required for NERIS refresh tokens
|
|
100
|
-
headers={
|
|
107
|
+
headers={
|
|
108
|
+
"Authorization": f"Basic {self.client_creds}",
|
|
109
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
110
|
+
},
|
|
101
111
|
data={
|
|
102
112
|
"grant_type": "refresh_token",
|
|
103
113
|
"refresh_token": self.tokens.refresh_token,
|
|
@@ -141,13 +151,13 @@ class _NerisApiClient:
|
|
|
141
151
|
|
|
142
152
|
res = self._session.post(
|
|
143
153
|
token_url,
|
|
144
|
-
headers={
|
|
154
|
+
headers={"Content-Type": "application/x-www-form-urlencoded"},
|
|
145
155
|
data={
|
|
146
156
|
"grant_type": got["challenge_name"],
|
|
147
157
|
"username": self.config.username,
|
|
148
158
|
"session": got["session"],
|
|
149
159
|
got["challenge_name"]: code,
|
|
150
|
-
}
|
|
160
|
+
},
|
|
151
161
|
)
|
|
152
162
|
|
|
153
163
|
def _call(
|
|
@@ -167,8 +177,9 @@ class _NerisApiClient:
|
|
|
167
177
|
if isinstance(data, dict):
|
|
168
178
|
data = model.model_validate(data).model_dump(mode="json", by_alias=True)
|
|
169
179
|
|
|
170
|
-
|
|
171
|
-
|
|
180
|
+
res = getattr(self._session, method)(
|
|
181
|
+
f"{self.config.base_url}{path}", json=data, params=params
|
|
182
|
+
)
|
|
172
183
|
|
|
173
184
|
if self.config.debug:
|
|
174
185
|
print(
|
|
@@ -180,12 +191,11 @@ class _NerisApiClient:
|
|
|
180
191
|
"headers": self._session.headers,
|
|
181
192
|
"params": params,
|
|
182
193
|
},
|
|
183
|
-
|
|
184
194
|
"response": {
|
|
185
195
|
"status_code": res.status_code,
|
|
186
196
|
"headers": res.headers,
|
|
187
197
|
"content": res.text,
|
|
188
|
-
}
|
|
198
|
+
},
|
|
189
199
|
},
|
|
190
200
|
indent=4,
|
|
191
201
|
cls=Encoder,
|
|
@@ -236,11 +246,17 @@ class NerisApiClient(_NerisApiClient):
|
|
|
236
246
|
def delete_user(self, sub: str | UUID) -> None:
|
|
237
247
|
self._call("delete", f"/user/{sub}")
|
|
238
248
|
|
|
239
|
-
def create_user_role_entity_set_attachment(
|
|
249
|
+
def create_user_role_entity_set_attachment(
|
|
250
|
+
self, sub_user: str | UUID, nuid_role: str | UUID, nuid_entity_set: str | UUID
|
|
251
|
+
) -> Dict[str, Any]:
|
|
240
252
|
return self._call(
|
|
241
253
|
"post",
|
|
242
254
|
"/auth/user_role_entity_set_attachment",
|
|
243
|
-
params={
|
|
255
|
+
params={
|
|
256
|
+
"sub_user": str(sub_user),
|
|
257
|
+
"nuid_role": str(nuid_role),
|
|
258
|
+
"nuid_entity_set": str(nuid_entity_set),
|
|
259
|
+
},
|
|
244
260
|
)
|
|
245
261
|
|
|
246
262
|
def create_user_entity_membership(self, sub: str | UUID, neris_id: str) -> None:
|
|
@@ -267,9 +283,54 @@ class NerisApiClient(_NerisApiClient):
|
|
|
267
283
|
"post", f"/incident/{neris_id}/validate", data=body, model=IncidentPayload
|
|
268
284
|
)
|
|
269
285
|
|
|
286
|
+
def list_incidents(
|
|
287
|
+
self,
|
|
288
|
+
*,
|
|
289
|
+
neris_id_entity: str | None = None,
|
|
290
|
+
incident_types: list[str] | None = None,
|
|
291
|
+
incident_types_set_operation: Literal["UNION", "INTERSECTION"] | None = None,
|
|
292
|
+
call_create_start: datetime | None = None,
|
|
293
|
+
call_create_end: datetime | None = None,
|
|
294
|
+
incident_number: str | None = None,
|
|
295
|
+
dispatch_incident_number: str | None = None,
|
|
296
|
+
status: list[Literal["APPROVED", "PENDING_APPROVAL", "REJECTED", "SUBMITTED"]] | None = None,
|
|
297
|
+
last_modified: str | None = None,
|
|
298
|
+
sort_by: Literal["call_create", "neris_id_entity", "incident_number", "dispatch_incident_number", "status", "last_modified"] | None = None,
|
|
299
|
+
sort_direction: Literal["ASCENDING", "DESCENDING"] | None = None,
|
|
300
|
+
page_size: int | None = None,
|
|
301
|
+
cursor: str | None = None,
|
|
302
|
+
) -> dict[str, Any]:
|
|
303
|
+
params = dict(
|
|
304
|
+
neris_id_entity=neris_id_entity,
|
|
305
|
+
incident_types=incident_types,
|
|
306
|
+
incident_types_set_operation=incident_types_set_operation,
|
|
307
|
+
call_create_start=call_create_start and call_create_start.isoformat(),
|
|
308
|
+
call_create_end=call_create_end and call_create_end.isoformat(),
|
|
309
|
+
incident_number=incident_number,
|
|
310
|
+
dispatch_incident_number=dispatch_incident_number,
|
|
311
|
+
status=status,
|
|
312
|
+
last_modified=last_modified,
|
|
313
|
+
sort_by=sort_by,
|
|
314
|
+
sort_direction=sort_direction,
|
|
315
|
+
page_size=page_size,
|
|
316
|
+
cursor=cursor,
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
# delete null params
|
|
320
|
+
for k in list(params.keys()):
|
|
321
|
+
if params[k] is None:
|
|
322
|
+
del params[k]
|
|
323
|
+
|
|
324
|
+
return self._call("get", "/incident", params=params)
|
|
325
|
+
|
|
270
326
|
def patch_entity(self, neris_id: str, body: str | Dict[str, Any]) -> Dict[str, Any]:
|
|
271
327
|
return self._call("patch", f"/entity/{neris_id}", data=body, model=PatchDepartmentPayload)
|
|
272
328
|
|
|
329
|
+
def create_station(self, neris_id_entity: str, body: str | Dict[str, Any]) -> Dict[str, Any]:
|
|
330
|
+
return self._call(
|
|
331
|
+
"post", f"/entity/{neris_id_entity}/station", data=body, model=CreateStationPayload
|
|
332
|
+
)
|
|
333
|
+
|
|
273
334
|
def patch_station(
|
|
274
335
|
self, neris_id_entity: str, neris_id_station: str, body: str | Dict[str, Any]
|
|
275
336
|
) -> Dict[str, Any]:
|
|
@@ -280,6 +341,16 @@ class NerisApiClient(_NerisApiClient):
|
|
|
280
341
|
model=PatchStationPayload,
|
|
281
342
|
)
|
|
282
343
|
|
|
344
|
+
def create_unit(
|
|
345
|
+
self, neris_id_entity: str, neris_id_station: str, body: str | Dict[str, Any]
|
|
346
|
+
) -> Dict[str, Any]:
|
|
347
|
+
return self._call(
|
|
348
|
+
"post",
|
|
349
|
+
f"/entity/{neris_id_entity}/station/{neris_id_station}",
|
|
350
|
+
data=body,
|
|
351
|
+
model=CreateUnitPayload,
|
|
352
|
+
)
|
|
353
|
+
|
|
283
354
|
def patch_unit(
|
|
284
355
|
self,
|
|
285
356
|
neris_id_entity: str,
|
|
@@ -314,10 +385,10 @@ class NerisApiClient(_NerisApiClient):
|
|
|
314
385
|
)
|
|
315
386
|
|
|
316
387
|
def create_api_integration(self, neris_id: str, title: str) -> Dict[str, Any]:
|
|
317
|
-
return self._call("post", f"/account/integration/{neris_id}", data={
|
|
388
|
+
return self._call("post", f"/account/integration/{neris_id}", data={"title": title})
|
|
318
389
|
|
|
319
390
|
def generate_api_secret(self, client_id: str, title: str) -> Dict[str, Any]:
|
|
320
|
-
return self._call("post", f"/account/credential/{client_id}", data={
|
|
391
|
+
return self._call("post", f"/account/credential/{client_id}", data={"title": title})
|
|
321
392
|
|
|
322
393
|
def list_integrations(self, neris_id: str) -> Dict[str, Any]:
|
|
323
394
|
return self._call("get", f"/account/integration/{neris_id}/list")
|