pangea-sdk 6.2.0b1__py3-none-any.whl → 6.2.0b2__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.
Files changed (54) hide show
  1. pangea/__init__.py +9 -1
  2. pangea/asyncio/__init__.py +1 -0
  3. pangea/asyncio/file_uploader.py +4 -2
  4. pangea/asyncio/request.py +51 -21
  5. pangea/asyncio/services/__init__.py +2 -0
  6. pangea/asyncio/services/ai_guard.py +91 -2
  7. pangea/asyncio/services/audit.py +14 -8
  8. pangea/asyncio/services/authn.py +33 -23
  9. pangea/asyncio/services/authz.py +6 -6
  10. pangea/asyncio/services/base.py +4 -0
  11. pangea/asyncio/services/file_scan.py +8 -2
  12. pangea/asyncio/services/intel.py +6 -2
  13. pangea/asyncio/services/prompt_guard.py +112 -2
  14. pangea/asyncio/services/redact.py +7 -3
  15. pangea/asyncio/services/sanitize.py +5 -1
  16. pangea/asyncio/services/share.py +5 -1
  17. pangea/asyncio/services/vault.py +19 -15
  18. pangea/audit_logger.py +3 -1
  19. pangea/deep_verify.py +13 -13
  20. pangea/deprecated.py +1 -1
  21. pangea/dump_audit.py +2 -3
  22. pangea/exceptions.py +8 -5
  23. pangea/file_uploader.py +4 -0
  24. pangea/request.py +58 -41
  25. pangea/response.py +15 -12
  26. pangea/services/__init__.py +2 -0
  27. pangea/services/ai_guard.py +497 -16
  28. pangea/services/audit/audit.py +15 -13
  29. pangea/services/audit/models.py +4 -0
  30. pangea/services/audit/signing.py +1 -1
  31. pangea/services/audit/util.py +10 -10
  32. pangea/services/authn/authn.py +33 -23
  33. pangea/services/authn/models.py +3 -0
  34. pangea/services/authz.py +10 -6
  35. pangea/services/base.py +5 -1
  36. pangea/services/embargo.py +6 -0
  37. pangea/services/file_scan.py +8 -2
  38. pangea/services/intel.py +4 -0
  39. pangea/services/management.py +8 -8
  40. pangea/services/prompt_guard.py +193 -2
  41. pangea/services/redact.py +7 -3
  42. pangea/services/sanitize.py +5 -1
  43. pangea/services/share/share.py +13 -7
  44. pangea/services/vault/models/asymmetric.py +4 -0
  45. pangea/services/vault/models/common.py +4 -0
  46. pangea/services/vault/models/symmetric.py +4 -0
  47. pangea/services/vault/vault.py +17 -19
  48. pangea/tools.py +13 -9
  49. pangea/utils.py +3 -5
  50. pangea/verify_audit.py +23 -27
  51. {pangea_sdk-6.2.0b1.dist-info → pangea_sdk-6.2.0b2.dist-info}/METADATA +6 -6
  52. pangea_sdk-6.2.0b2.dist-info/RECORD +62 -0
  53. {pangea_sdk-6.2.0b1.dist-info → pangea_sdk-6.2.0b2.dist-info}/WHEEL +1 -1
  54. pangea_sdk-6.2.0b1.dist-info/RECORD +0 -62
@@ -1,9 +1,13 @@
1
1
  from __future__ import annotations
2
2
 
3
- from typing import Any, Dict, Generic, List, Literal, Optional, TypeVar, overload
3
+ from collections.abc import Mapping
4
+ from typing import Annotated, Generic, Literal, Optional, Union, overload
5
+
6
+ from pydantic import BaseModel, ConfigDict, Field, RootModel
7
+ from typing_extensions import TypeVar
4
8
 
5
9
  from pangea.config import PangeaConfig
6
- from pangea.response import APIRequestModel, APIResponseModel, PangeaResponse, PangeaResponseResult
10
+ from pangea.response import APIRequestModel, APIResponseModel, PangeaDateTime, PangeaResponse, PangeaResponseResult
7
11
  from pangea.services.base import ServiceBase
