pangea-sdk 6.2.0b2__py3-none-any.whl → 6.3.0__py3-none-any.whl

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.
@@ -59,7 +59,6 @@ from pangea.services.vault.models.common import (
59
59
  JWTVerifyResult,
60
60
  ListRequest,
61
61
  ListResult,
62
- Metadata,
63
62
  PangeaToken,
64
63
  PangeaTokenRotateRequest,
65
64
  RequestManualRotationState,
@@ -319,7 +318,7 @@ class VaultAsync(ServiceBaseAsync):
319
318
  *,
320
319
  name: str | None = None,
321
320
  folder: str | None = None,
322
- metadata: Metadata | None = None,
321
+ metadata: Mapping[str, str] | None = None,
323
322
  tags: Tags | None = None,
324
323
  disabled_at: str | None = None,
325
324
  enabled: bool | None = None,
@@ -395,7 +394,7 @@ class VaultAsync(ServiceBaseAsync):
395
394
  result_class: type[TResult] = SecretStoreResult, # type: ignore[assignment]
396
395
  name: str | None = None,
397
396
  folder: str | None = None,
398
- metadata: Metadata | None = None,
397
+ metadata: Mapping[str, str] | None = None,
399
398
  tags: Tags | None = None,
400
399
  disabled_at: datetime.datetime | None = None,
401
400
  **kwargs: Any,
@@ -420,22 +419,22 @@ class VaultAsync(ServiceBaseAsync):
420
419
  *,
421
420
  name: str | None = None,
422
421
  folder: str | None = None,
423
- metadata: Metadata | None = None,
422
+ metadata: Mapping[str, str] | None = None,
424
423
  tags: Tags | None = None,
425
424
  disabled_at: datetime.datetime | None = None,
426
425
  ) -> PangeaResponse[Secret]:
427
426
  """
428
427
  Store secret
429
428
 
430
- Store a secret.
429
+ Store a secret as a Vault item.
431
430
 
432
431
  Args:
433
- secret: The secret value.
434
- name: The name of this item.
435
- folder: The folder where this item is stored.
436
- metadata: User-provided metadata.
437
- tags: A list of user-defined tags.
438
- disabled_at: Timestamp indicating when the item will be disabled.
432
+ secret: Secret value
433
+ name: Name of the item
434
+ folder: Folder where the item is stored
435
+ metadata: Metadata provided by the user
436
+ tags: List of user-defined tags
437
+ disabled_at: Timestamp indicating when the item will be disabled
439
438
 
440
439
  Raises:
441
440
  PangeaAPIException: If an API Error happens
@@ -461,25 +460,38 @@ class VaultAsync(ServiceBaseAsync):
461
460
  *,
462
461
  name: str | None = None,
463
462
  folder: str | None = None,
464
- metadata: Metadata | None = None,
463
+ metadata: Mapping[str, str] | None = None,
465
464
  tags: Tags | None = None,
466
465
  disabled_at: datetime.datetime | None = None,
467
466
  rotation_frequency: str | None = None,
468
- rotation_state: RotationState | None = None,
467
+ rotation_state: Literal["deactivated", "destroyed", "inherited"] | None = None,
469
468
  rotation_grace_period: str | None = None,
470
469
  ) -> PangeaResponse[PangeaToken]:
471
470
  """
472
471
  Store secret
473
472
 
474
- Store a Pangea token.
473
+ Store a Pangea token as a Vault item.
475
474
 
476
475
  Args:
477
- token: The Pangea token value.
478
- name: The name of this item.
479
- folder: The folder where this item is stored.
480
- metadata: User-provided metadata.
481
- tags: A list of user-defined tags.
482
- disabled_at: Timestamp indicating when the item will be disabled.
476
+ token: Pangea token value
477
+ name: Name of the item
478
+ folder: Folder where the item is stored
479
+ metadata: Metadata provided by the user
480
+ tags: List of user-defined tags
481
+ disabled_at: Timestamp indicating when the item will be disabled
482
+ rotation_frequency: Time interval between item rotations, provided
483
+ as a positive number followed by a time unit: `secs`, `mins`, `hrs`,
484
+ `days`, `weeks`, `months`, or `years`. You can use abbreviations
485
+ like `1d`. Omit to inherit from the parent folder or default
486
+ settings. Set to `never` to disable rotation.
487
+ rotation_state: Target state for the previous version after
488
+ rotation. Set to `inherited` to inherit from the parent folder
489
+ or default settings.
490
+ rotation_grace_period: Grace period for the previous version,
491
+ provided as a positive number followed by a time unit: `secs`,
492
+ `mins`, `hrs`, `days`, `weeks`, `months`, or `years`. You can use
493
+ abbreviations like `1d`. Omit to inherit from the parent folder or
494
+ default settings.
483
495
 
