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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: neris_api_client
3
- Version: 1.3.5
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
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "neris_api_client"
7
- version = "1.3.5"
7
+ version = "1.4.0"
8
8
  authors = [
9
9
  { name="Ben Coleman", email="ben.coleman@ul.org" },
10
10
  { name="Tommy Messbauer", email="thomas.messbauer@ul.org" },
@@ -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(f"{config.client_id}:{config.client_secret}".encode("utf-8")).decode("utf-8")
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("Bad grant type. Must be \"password\" or \"client_credentials\"")
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={'Content-Type': 'application/x-www-form-urlencoded'},
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={"Authorization": f"Basic {self.client_creds}", "Content-Type": "application/x-www-form-urlencoded"},
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={"Authorization": f"Basic {self.client_creds}", "Content-Type": "application/x-www-form-urlencoded"},
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={'Content-Type': 'application/x-www-form-urlencoded'},
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
- res = getattr(self._session, method)(f"{self.config.base_url}{path}", json=data, params=params)
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(self, sub_user: str | UUID, nuid_role: str | UUID, nuid_entity_set: str | UUID) -> Dict[str, Any]:
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={"sub_user": str(sub_user), "nuid_role": str(nuid_role), "nuid_entity_set": str(nuid_entity_set)},
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={ "title": title })
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={ "title": title })
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")