8
12
 
9
13
  # This is named "prompt injection" in the API spec even though it is also used
@@ -24,14 +28,14 @@ class CodeDetectionOverride(APIRequestModel):
24
28
 
25
29
  class LanguageDetectionOverride(APIRequestModel):
26
30
  disabled: Optional[bool] = None
27
- allow: Optional[List[str]] = None
28
- block: Optional[List[str]] = None
29
- report: Optional[List[str]] = None
31
+ allow: Optional[list[str]] = None
32
+ block: Optional[list[str]] = None
33
+ report: Optional[list[str]] = None
30
34
 
31
35
 
32
36
  class TopicDetectionOverride(APIRequestModel):
33
37
  disabled: Optional[bool] = None
34
- block: Optional[List[str]] = None
38
+ block: Optional[list[str]] = None
35
39
 
36
40
 
37
41
  class PromptInjectionOverride(APIRequestModel):
@@ -179,7 +183,7 @@ class PromptInjectionResult(APIResponseModel):
179
183
  action: str
180
184
  """The action taken by this Detector"""
181
185
 
182
- analyzer_responses: List[AnalyzerResponse]
186
+ analyzer_responses: list[AnalyzerResponse]
183
187
  """Triggered prompt injection analyzers."""
184
188
 
185
189
 
@@ -192,20 +196,20 @@ class PiiEntity(APIResponseModel):
192
196
 
193
197
 
194
198
  class PiiEntityResult(APIResponseModel):
195
- entities: List[PiiEntity]
199
+ entities: list[PiiEntity]
196
200
  """Detected redaction rules."""
197
201
 
198
202
 
199
203
  class MaliciousEntity(APIResponseModel):
200
204
  type: str
201
205
  value: str
202
- action: str
206
+ action: Optional[str] = None
203
207
  start_pos: Optional[int] = None
204
- raw: Optional[Dict[str, Any]] = None
208
+ raw: Optional[dict[str, object]] = None
205
209
 
206
210
 
207
211
  class MaliciousEntityResult(APIResponseModel):
208
- entities: List[MaliciousEntity]
212
+ entities: list[MaliciousEntity]
209
213
  """Detected harmful items."""
210
214
 
211
215
 
@@ -215,11 +219,11 @@ class CustomEntity(APIResponseModel):
215
219
  action: str
216
220
  """The action taken on this Entity"""
217
221
  start_pos: Optional[int] = None
218
- raw: Optional[Dict[str, Any]] = None
222
+ raw: Optional[dict[str, object]] = None
219
223
 
220
224
 
221
225
  class CustomEntityResult(APIResponseModel):
222
- entities: List[CustomEntity]
226
+ entities: list[CustomEntity]
223
227
  """Detected redaction rules."""
224
228
 
225
229
 
@@ -233,7 +237,7 @@ class SecretsEntity(APIResponseModel):
233
237
 
234
238
 
235
239
  class SecretsEntityResult(APIResponseModel):
236
- entities: List[SecretsEntity]
240
+ entities: list[SecretsEntity]
237
241
  """Detected redaction rules."""
238
242
 
239
243
 
@@ -266,9 +270,9 @@ class TextGuardDetectors(APIResponseModel):
266
270
  prompt_injection: Optional[TextGuardDetector[PromptInjectionResult]] = None
267
271
  pii_entity: Optional[TextGuardDetector[PiiEntityResult]] = None
268
272
  malicious_entity: Optional[TextGuardDetector[MaliciousEntityResult]] = None
269
- custom_entity: Optional[TextGuardDetector[Any]] = None
273
+ custom_entity: Optional[TextGuardDetector[object]] = None
270
274
  secrets_detection: Optional[TextGuardDetector[SecretsEntityResult]] = None
271
- profanity_and_toxicity: Optional[TextGuardDetector[Any]] = None
275
+ profanity_and_toxicity: Optional[TextGuardDetector[object]] = None
272
276
  language_detection: Optional[TextGuardDetector[LanguageDetectionResult]] = None