484
496
  Raises:
485
497
  PangeaAPIException: If an API Error happens
@@ -510,7 +522,7 @@ class VaultAsync(ServiceBaseAsync):
510
522
  *,
511
523
  name: str | None = None,
512
524
  folder: str | None = None,
513
- metadata: Metadata | None = None,
525
+ metadata: Mapping[str, str] | None = None,
514
526
  tags: Tags | None = None,
515
527
  disabled_at: datetime.datetime | None = None,
516
528
  rotation_frequency: str | None = None,
@@ -672,7 +684,7 @@ class VaultAsync(ServiceBaseAsync):
672
684
  algorithm: AsymmetricKeySigningAlgorithm,
673
685
  name: str | None = None,
674
686
  folder: str | None = None,
675
- metadata: Metadata | None = None,
687
+ metadata: Mapping[str, str] | None = None,
676
688
  tags: Tags | None = None,
677
689
  rotation_frequency: str | None = None,
678
690
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -718,7 +730,7 @@ class VaultAsync(ServiceBaseAsync):
718
730
  algorithm: AsymmetricKeyEncryptionAlgorithm,
719
731
  name: str | None = None,
720
732
  folder: str | None = None,
721
- metadata: Metadata | None = None,
733
+ metadata: Mapping[str, str] | None = None,
722
734
  tags: Tags | None = None,
723
735
  rotation_frequency: str | None = None,
724
736
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -764,7 +776,7 @@ class VaultAsync(ServiceBaseAsync):
764
776
  algorithm: AsymmetricKeyJwtAlgorithm,
765
777
  name: str | None = None,
766
778
  folder: str | None = None,
767
- metadata: Metadata | None = None,
779
+ metadata: Mapping[str, str] | None = None,
768
780
  tags: Tags | None = None,
769
781
  rotation_frequency: str | None = None,
770
782
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -810,7 +822,7 @@ class VaultAsync(ServiceBaseAsync):
810
822
  algorithm: AsymmetricKeyPkiAlgorithm,
811
823
  name: str | None = None,
812
824
  folder: str | None = None,
813
- metadata: Metadata | None = None,
825
+ metadata: Mapping[str, str] | None = None,
814
826
  tags: Tags | None = None,
815
827
  rotation_frequency: str | None = None,
816
828
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -856,7 +868,7 @@ class VaultAsync(ServiceBaseAsync):
856
868
  algorithm: AsymmetricKeyAlgorithm,
857
869
  name: str | None = None,
858
870
  folder: str | None = None,
859
- metadata: Metadata | None = None,
871
+ metadata: Mapping[str, str] | None = None,
860
872
  tags: Tags | None = None,
861
873
  rotation_frequency: str | None = None,
862
874
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -902,7 +914,7 @@ class VaultAsync(ServiceBaseAsync):
902
914
  algorithm: SymmetricKeyEncryptionAlgorithm,
903
915
  name: str | None = None,
904
916
  folder: str | None = None,
905
- metadata: Metadata | None = None,
917
+ metadata: Mapping[str, str] | None = None,
906
918
  tags: Tags | None = None,
907
919
  rotation_frequency: str | None = None,
908
920
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -948,7 +960,7 @@ class VaultAsync(ServiceBaseAsync):
948
960
  algorithm: SymmetricKeyJwtAlgorithm,
949
961
  name: str | None = None,
950
962
  folder: str | None = None,
951
- metadata: Metadata | None = None,
963
+ metadata: Mapping[str, str] | None = None,
952
964
  tags: Tags | None = None,
953
965
  rotation_frequency: str | None = None,