273
277
  topic_detection: Optional[TextGuardDetector[TopicDetectionResult]] = None
274
278
  code_detection: Optional[TextGuardDetector[CodeDetectionResult]] = None
@@ -297,6 +301,405 @@ class TextGuardResult(PangeaResponseResult, Generic[_T]):
297
301
  """
298
302
 
299
303
 
304
+ class Areas(BaseModel):
305
+ model_config = ConfigDict(extra="forbid")
306
+
307
+ text_guard: bool
308
+
309
+
310
+ class AuditDataActivityConfig(BaseModel):
311
+ model_config = ConfigDict(extra="forbid")
312
+
313
+ enabled: bool
314
+ audit_service_config_id: str
315
+ areas: Areas
316
+
317
+
318
+ class PromptGuard(BaseModel):
319
+ model_config = ConfigDict(extra="forbid")
320
+
321
+ enabled: Optional[bool] = None
322
+ config_id: Optional[str] = None
323
+ confidence_threshold: Optional[float] = None
324
+
325
+
326
+ class IpIntel(BaseModel):
327
+ model_config = ConfigDict(extra="forbid")
328
+
329
+ enabled: Optional[bool] = None
330
+ config_id: Optional[str] = None
331
+ reputation_provider: Optional[str] = None
332
+ risk_threshold: Optional[float] = None
333
+
334
+
335
+ class UserIntel(BaseModel):
336
+ model_config = ConfigDict(extra="forbid")
337
+
338
+ enabled: Optional[bool] = None
339
+ config_id: Optional[str] = None
340
+ breach_provider: Optional[str] = None
341
+
342
+
343
+ class UrlIntel(BaseModel):
344
+ model_config = ConfigDict(extra="forbid")
345
+
346
+ enabled: Optional[bool] = None
347
+ config_id: Optional[str] = None
348
+ reputation_provider: Optional[str] = None
349
+ risk_threshold: Optional[float] = None
350
+
351
+
352
+ class DomainIntel(BaseModel):
353
+ model_config = ConfigDict(extra="forbid")
354
+
355
+ enabled: Optional[bool] = None
356
+ config_id: Optional[str] = None
357
+ reputation_provider: Optional[str] = None
358
+ risk_threshold: Optional[float] = None
359
+
360
+
361
+ class FileScan(BaseModel):
362
+ model_config = ConfigDict(extra="forbid")
363
+
364
+ enabled: Optional[bool] = None
365
+ config_id: Optional[str] = None
366
+ scan_provider: Optional[str] = None
367
+ risk_threshold: Optional[float] = None
368
+
369
+
370
+ class Redact(BaseModel):
371
+ model_config = ConfigDict(extra="forbid")
372
+
373
+ enabled: Optional[bool] = None
374
+ config_id: Optional[str] = None
375
+
376
+
377
+ class Vault(BaseModel):
378
+ model_config = ConfigDict(extra="forbid")
379
+
380
+ config_id: Optional[str] = None
381
+
382
+
383
+ class Lingua(BaseModel):
384
+ model_config = ConfigDict(extra="forbid")
385
+
386
+ enabled: Optional[bool] = None
387
+
388
+
389
+ class Code(BaseModel):
390
+ model_config = ConfigDict(extra="forbid")
391
+
392
+ enabled: Optional[bool] = None
393
+
394
+
395
+ class ConnectionsConfig(BaseModel):
396
+ model_config = ConfigDict(extra="forbid")
397
+
398
+ prompt_guard: Optional[PromptGuard] = None
399
+ ip_intel: Optional[IpIntel] = None
400
+ user_intel: Optional[UserIntel] = None
401
+ url_intel: Optional[UrlIntel] = None
402
+ domain_intel: Optional[DomainIntel] = None
403
+ file_scan: Optional[FileScan] = None
404
+ redact: Optional[Redact] = None
405
+ vault: Optional[Vault] = None
406
+ lingua: Optional[Lingua] = None
407
+ code: Optional[Code] = None
408
+
409
+
410
+ class PartialMasking(BaseModel):
411
+ masking_type: Optional[Literal["unmask", "mask"]] = "unmask"
412
+ unmasked_from_left: Annotated[Optional[int], Field(ge=0)] = None
413
+ unmasked_from_right: Annotated[Optional[int], Field(ge=0)] = None
414
+ masked_from_left: Annotated[Optional[int], Field(ge=0)] = None
415
+ masked_from_right: Annotated[Optional[int], Field(ge=0)] = None
416
+ chars_to_ignore: Optional[list[CharsToIgnoreItem]] = None
417
+ masking_char: Annotated[Optional[str], Field(max_length=1, min_length=1)] = "*"
418
+
419
+
420
+ class RuleRedactionConfig1(BaseModel):
421
+ model_config = ConfigDict(extra="forbid")
422
+
423
+ redaction_type: Literal[
424
+ "mask",
425
+ "partial_masking",
426
+ "replacement",
427
+ "hash",
428
+ "detect_only",
429
+ "fpe",
430
+ "mask",
431
+ "detect_only",
432
+ ]
433
+ redaction_value: Optional[str] = None
434
+ partial_masking: Optional[PartialMasking] = None
435
+ hash: Optional[Hash] = None
436
+ fpe_alphabet: Optional[
437
+ Literal[
438
+ "numeric",
439
+ "alphalower",
440
+ "alphaupper",
441
+ "alpha",
442
+ "alphanumericlower",
443
+ "alphanumericupper",
444
+ "alphanumeric",
445
+ ]
446
+ ] = None
447
+
448
+
449
+ class PartialMasking1(BaseModel):
450
+ masking_type: Optional[Literal["unmask", "mask"]] = "unmask"
451
+ unmasked_from_left: Annotated[Optional[int], Field(ge=0)] = None
452
+ unmasked_from_right: Annotated[Optional[int], Field(ge=0)] = None
453
+ masked_from_left: Annotated[Optional[int], Field(ge=0)] = None
454
+ masked_from_right: Annotated[Optional[int], Field(ge=0)] = None
455
+ chars_to_ignore: Optional[list[CharsToIgnoreItem]] = None
456
+ masking_char: Annotated[Optional[str], Field(max_length=1, min_length=1)] = "*"
457
+
458
+
459
+ class RuleRedactionConfig2(BaseModel):
460
+ model_config = ConfigDict(extra="forbid")
461
+
462
+ redaction_type: Literal["replacement"]
463
+ redaction_value: str
464
+ partial_masking: Optional[PartialMasking1] = None
465
+ hash: Optional[Hash] = None
466
+ fpe_alphabet: Optional[
467
+ Literal[
468
+ "numeric",
469
+ "alphalower",
470
+ "alphaupper",
471
+ "alpha",
472
+ "alphanumericlower",
473
+ "alphanumericupper",
474
+ "alphanumeric",
475
+ ]
476
+ ] = None
477
+
478
+
479
+ class PartialMasking2(BaseModel):
480
+ masking_type: Optional[Literal["unmask", "mask"]] = "unmask"
481
+ unmasked_from_left: Annotated[Optional[int], Field(ge=0)] = None
482
+ unmasked_from_right: Annotated[Optional[int], Field(ge=0)] = None
483
+ masked_from_left: Annotated[Optional[int], Field(ge=0)] = None
484
+ masked_from_right: Annotated[Optional[int], Field(ge=0)] = None
485
+ chars_to_ignore: Optional[list[CharsToIgnoreItem]] = None
486
+ masking_char: Annotated[Optional[str], Field(max_length=1, min_length=1)] = "*"
487
+
488
+
489
+ class RuleRedactionConfig3(BaseModel):
490
+ model_config = ConfigDict(extra="forbid")
491
+
492
+ redaction_type: Literal["partial_masking"]
493
+ redaction_value: str
494
+ partial_masking: PartialMasking2
495
+ hash: Optional[Hash] = None
496
+ fpe_alphabet: Optional[
497
+ Literal[
498
+ "numeric",
499
+ "alphalower",
500
+ "alphaupper",
501
+ "alpha",
502
+ "alphanumericlower",
503
+ "alphanumericupper",
504
+ "alphanumeric",
505
+ ]
506
+ ] = None
507
+
508
+
509
+ class PartialMasking3(BaseModel):
510
+ masking_type: Optional[Literal["unmask", "mask"]] = "unmask"
511
+ unmasked_from_left: Annotated[Optional[int], Field(ge=0)] = None
512
+ unmasked_from_right: Annotated[Optional[int], Field(ge=0)] = None
513
+ masked_from_left: Annotated[Optional[int], Field(ge=0)] = None
514
+ masked_from_right: Annotated[Optional[int], Field(ge=0)] = None
515
+ chars_to_ignore: Optional[list[CharsToIgnoreItem]] = None
516
+ masking_char: Annotated[Optional[str], Field(max_length=1, min_length=1)] = "*"
517
+
518
+
519
+ class RuleRedactionConfig4(BaseModel):
520
+ model_config = ConfigDict(extra="forbid")
521
+
522
+ redaction_type: Literal["hash"]
523
+ redaction_value: str
524
+ partial_masking: PartialMasking3
525
+ hash: Optional[Hash] = None
526
+ fpe_alphabet: Optional[
527
+ Literal[
528
+ "numeric",
529
+ "alphalower",
530
+ "alphaupper",
531
+ "alpha",
532
+ "alphanumericlower",
533
+ "alphanumericupper",
534
+ "alphanumeric",
535
+ ]
536
+ ] = None
537
+
538
+
539
+ class CharsToIgnoreItem(RootModel[str]):
540
+ root: Annotated[str, Field(max_length=1, min_length=1)]
541
+
542
+
543
+ class PartialMasking4(BaseModel):
544
+ masking_type: Optional[Literal["unmask", "mask"]] = "unmask"
545
+ unmasked_from_left: Annotated[Optional[int], Field(ge=0)] = None
546
+ unmasked_from_right: Annotated[Optional[int], Field(ge=0)] = None
547
+ masked_from_left: Annotated[Optional[int], Field(ge=0)] = None
548
+ masked_from_right: Annotated[Optional[int], Field(ge=0)] = None
549
+ chars_to_ignore: Optional[list[CharsToIgnoreItem]] = None
550
+ masking_char: Annotated[Optional[str], Field(max_length=1, min_length=1)] = "*"
551
+
552
+
553
+ class Hash(BaseModel):
554
+ hash_type: Literal["md5", "sha256"]
555
+ """The type of hashing algorithm"""
556
+
557
+
558
+ class RuleRedactionConfig5(BaseModel):
559
+ model_config = ConfigDict(extra="forbid")
560
+
561
+ redaction_type: Literal["fpe"]
562
+ redaction_value: str
563
+ partial_masking: PartialMasking4
564
+ hash: Optional[Hash] = None
565
+ fpe_alphabet: Optional[
566
+ Literal[
567
+ "numeric",
568
+ "alphalower",
569
+ "alphaupper",
570
+ "alpha",
571
+ "alphanumericlower",
572
+ "alphanumericupper",
573
+ "alphanumeric",
574
+ ]
575
+ ] = None
576
+
577
+
578
+ class Rule(BaseModel):
579
+ model_config = ConfigDict(extra="forbid")
580
+ redact_rule_id: str
581
+ redaction: Union[
582
+ RuleRedactionConfig1,
583
+ RuleRedactionConfig2,
584
+ RuleRedactionConfig3,
585
+ RuleRedactionConfig4,
586
+ RuleRedactionConfig5,
587
+ ]
588
+ block: Optional[bool] = None
589
+ disabled: Optional[bool] = None
590
+ reputation_check: Optional[bool] = None
591
+ transform_if_malicious: Optional[bool] = None
592
+
593
+
594
+ class Settings(BaseModel):
595
+ rules: Optional[list[Rule]] = None
596
+
597
+
598
+ class DetectorSetting(BaseModel):
599
+ model_config = ConfigDict(extra="forbid")
600
+
601
+ detector_name: str
602
+ state: Literal["disabled", "enabled"]
603
+ settings: Settings
604
+
605
+
606
+ class RedactConnectorSettings(BaseModel):
607
+ fpe_tweak_vault_secret_id: Optional[str] = None
608
+
609
+
610
+ class ConnectorSettings(BaseModel):
611
+ model_config = ConfigDict(extra="forbid")
612
+
613
+ redact: Optional[RedactConnectorSettings] = None
614
+
615
+
616
+ class RecipeConfig(BaseModel):
617
+ model_config = ConfigDict(extra="forbid")
618
+
619
+ name: str
620
+ description: str
621
+ version: Optional[str] = ""
622
+ detectors: Optional[list[DetectorSetting]] = None
623
+ """Setting for Detectors"""
624
+ connector_settings: Optional[ConnectorSettings] = None
625
+
626
+
627
+ class ServiceConfig(PangeaResponseResult):
628
+ id: Optional[str] = None
629
+ name: Optional[str] = None
630
+ audit_data_activity: Optional[AuditDataActivityConfig] = None
631
+ connections: Optional[ConnectionsConfig] = None
632
+ recipes: Optional[dict[str, RecipeConfig]] = None
633
+
634
+
635
+ class ServiceConfigFilter(BaseModel):
636
+ model_config = ConfigDict(extra="forbid")
637
+
638
+ id: Optional[str] = None
639
+ """
640
+ Only records where id equals this value.
641
+ """
642
+ id__contains: Optional[list[str]] = None
643
+ """
644
+ Only records where id includes each substring.
645
+ """
646
+ id__in: Optional[list[str]] = None
647
+ """
648
+ Only records where id equals one of the provided substrings.
649
+ """
650
+ created_at: Optional[PangeaDateTime] = None
651
+ """
652
+ Only records where created_at equals this value.
653
+ """
654
+ created_at__gt: Optional[PangeaDateTime] = None
655
+ """
656
+ Only records where created_at is greater than this value.
657
+ """
658
+ created_at__gte: Optional[PangeaDateTime] = None
659
+ """
660
+ Only records where created_at is greater than or equal to this value.
661
+ """
662
+ created_at__lt: Optional[PangeaDateTime] = None
663
+ """
664
+ Only records where created_at is less than this value.
665
+ """
666
+ created_at__lte: Optional[PangeaDateTime] = None
667
+ """
668
+ Only records where created_at is less than or equal to this value.
669
+ """
670
+ updated_at: Optional[PangeaDateTime] = None
671
+ """
672
+ Only records where updated_at equals this value.
673
+ """
674
+ updated_at__gt: Optional[PangeaDateTime] = None
675
+ """
676
+ Only records where updated_at is greater than this value.
677
+ """
678
+ updated_at__gte: Optional[PangeaDateTime] = None
679
+ """
680
+ Only records where updated_at is greater than or equal to this value.
681
+ """
682
+ updated_at__lt: Optional[PangeaDateTime] = None
683
+ """
684
+ Only records where updated_at is less than this value.
685
+ """
686
+ updated_at__lte: Optional[PangeaDateTime] = None
687
+ """
688
+ Only records where updated_at is less than or equal to this value.
689
+ """
690
+
691
+
692
+ class ServiceConfigsPage(PangeaResponseResult):
693
+ count: Optional[int] = None
694
+ """The total number of service configs matched by the list request."""
695
+ last: Optional[str] = None
696
+ """
697
+ Used to fetch the next page of the current listing when provided in a
698
+ repeated request's last parameter.
699
+ """
700
+ items: Optional[list[ServiceConfig]] = None
701
+
702
+
300
703
  class AIGuard(ServiceBase):
301
704
  """AI Guard service client.
302
705
 
@@ -455,3 +858,81 @@ class AIGuard(ServiceBase):
455
858
  "log_fields": log_fields,
456
859
  },
457
860
  )
861
+
862
+ def get_service_config(self, id: str) -> PangeaResponse[ServiceConfig]:
863
+ """
864
+ OperationId: ai_guard_post_v1beta_config
865
+ """
866
+ return self.request.post("v1beta/config", data={"id": id}, result_class=ServiceConfig)
867
+
868
+ def create_service_config(
869
+ self,
870
+ name: str,
871
+ *,
872
+ id: str | None = None,
873
+ audit_data_activity: AuditDataActivityConfig | None = None,
874
+ connections: ConnectionsConfig | None = None,
875
+ recipes: Mapping[str, RecipeConfig] | None = None,
876
+ ) -> PangeaResponse[ServiceConfig]:
877
+ """
878
+ OperationId: ai_guard_post_v1beta_config_create
879
+ """
880
+ return self.request.post(
881
+ "v1beta/config/create",
882
+ data={
883
+ "name": name,
884
+ "id": id,
885
+ "audit_data_activity": audit_data_activity,
886
+ "connections": connections,
887
+ "recipes": recipes,
888
+ },
889
+ result_class=ServiceConfig,
890
+ )
891
+
892
+ def update_service_config(
893
+ self,
894
+ id: str,
895
+ name: str,
896
+ *,
897
+ audit_data_activity: AuditDataActivityConfig | None = None,
898
+ connections: ConnectionsConfig | None = None,
899
+ recipes: Mapping[str, RecipeConfig] | None = None,
900
+ ) -> PangeaResponse[ServiceConfig]:
901
+ """
902
+ OperationId: ai_guard_post_v1beta_config_update
903
+ """
904
+ return self.request.post(
905
+ "v1beta/config/update",
906
+ data={
907
+ "id": id,
908
+ "name": name,
909
+ "audit_data_activity": audit_data_activity,
910
+ "connections": connections,
911
+ "recipes": recipes,
912
+ },
913
+ result_class=ServiceConfig,
914
+ )
915
+
916
+ def delete_service_config(self, id: str) -> PangeaResponse[ServiceConfig]:
917
+ """
918
+ OperationId: ai_guard_post_v1beta_config_delete
919
+ """
920
+ return self.request.post("v1beta/config/delete", data={"id": id}, result_class=ServiceConfig)
921
+
922
+ def list_service_configs(
923
+ self,
924
+ *,
925
+ filter: ServiceConfigFilter | None = None,
926
+ last: str | None = None,
927
+ order: Literal["asc", "desc"] | None = None,
928
+ order_by: Literal["id", "created_at", "updated_at"] | None = None,
929
+ size: int | None = None,
930
+ ) -> PangeaResponse[ServiceConfigsPage]:
931
+ """
932
+ OperationId: ai_guard_post_v1beta_config_list
933
+ """
934
+ return self.request.post(
935
+ "v1beta/config/list",
936
+ data={"filter": filter, "last": last, "order": order, "order_by": order_by, "size": size},
937
+ result_class=ServiceConfigsPage,
938
+ )
@@ -1,9 +1,14 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
3
7
  from __future__ import annotations