954
966
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -994,7 +1006,7 @@ class VaultAsync(ServiceBaseAsync):
994
1006
  algorithm: SymmetricKeyFpeAlgorithm,
995
1007
  name: str | None = None,
996
1008
  folder: str | None = None,
997
- metadata: Metadata | None = None,
1009
+ metadata: Mapping[str, str] | None = None,
998
1010
  tags: Tags | None = None,
999
1011
  rotation_frequency: str | None = None,
1000
1012
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1040,7 +1052,7 @@ class VaultAsync(ServiceBaseAsync):
1040
1052
  algorithm: SymmetricKeyAlgorithm,
1041
1053
  name: str | None = None,
1042
1054
  folder: str | None = None,
1043
- metadata: Metadata | None = None,
1055
+ metadata: Mapping[str, str] | None = None,
1044
1056
  tags: Tags | None = None,
1045
1057
  rotation_frequency: str | None = None,
1046
1058
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1085,7 +1097,7 @@ class VaultAsync(ServiceBaseAsync):
1085
1097
  algorithm: AsymmetricKeyAlgorithm | SymmetricKeyAlgorithm,
1086
1098
  name: str | None = None,
1087
1099
  folder: str | None = None,
1088
- metadata: Metadata | None = None,
1100
+ metadata: Mapping[str, str] | None = None,
1089
1101
  tags: Tags | None = None,
1090
1102
  rotation_frequency: str | None = None,
1091
1103
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1151,7 +1163,7 @@ class VaultAsync(ServiceBaseAsync):
1151
1163
  private_key: str,
1152
1164
  name: str | None = None,
1153
1165
  folder: str | None = None,
1154
- metadata: Metadata | None = None,
1166
+ metadata: Mapping[str, str] | None = None,
1155
1167
  tags: Tags | None = None,
1156
1168
  rotation_frequency: str | None = None,
1157
1169
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1201,7 +1213,7 @@ class VaultAsync(ServiceBaseAsync):
1201
1213
  private_key: str,
1202
1214
  name: str | None = None,
1203
1215
  folder: str | None = None,
1204
- metadata: Metadata | None = None,
1216
+ metadata: Mapping[str, str] | None = None,
1205
1217
  tags: Tags | None = None,
1206
1218
  rotation_frequency: str | None = None,
1207
1219
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1251,7 +1263,7 @@ class VaultAsync(ServiceBaseAsync):
1251
1263
  private_key: str,
1252
1264
  name: str | None = None,
1253
1265
  folder: str | None = None,
1254
- metadata: Metadata | None = None,
1266
+ metadata: Mapping[str, str] | None = None,
1255
1267
  tags: Tags | None = None,
1256
1268
  rotation_frequency: str | None = None,
1257
1269
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1301,7 +1313,7 @@ class VaultAsync(ServiceBaseAsync):
1301
1313
  private_key: str,
1302
1314
  name: str | None = None,
1303
1315
  folder: str | None = None,
1304
- metadata: Metadata | None = None,
1316
+ metadata: Mapping[str, str] | None = None,
1305
1317
  tags: Tags | None = None,
1306
1318
  rotation_frequency: str | None = None,
1307
1319
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1350,7 +1362,7 @@ class VaultAsync(ServiceBaseAsync):
1350
1362
  key: str,
1351
1363
  name: str | None = None,
1352
1364
  folder: str | None = None,
1353
- metadata: Metadata | None = None,
1365
+ metadata: Mapping[str, str] | None = None,
1354
1366
  tags: Tags | None = None,
1355
1367
  rotation_frequency: str | None = None,
1356
1368
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1398,7 +1410,7 @@ class VaultAsync(ServiceBaseAsync):
1398
1410
  key: str,
1399
1411
  name: str | None = None,
1400
1412
  folder: str | None = None,
1401
- metadata: Metadata | None = None,
1413
+ metadata: Mapping[str, str] | None = None,
1402
1414
  tags: Tags | None = None,
1403
1415
  rotation_frequency: str | None = None,
1404
1416
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1446,7 +1458,7 @@ class VaultAsync(ServiceBaseAsync):
1446
1458
  key: str,
1447
1459
  name: str | None = None,