4
8
 
5
9
  import datetime
6
10
  import json
11
+ from collections.abc import Mapping
7
12
  from typing import Any, Dict, Iterable, List, Optional, Sequence, Set, Tuple, Union, cast, overload
8
13
 
9
14
  from pydantic import TypeAdapter
@@ -63,7 +68,7 @@ from pangea.utils import canonicalize_nested_json
63
68
 
64
69
  class AuditBase:
65
70
  def __init__(
66
- self, private_key_file: str = "", public_key_info: dict[str, str] = {}, tenant_id: str | None = None
71
+ self, private_key_file: str = "", public_key_info: Mapping[str, str] = {}, tenant_id: str | None = None
67
72
  ) -> None:
68
73
  self.pub_roots: Dict[int, PublishedRoot] = {}
69
74
  self.buffer_data: Optional[str] = None
@@ -98,7 +103,7 @@ class AuditBase:
98
103
  return input # type: ignore[return-value]
99
104
 
100
105
  def _process_log(self, event: dict, sign_local: bool) -> LogEvent:
101
- if event.get("tenant_id", None) is None and self.tenant_id:
106
+ if event.get("tenant_id") is None and self.tenant_id:
102
107
  event["tenant_id"] = self.tenant_id
103
108
 
104
109
  event = {k: v for k, v in event.items() if v is not None}