1448
1460
  folder: str | None = None,
1449
- metadata: Metadata | None = None,
1461
+ metadata: Mapping[str, str] | None = None,
1450
1462
  tags: Tags | None = None,
1451
1463
  rotation_frequency: str | None = None,
1452
1464
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1503,7 +1515,7 @@ class VaultAsync(ServiceBaseAsync):
1503
1515
  key: str | None = None,
1504
1516
  name: str | None = None,
1505
1517
  folder: str | None = None,
1506
- metadata: Metadata | None = None,
1518
+ metadata: Mapping[str, str] | None = None,
1507
1519
  tags: Tags | None = None,
1508
1520
  rotation_frequency: str | None = None,
1509
1521
  rotation_state: RequestRotationState | None = RequestRotationState.INHERITED,
@@ -1941,7 +1953,7 @@ class VaultAsync(ServiceBaseAsync):
1941
1953
  name: str,
1942
1954
  folder: str,
1943
1955
  *,
1944
- metadata: Metadata | None = None,
1956
+ metadata: Mapping[str, str] | None = None,
1945
1957
  tags: Tags | None = None,
1946
1958
  rotation_frequency: str | None = None,
1947
1959
  rotation_state: RequestRotationState = RequestRotationState.INHERITED,
pangea/request.py CHANGED
@@ -11,14 +11,14 @@ import json
11
11
  import logging
12
12
  import time
13
13
  from collections.abc import Iterable, Mapping
14
- from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, Union, cast, overload
14
+ from typing import TYPE_CHECKING, Any, Dict, List, Optional, Tuple, Type, Union, cast
15
15
 
16
16
  import requests
17
- from pydantic import BaseModel, TypeAdapter
17
+ from pydantic import BaseModel
18
18
  from pydantic_core import to_jsonable_python
19
19
  from requests.adapters import HTTPAdapter, Retry
20
20
  from requests_toolbelt import MultipartDecoder # type: ignore[import-untyped]
21
- from typing_extensions import Literal, TypeAlias, TypeVar, override
21
+ from typing_extensions import TypeAlias, TypeVar, override
22
22
  from yarl import URL
23
23
 
24
24
  import pangea