@@ -229,10 +234,7 @@ class AuditBase:
229
234
  tree_sizes.add(result.root.size)
230
235
  tree_sizes.difference_update(self.pub_roots.keys())
231
236
 
232
- if tree_sizes:
233
- arweave_roots = get_arweave_published_roots(result.root.tree_name, tree_sizes)
234
- else:
235
- arweave_roots = {}
237
+ arweave_roots = get_arweave_published_roots(result.root.tree_name, tree_sizes) if tree_sizes else {}
236
238
 
237
239
  return tree_sizes, arweave_roots
238
240
 
@@ -393,7 +395,7 @@ class Audit(ServiceBase, AuditBase):
393
395
  token: str,
394
396
  config: PangeaConfig | None = None,
395
397
  private_key_file: str = "",
396
- public_key_info: dict[str, str] = {},
398
+ public_key_info: Mapping[str, str] = {},
397
399
  tenant_id: str | None = None,
398
400
  logger_name: str = "pangea",
399
401
  config_id: str | None = None,
@@ -465,7 +467,7 @@ class Audit(ServiceBase, AuditBase):
465
467
  A PangeaResponse where the hash of event data and optional verbose
466
468
  results are returned in the response.result field.
467
469
  Available response fields can be found in our
468
- [API documentation](https://pangea.cloud/docs/api/audit#/v1/log).
470
+ [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
469
471
 
470
472
  Examples:
471
473
  log_response = audit.log(
@@ -513,7 +515,7 @@ class Audit(ServiceBase, AuditBase):
513
515
  Returns:
514
516
  A PangeaResponse where the hash of event data and optional verbose
515
517
  results are returned in the response.result field.
516
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log).
518
+ Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/log-post).
517
519
 
518
520
  Examples:
519
521
  response = audit.log_event({"message": "hello world"}, verbose=True)
@@ -551,7 +553,7 @@ class Audit(ServiceBase, AuditBase):
551
553
  Returns:
552
554
  A PangeaResponse where the hash of event data and optional verbose
553
555
  results are returned in the response.result field.
554
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v2/log).
556
+ Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v2/log-post).
555
557
 