@@ -43,6 +43,8 @@ _FileSpecTuple4: TypeAlias = tuple[_FileName, _FileContent, _FileContentType, _F
43
43
  _FileSpec: TypeAlias = Union[_FileContent, _FileSpecTuple2, _FileSpecTuple3, _FileSpecTuple4]
44
44
  _Files: TypeAlias = Union[Mapping[str, _FileSpec], Iterable[tuple[str, _FileSpec]]]
45
45
 
46
+ _HeadersUpdateMapping: TypeAlias = Mapping[str, str]
47
+
46
48
 
47
49
  class MultipartResponse:
48
50
  pangea_json: Dict[str, str]
@@ -66,7 +68,7 @@ class PangeaRequestBase:
66
68
  self._queued_retry_enabled = config.queued_retry_enabled
67
69
 
68
70
  # Custom headers
69
- self._extra_headers: Dict = {}
71
+ self._extra_headers: _HeadersUpdateMapping = {}
70
72
  self._user_agent = ""
71
73
 
72
74
  self.set_custom_user_agent(config.custom_user_agent)
@@ -81,18 +83,17 @@ class PangeaRequestBase:
81
83
 
82
84
  return self._session
83
85
 
84
- def set_extra_headers(self, headers: dict):
86
+ def set_extra_headers(self, headers: _HeadersUpdateMapping):
85
87
  """Sets any additional headers in the request.
86
88
 
87
89
  Args:
88
- headers (dict): key-value pair containing extra headers to et
90
+ headers: key-value pairs containing extra headers to set
89
91
 
90
92
  Example:
91
93
  set_extra_headers({ "My-Header" : "foobar" })
92
94
  """
93
95
 
94
- if isinstance(headers, dict):
95
- self._extra_headers = headers
96
+ self._extra_headers = headers
96
97
 
97
98
  def set_custom_user_agent(self, user_agent: Optional[str]):
98
99
  self.config.custom_user_agent = user_agent
@@ -129,17 +130,14 @@ class PangeaRequestBase:
129
130
  url = URL(self.config.base_url_template.format(SERVICE_NAME=self.service))
130
131
  return str(url / path)
131
132
 
132
- def _headers(self) -> dict:
133
- headers = {
134
- "User-Agent": self._user_agent,
133
+ def _headers(self) -> dict[str, str]:
134
+ return {
135
+ **self._extra_headers,
135
136
  "Authorization": f"Bearer {self.token}",
136
137
  "Content-Type": "application/json",
138
+ "User-Agent": self._user_agent,
137
139
  }
138
140
 
139
- # We want to ignore previous headers if user tried to set them, so we will overwrite them.
140
- self._extra_headers.update(headers)
141
- return self._extra_headers
142
-
143
141
  def _get_filename_from_content_disposition(self, content_disposition: str) -> Optional[str]:
144
142
  filename_parts = content_disposition.split("name=")
145
143
  if len(filename_parts) > 1:
@@ -222,24 +220,6 @@ class PangeaRequest(PangeaRequestBase):
222
220
  def __del__(self) -> None:
223
221
  self.session.close()
224
222
 
225
- def delete(self, endpoint: str) -> None:
226
- """
227
- Makes a DELETE call to a Pangea endpoint.
228
-
229
- Args:
230
- endpoint: The Pangea API endpoint.
231
- """
232
-
233
- url = self._url(endpoint)
234
-
235
- self.logger.debug(
236
- json.dumps({"service": self.service, "action": "delete", "url": url}, default=default_encoder)
237
- )
238
-
239
- requests_response = self._http_delete(url, headers=self._headers())
240
- self._check_http_errors(requests_response)
241
-
242
- @overload
243
223
  def post(
244
224
  self,
245
225
  endpoint: str,
@@ -248,62 +228,18 @@ class PangeaRequest(PangeaRequestBase):
248
228
  files: Optional[list[Tuple]] = None,
249
229
  poll_result: bool = True,
250
230
  url: Optional[str] = None,
251
- *,
252
- pangea_response: Literal[True] = True,
253
231
  ) -> PangeaResponse[TResult]:
254
- """
255
- Makes the POST call to a Pangea Service endpoint.
232
+ """Makes the POST call to a Pangea Service endpoint.
256
233
 
257
234
  Args:
258
- endpoint: The Pangea Service API endpoint.
259
- data: The POST body payload object
235
+ endpoint(str): The Pangea Service API endpoint.
236
+ data(dict): The POST body payload object
260
237
 
261
238
  Returns:
262
239
  PangeaResponse which contains the response in its entirety and
263
240
  various properties to retrieve individual fields
264
241
  """
265
242
 
266
- @overload
267
- def post(
268
- self,
269
- endpoint: str,
270
- result_class: Type[TResult],
271
- data: str | BaseModel | Mapping[str, Any] | None = None,
272
- files: Optional[list[Tuple]] = None,
273
- poll_result: bool = True,
274
- url: Optional[str] = None,
275
- *,
276
- pangea_response: Literal[False],
277
- ) -> TResult:
278
- """
279
- Makes the POST call to a Pangea Service endpoint.
280
-
281
- Args:
282
- endpoint: The Pangea Service API endpoint.
283
- data: The POST body payload object
284
- """
285
-
286
- def post(
287
- self,
288
- endpoint: str,
289
- result_class: Type[TResult],
290
- data: str | BaseModel | Mapping[str, Any] | None = None,
291
- files: Optional[list[Tuple]] = None,
292
- poll_result: bool = True,
293
- url: Optional[str] = None,
294
- *,
295
- pangea_response: bool = True,
296
- ) -> PangeaResponse[TResult] | TResult:
297
- """
298
- Makes a POST call to a Pangea Service endpoint.
299
-
300
- Args:
301
- endpoint: The Pangea Service API endpoint.
302
- data: The POST body payload object
303
- pangea_response: Whether or not the response body follows Pangea's
304
- standard response schema
305
- """
306
-
307
243
  if isinstance(data, BaseModel):
308
244
  data = data.model_dump(exclude_none=True)
309
245
 
@@ -341,13 +277,9 @@ class PangeaRequest(PangeaRequestBase):
341
277
 
342
278
  self._check_http_errors(requests_response)
343
279
 
344
- if not pangea_response:
345
- type_adapter = TypeAdapter(result_class)
346
- return type_adapter.validate_python(requests_response.json())
347
-
348
280
  if "multipart/form-data" in requests_response.headers.get("content-type", ""):
349
281
  multipart_response = self._process_multipart_response(requests_response)
350
- pangea_response_obj: PangeaResponse = PangeaResponse(
282
+ pangea_response: PangeaResponse = PangeaResponse(
351
283
  requests_response,
352
284
  result_class=result_class,
353
285
  json=multipart_response.pangea_json,
@@ -360,14 +292,14 @@ class PangeaRequest(PangeaRequestBase):
360
292
  json.dumps({"service": self.service, "action": "post", "url": url, "response": json_resp})
361
293
  )
362
294
 
363
- pangea_response_obj = PangeaResponse(requests_response, result_class=result_class, json=json_resp)
295
+ pangea_response = PangeaResponse(requests_response, result_class=result_class, json=json_resp)
364
296
  except requests.exceptions.JSONDecodeError as e:
365
297
  raise pe.PangeaException(f"Failed to decode json response. {e}. Body: {requests_response.text}") from e
366
298
 
367
299
  if poll_result:
368
- pangea_response_obj = self._handle_queued_result(pangea_response_obj)
300
+ pangea_response = self._handle_queued_result(pangea_response)
369
301
 
370
- return self._check_response(pangea_response_obj)
302
+ return self._check_response(pangea_response)
371
303
 
372
304
  def _get_pangea_json(self, decoder: MultipartDecoder) -> Optional[Dict]:
373
305
  # Iterate through parts
@@ -410,18 +342,10 @@ class PangeaRequest(PangeaRequestBase):
410
342
  if resp.status_code == 503:
411
343
  raise pe.ServiceTemporarilyUnavailable(resp.json())
412
344
 
413
- def _http_delete(
414
- self,
415
- url: str,
416
- *,
417
- headers: Mapping[str, str | bytes | None] = {},
418
- ) -> requests.Response:
419
- return self.session.delete(url, headers=headers)
420
-
421
345
  def _http_post(
422
346
  self,
423
347
  url: str,
424
- headers: Mapping[str, str] = {},
348
+ headers: _HeadersUpdateMapping = {}, # noqa: B006
425
349
  data: str | dict[Any, Any] = {}, # noqa: B006
426
350
  files: _Files | None = None,
427
351
  multipart_post: bool = True,
@@ -462,98 +386,37 @@ class PangeaRequest(PangeaRequestBase):
462
386
 
463
387
  return response
464
388
 
465
- @overload
466
- def get(
467
- self,
468
- path: str,
469
- result_class: Type[TResult],
470
- check_response: bool = True,
471
- *,
472
- params: (
473
- Mapping[str | bytes | int | float, str | bytes | int | float | Iterable[str | bytes | int | float] | None]
474
- | None
475
- ) = None,
476
- pangea_response: Literal[True] = True,
477
- ) -> PangeaResponse[TResult]:
478
- """
479
- Makes the GET call to a Pangea Service endpoint.
389
+ def get(self, path: str, result_class: Type[TResult], check_response: bool = True) -> PangeaResponse[TResult]:
390
+ """Makes the GET call to a Pangea Service endpoint.
480
391
 
481
392
  Args:
482
- path: Additional URL path
483
- params: Dictionary of querystring data to attach to the request
393
+ endpoint(str): The Pangea Service API endpoint.
394
+ path(str): Additional URL path
484
395
 
485
396
  Returns:
486
397
  PangeaResponse which contains the response in its entirety and
487
398
  various properties to retrieve individual fields
488
399
  """
489
400
 
490
- @overload
491
- def get(
492
- self,
493
- path: str,
494
- result_class: Type[TResult],
495
- check_response: bool = True,
496
- *,
497
- params: (
498
- Mapping[str | bytes | int | float, str | bytes | int | float | Iterable[str | bytes | int | float] | None]
499
- | None
500
- ) = None,
501
- pangea_response: Literal[False] = False,
502
- ) -> TResult:
503
- """
504
- Makes the GET call to a Pangea Service endpoint.
505
-
506
- Args:
507
- path: Additional URL path
508
- params: Dictionary of querystring data to attach to the request
509
- """
510
-
511
- def get(
512
- self,
513
- path: str,
514
- result_class: Type[TResult],
515
- check_response: bool = True,
516
- *,
517
- params: (
518
- Mapping[str | bytes | int | float, str | bytes | int | float | Iterable[str | bytes | int | float] | None]
519
- | None
520
- ) = None,
521
- pangea_response: bool = True,
522
- ) -> PangeaResponse[TResult] | TResult:
523
- """
524
- Makes the GET call to a Pangea Service endpoint.
525
-
526
- Args:
527
- path: Additional URL path
528
- params: Dictionary of querystring data to attach to the request
529
- pangea_response: Whether or not the response body follows Pangea's
530
- standard response schema
531
- """
532
-
533
401
  url = self._url(path)
534
402
  self.logger.debug(json.dumps({"service": self.service, "action": "get", "url": url}))
535
- requests_response = self.session.get(url, params=params, headers=self._headers())
403
+ requests_response = self.session.get(url, headers=self._headers())
536
404
  self._check_http_errors(requests_response)
537
-
538
- if not pangea_response:
539
- type_adapter = TypeAdapter(result_class)
540
- return type_adapter.validate_python(requests_response.json())
541
-
542
- pangea_response_obj: PangeaResponse = PangeaResponse(
405
+ pangea_response: PangeaResponse = PangeaResponse(
543
406
  requests_response, result_class=result_class, json=requests_response.json()
544
407
  )
545
408
 
546
409
  self.logger.debug(
547
410
  json.dumps(
548
- {"service": self.service, "action": "get", "url": url, "response": pangea_response_obj.json},
411
+ {"service": self.service, "action": "get", "url": url, "response": pangea_response.json},
549
412
  default=default_encoder,
550
413
  )
551
414
  )
552
415
 
553
416
  if check_response is False:
554
- return pangea_response_obj
417
+ return pangea_response
555
418
 
556
- return self._check_response(pangea_response_obj)
419
+ return self._check_response(pangea_response)
557
420
 
558
421
  def download_file(self, url: str, filename: str | None = None) -> AttachedFile:
559
422
  """
pangea/response.py CHANGED
@@ -82,14 +82,12 @@ class TransferMethod(str, enum.Enum):
82
82
  PangeaDateTime = Annotated[datetime.datetime, PlainSerializer(format_datetime)]
83
83
 
84
84
 
85
- # API response should accept arbitrary fields to make them accept possible new parameters
86
- class APIResponseModel(BaseModel):
87
- model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
85
+ class APIRequestModel(BaseModel):
86
+ model_config = ConfigDict(extra="forbid")
88
87
 
89
88
 
90
- # API request models doesn't not allow arbitrary fields
91
- class APIRequestModel(BaseModel):
92
- model_config = ConfigDict(arbitrary_types_allowed=True, extra="allow")
89
+ class APIResponseModel(BaseModel):
90
+ model_config = ConfigDict(extra="allow")
93
91
 
94
92
 
95
93
  class PangeaResponseResult(APIResponseModel):
@@ -195,6 +193,8 @@ T = TypeVar("T", bound=PangeaResponseResult)
195
193
 
196
194
 
197
195
  class PangeaResponse(ResponseHeader, Generic[T]):
196
+ model_config = ConfigDict(arbitrary_types_allowed=True, extra="forbid")
197
+
198
198
  raw_result: Optional[Dict[str, Any]] = None
199
199
  raw_response: Optional[Union[requests.Response, aiohttp.ClientResponse]] = None
200
200
  result: Optional[T] = None
@@ -7,7 +7,6 @@ from .authz import AuthZ
7
7
  from .embargo import Embargo
8
8
  from .file_scan import FileScan
9
9
  from .intel import DomainIntel, FileIntel, IpIntel, UrlIntel, UserIntel
10
- from .management import Management
11
10
  from .prompt_guard import PromptGuard
12
11
  from .redact import Redact
13
12
  from .sanitize import Sanitize