556
558
  Examples:
557
559
  log_response = audit.log_bulk(
@@ -592,7 +594,7 @@ class Audit(ServiceBase, AuditBase):
592
594
  Returns:
593
595
  A PangeaResponse where the hash of event data and optional verbose
594
596
  results are returned in the response.result field.
595
- Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v2/log_async).
597
+ Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v2/log_async-post).
596
598
 
597
599
  Examples:
598
600
  log_response = audit.log_bulk_async(
@@ -667,8 +669,8 @@ class Audit(ServiceBase, AuditBase):
667
669
 
668
670
  Returns:
669
671
  A PangeaResponse[SearchOutput] where the first page of matched events is returned in the
670
- response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/search).
671
- Pagination can be found in the [search results endpoint](https://pangea.cloud/docs/api/audit#/v1/results).
672
+ response.result field. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/audit#/v1/search-post).
673
+ Pagination can be found in the [search results endpoint](https://pangea.cloud/docs/api/audit#/v1/results-post).
672
674
 
673
675
  Examples:
674
676
  response = audit.search(
@@ -1,5 +1,9 @@
1
1
  # Copyright 2022 Pangea Cyber Corporation
2
2
  # Author: Pangea Cyber Corporation
3
+
4
+ # TODO: Modernize.
5
+ # ruff: noqa: UP006, UP035
6
+
3
7
  from __future__ import annotations
4
8
 
5
9
  import datetime