pangea-sdk 3.8.0__py3-none-any.whl → 5.3.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. pangea/__init__.py +2 -1
  2. pangea/asyncio/__init__.py +1 -0
  3. pangea/asyncio/file_uploader.py +39 -0
  4. pangea/asyncio/request.py +46 -23
  5. pangea/asyncio/services/__init__.py +2 -0
  6. pangea/asyncio/services/audit.py +46 -20
  7. pangea/asyncio/services/authn.py +123 -61
  8. pangea/asyncio/services/authz.py +57 -31
  9. pangea/asyncio/services/base.py +21 -2
  10. pangea/asyncio/services/embargo.py +2 -2
  11. pangea/asyncio/services/file_scan.py +24 -9
  12. pangea/asyncio/services/intel.py +104 -30
  13. pangea/asyncio/services/redact.py +52 -3
  14. pangea/asyncio/services/sanitize.py +217 -0
  15. pangea/asyncio/services/share.py +733 -0
  16. pangea/asyncio/services/vault.py +1709 -766
  17. pangea/crypto/rsa.py +135 -0
  18. pangea/deep_verify.py +7 -1
  19. pangea/dump_audit.py +9 -8
  20. pangea/file_uploader.py +35 -0
  21. pangea/request.py +70 -49
  22. pangea/response.py +36 -17
  23. pangea/services/__init__.py +2 -0
  24. pangea/services/audit/audit.py +57 -29
  25. pangea/services/audit/models.py +12 -3
  26. pangea/services/audit/signing.py +6 -5
  27. pangea/services/audit/util.py +3 -3
  28. pangea/services/authn/authn.py +120 -66
  29. pangea/services/authn/models.py +167 -11
  30. pangea/services/authz.py +53 -30
  31. pangea/services/base.py +16 -2
  32. pangea/services/embargo.py +2 -2
  33. pangea/services/file_scan.py +32 -15
  34. pangea/services/intel.py +155 -30
  35. pangea/services/redact.py +132 -3
  36. pangea/services/sanitize.py +388 -0
  37. pangea/services/share/file_format.py +170 -0
  38. pangea/services/share/share.py +1440 -0
  39. pangea/services/vault/models/asymmetric.py +120 -18
  40. pangea/services/vault/models/common.py +439 -141
  41. pangea/services/vault/models/keys.py +94 -0
  42. pangea/services/vault/models/secret.py +27 -3
  43. pangea/services/vault/models/symmetric.py +68 -22
  44. pangea/services/vault/vault.py +1690 -766
  45. pangea/tools.py +6 -7
  46. pangea/utils.py +94 -33
  47. pangea/verify_audit.py +270 -83
  48. {pangea_sdk-3.8.0.dist-info → pangea_sdk-5.3.0.dist-info}/METADATA +21 -29
  49. pangea_sdk-5.3.0.dist-info/RECORD +56 -0
  50. {pangea_sdk-3.8.0.dist-info → pangea_sdk-5.3.0.dist-info}/WHEEL +1 -1
  51. pangea_sdk-3.8.0.dist-info/RECORD +0 -46
@@ -0,0 +1,1440 @@
1
+ # Copyright 2022 Pangea Cyber Corporation
2
+ # Author: Pangea Cyber Corporation
3
+ from __future__ import annotations
4
+
5
+ import enum
6
+ import io
7
+ from typing import Dict, List, NewType, Optional, Tuple, Union
8
+
9
+ from pangea.config import PangeaConfig
10
+ from pangea.response import APIRequestModel, PangeaResponse, PangeaResponseResult, TransferMethod
11
+ from pangea.services.base import ServiceBase
12
+ from pangea.services.share.file_format import FileFormat
13
+ from pangea.utils import get_file_size, get_file_upload_params
14
+
15
+ Metadata = NewType("Metadata", Dict[str, str])
16
+ Tags = NewType("Tags", List[str])
17
+
18
+
19
+ class ItemOrder(str, enum.Enum):
20
+ ASC = "asc"
21
+ DESC = "desc"
22
+
23
+ def __str__(self):
24
+ return str(self.value)
25
+
26
+ def __repr__(self):
27
+ return str(self.value)
28
+
29
+
30
+ class ArchiveFormat(str, enum.Enum):
31
+ TAR = "tar"
32
+ ZIP = "zip"
33
+
34
+ def __str__(self):
35
+ return str(self.value)
36
+
37
+ def __repr__(self):
38
+ return str(self.value)
39
+
40
+
41
+ class LinkType(str, enum.Enum):
42
+ UPLOAD = "upload"
43
+ DOWNLOAD = "download"
44
+ EDITOR = "editor"
45
+
46
+ def __str__(self):
47
+ return str(self.value)
48
+
49
+ def __repr__(self):
50
+ return str(self.value)
51
+
52
+
53
+ class AuthenticatorType(str, enum.Enum):
54
+ EMAIL_OTP = "email_otp"
55
+ PASSWORD = "password"
56
+ SMS_OTP = "sms_otp"
57
+ SOCIAL = "social"
58
+
59
+ def __str__(self):
60
+ return str(self.value)
61
+
62
+ def __repr__(self):
63
+ return str(self.value)
64
+
65
+
66
+ class ItemOrderBy(str, enum.Enum):
67
+ ID = "id"
68
+ CREATED_AT = "created_at"
69
+ NAME = "name"
70
+ PARENT_ID = "parent_id"
71
+ TYPE = "type"
72
+ UPDATED_AT = "updated_at"
73
+
74
+ def __str__(self):
75
+ return str(self.value)
76
+
77
+ def __repr__(self):
78
+ return str(self.value)
79
+
80
+
81
+ class ShareLinkOrderBy(str, enum.Enum):
82
+ ID = "id"
83
+ BUCKET_ID = "bucket_id"
84
+ TARGET = "target"
85
+ LINK_TYPE = "link_type"
86
+ ACCESS_COUNT = "access_count"
87
+ MAX_ACCESS_COUNT = "max_access_count"
88
+ CREATED_AT = "created_at"
89
+ EXPIRES_AT = "expires_at"
90
+ LAST_ACCESSED_AT = "last_accessed_at"
91
+ LINK = "link"
92
+
93
+ def __str__(self):
94
+ return str(self.value)
95
+
96
+ def __repr__(self):
97
+ return str(self.value)
98
+
99
+
100
+ class DeleteRequest(APIRequestModel):
101
+ id: Optional[str] = None
102
+ """The ID of the object to delete."""
103
+
104
+ force: Optional[bool] = None
105
+ """If true, delete a folder even if it's not empty. Deletes the contents of folder as well."""
106
+
107
+ bucket_id: Optional[str] = None
108
+ """The bucket to use, if not the default."""
109
+
110
+
111
+ class ItemData(PangeaResponseResult):
112
+ billable_size: Optional[int] = None
113
+ """The number of billable bytes (includes Metadata, Tags, etc.) for the object."""
114
+
115
+ created_at: str
116
+ """The date and time the object was created."""
117
+
118
+ id: str
119
+ """The ID of a stored object."""
120
+
121
+ md5: Optional[str] = None
122
+ """The MD5 hash of the file contents. Cannot be written to."""
123
+
124
+ metadata: Optional[Metadata] = None
125
+ """A set of string-based key/value pairs used to provide additional data about an object."""
126
+
127
+ metadata_protected: Optional[Metadata] = None
128
+ """Protected (read-only) metadata."""
129
+
130
+ sha256: Optional[str] = None
131
+ """The SHA256 hash of the file contents. Cannot be written to."""
132
+
133
+ sha512: Optional[str] = None
134
+ """The SHA512 hash of the file contents. Cannot be written to."""
135
+
136
+ size: Optional[int] = None
137
+ """The size of the object in bytes."""
138
+
139
+ tags: Optional[Tags] = None
140
+ """A list of user-defined tags."""
141
+
142
+ tags_protected: Optional[Tags] = None
143
+ """Protected (read-only) flags."""
144
+
145
+ type: str
146
+ """The type of the item (file or dir). Cannot be written to."""
147
+
148
+ updated_at: str
149
+ """The date and time the object was last updated."""
150
+
151
+ name: str
152
+ """The name of the object."""
153
+
154
+ folder: str
155
+ """The full path to the folder the object is stored in."""
156
+
157
+ parent_id: Optional[str] = None
158
+ """The parent ID (a folder). Blanks means the root folder."""
159
+
160
+ external_bucket_key: Optional[str] = None
161
+ """The key in the external bucket that contains this file."""
162
+
163
+ file_ttl: Optional[str] = None
164
+ """The explicit file TTL setting for this object."""
165
+
166
+ file_ttl_effective: Optional[str] = None
167
+ """
168
+ The effective file TTL setting for this object, either explicitly set or
169
+ inherited (see `file_ttl_from_id`.)
170
+ """
171
+
172
+ file_ttl_from_id: Optional[str] = None
173
+ """
174
+ The ID of the object the expiry / TTL is set from. Either a service
175
+ configuration, the object itself, or a parent folder.
176
+ """
177
+
178
+
179
+ class DeleteResult(PangeaResponseResult):
180
+ count: int
181
+ """Number of objects deleted."""
182
+
183
+
184
+ class FolderCreateRequest(APIRequestModel):
185
+ name: Optional[str] = None
186
+ """The name of an object."""
187
+
188
+ file_ttl: Optional[str] = None
189
+ """Duration until files within this folder are automatically deleted."""
190
+
191
+ metadata: Optional[Metadata] = None
192
+ """A set of string-based key/value pairs used to provide additional data about an object."""
193
+
194
+ root_folder: Optional[str] = None
195
+ """
196
+ The path of a root folder to restrict the operation to. Must resolve to
197
+ `root_id` if also set.
198
+ """
199
+
200
+ root_id: Optional[str] = None
201
+ """
202
+ The ID of a root folder to restrict the operation to. Must match
203
+ `root_folder` if also set.
204
+ """
205
+
206
+ parent_id: Optional[str] = None
207
+ """The ID of the parent folder. Must match `folder` if also set."""
208
+
209
+ folder: Optional[str] = None
210
+ """The folder to place the folder in. Must match `parent_id` if also set."""
211
+
212
+ tags: Optional[Tags] = None
213
+ """A list of user-defined tags"""
214
+
215
+ tenant_id: Optional[str] = None
216
+ """A tenant to associate with this request"""
217
+
218
+ bucket_id: Optional[str] = None
219
+ """The bucket to use, if not the default."""
220
+
221
+
222
+ class FolderCreateResult(PangeaResponseResult):
223
+ object: ItemData
224
+ """Information on the created folder."""
225
+
226
+
227
+ class GetRequest(APIRequestModel):
228
+ id: Optional[str] = None
229
+ """The ID of the object to retrieve."""
230
+
231
+ password: Optional[str] = None
232
+ """If the file was protected with a password, the password to decrypt with."""
233
+
234
+ transfer_method: Optional[TransferMethod] = None
235
+ """The requested transfer method for the file data."""
236
+
237
+ bucket_id: Optional[str] = None
238
+ """The bucket to use, if not the default."""
239
+
240
+ tenant_id: Optional[str] = None
241
+ """A tenant to associate with this request."""
242
+
243
+
244
+ class GetResult(PangeaResponseResult):
245
+ object: ItemData
246
+ """File information."""
247
+
248
+ dest_url: Optional[str] = None
249
+ """A URL where the file can be downloaded from. (transfer_method: dest-url)"""
250
+
251
+
252
+ class PutRequest(APIRequestModel):
253
+ transfer_method: Optional[TransferMethod] = None
254
+ """The transfer method used to upload the file data."""
255
+
256
+ bucket_id: Optional[str] = None
257
+ """The bucket to use, if not the default."""
258
+
259
+ size: Optional[int] = None
260
+ """The size (in bytes) of the file. If the upload doesn't match, the call will fail."""
261
+
262
+ crc32c: Optional[str] = None
263
+ """The hexadecimal-encoded CRC32C hash of the file data, which will be verified by the server if provided."""
264
+
265
+ sha256: Optional[str] = None
266
+ """The SHA256 hash of the file data, which will be verified by the server if provided."""
267
+
268
+ md5: Optional[str] = None
269
+ """The hexadecimal-encoded MD5 hash of the file data, which will be verified by the server if provided."""
270
+
271
+ name: Optional[str] = None
272
+ """The name of the object to store."""
273
+
274
+ format: Optional[FileFormat] = None
275
+ """The format of the file, which will be verified by the server if provided. Uploads not matching the supplied format will be rejected."""
276
+
277
+ metadata: Optional[Metadata] = None
278
+ """A set of string-based key/value pairs used to provide additional data about an object."""
279
+
280
+ mimetype: Optional[str] = None
281
+ """The MIME type of the file, which will be verified by the server if provided. Uploads not matching the supplied MIME type will be rejected."""
282
+
283
+ parent_id: Optional[str] = None
284
+ """The parent ID of the object (a folder). Leave blank to keep in the root folder."""
285
+
286
+ folder: Optional[str] = None
287
+ """The path to the parent folder. Leave blank for the root folder. Path must resolve to `parent_id` if also set."""
288
+
289
+ file_ttl: Optional[str] = None
290
+ """The TTL before expiry for the file."""
291
+
292
+ password: Optional[str] = None
293
+ """An optional password to protect the file with. Downloading the file will require this password."""
294
+
295
+ password_algorithm: Optional[str] = None
296
+ """An optional password algorithm to protect the file with. See symmetric vault password_algorithm."""
297
+
298
+ root_folder: Optional[str] = None
299
+ """
300
+ The path of a root folder to restrict the operation to. Must resolve to
301
+ `root_id` if also set.
302
+ """
303
+
304
+ root_id: Optional[str] = None
305
+ """
306
+ The ID of a root folder to restrict the operation to. Must match
307
+ `root_folder` if also set.
308
+ """
309
+
310
+ sha1: Optional[str] = None
311
+ """The hexadecimal-encoded SHA1 hash of the file data, which will be verified by the server if provided."""
312
+
313
+ sha512: Optional[str] = None
314
+ """The hexadecimal-encoded SHA512 hash of the file data, which will be verified by the server if provided."""
315
+
316
+ tags: Optional[Tags] = None
317
+ """A list of user-defined tags"""
318
+
319
+ tenant_id: Optional[str] = None
320
+ """A tenant to associate with this request"""
321
+
322
+
323
+ class PutResult(PangeaResponseResult):
324
+ object: ItemData
325
+
326
+
327
+ class UpdateRequest(APIRequestModel):
328
+ id: Optional[str]
329
+ """An identifier for the file to update."""
330
+
331
+ folder: Optional[str] = None
332
+ """
333
+ Set the parent (folder). Leave blank for the root folder. Path must resolve
334
+ to `parent_id` if also set.
335
+ """
336
+
337
+ add_metadata: Optional[Metadata] = None
338
+ """A list of Metadata key/values to set in the object. If a provided key exists, the value will be replaced."""
339
+
340
+ add_password: Optional[str] = None
341
+ """Protect the file with the supplied password."""
342
+
343
+ add_password_algorithm: Optional[str] = None
344
+ """The algorithm to use to password protect the file."""
345
+
346
+ add_tags: Optional[Tags] = None
347
+ """A list of Tags to add. It is not an error to provide a tag which already exists."""
348
+
349
+ file_ttl: Optional[str] = None
350
+ """Set the file TTL."""
351
+
352
+ name: Optional[str] = None
353
+ """Sets the object's Name."""
354
+
355
+ metadata: Optional[Metadata] = None
356
+ """Set the object's metadata."""
357
+
358
+ remove_metadata: Optional[Metadata] = None
359
+ """A list of metadata key/values to remove in the object. It is not an error for a provided key to not exist. If a provided key exists but doesn't match the provided value, it will not be removed."""
360
+
361
+ remove_password: Optional[str] = None
362
+ """Remove the supplied password from the file."""
363
+
364
+ remove_tags: Optional[Tags] = None
365
+ """A list of tags to remove. It is not an error to provide a tag which is not present."""
366
+
367
+ root_folder: Optional[str] = None
368
+ """
369
+ The path of a root folder to restrict the operation to. Must resolve to
370
+ `root_id` if also set.
371
+ """
372
+
373
+ root_id: Optional[str] = None
374
+ """
375
+ The ID of a root folder to restrict the operation to. Must match
376
+ `root_folder` if also set.
377
+ """
378
+
379
+ parent_id: Optional[str] = None
380
+ """Set the parent (folder) of the object. Can be an empty string for the root folder."""
381
+
382
+ tags: Optional[Tags] = None
383
+ """Set the object's tags."""
384
+
385
+ tenant_id: Optional[str] = None
386
+ """A tenant to associate with this request."""
387
+
388
+ updated_at: Optional[str] = None
389
+ """The date and time the object was last updated. If included, the update will fail if this doesn't match the date and time of the last update for the object."""
390
+
391
+ bucket_id: Optional[str] = None
392
+ """The bucket to use, if not the default."""
393
+
394
+
395
+ class UpdateResult(PangeaResponseResult):
396
+ object: ItemData
397
+
398
+
399
+ class FilterList(APIRequestModel):
400
+ created_at: Optional[str] = None
401
+ """Only records where created_at equals this value."""
402
+
403
+ created_at__gt: Optional[str] = None
404
+ """Only records where created_at is greater than this value."""
405
+
406
+ created_at__gte: Optional[str] = None
407
+ """Only records where created_at is greater than or equal to this value."""
408
+
409
+ created_at__lt: Optional[str] = None
410
+ """Only records where created_at is less than this value."""
411
+
412
+ created_at__lte: Optional[str] = None
413
+ """Only records where created_at is less than or equal to this value."""
414
+
415
+ folder: Optional[str] = None
416
+ """Only records where the object exists in the supplied parent folder path name."""
417
+
418
+ id: Optional[str] = None
419
+ """Only records where id equals this value."""
420
+
421
+ id__in: Optional[List[str]] = None
422
+ """Only records where id equals one of the provided substrings."""
423
+
424
+ name: Optional[str] = None
425
+ """Only records where name equals this value."""
426
+
427
+ name__contains: Optional[List[str]] = None
428
+ """Only records where name includes each substring."""
429
+
430
+ name__in: Optional[List[str]] = None
431
+ """Only records where name equals one of the provided substrings."""
432
+
433
+ parent_id: Optional[str] = None
434
+ """Only records where parent_id equals this value."""
435
+
436
+ parent_id__in: Optional[List[str]] = None
437
+ """Only records where parent_id equals one of the provided substrings."""
438
+
439
+ size: Optional[int] = None
440
+ """Only records where size equals this value."""
441
+
442
+ size__gt: Optional[int] = None
443
+ """Only records where size is greater than this value."""
444
+
445
+ size__gte: Optional[int] = None
446
+ """Only records where size is greater than or equal to this value."""
447
+
448
+ size__lt: Optional[int] = None
449
+ """Only records where size is less than to this value."""
450
+
451
+ size__lte: Optional[int] = None
452
+ """Only records where size is less than or equal to this value."""
453
+
454
+ tags: Optional[List[str]] = None
455
+ """A list of tags that all must be present."""
456
+
457
+ type: Optional[str] = None
458
+ """Only records where type equals this value."""
459
+
460
+ type__contains: Optional[List[str]] = None
461
+ """Only records where type includes each substring."""
462
+
463
+ type__in: Optional[List[str]] = None
464
+ """Only records where type equals one of the provided substrings."""
465
+
466
+ updated_at: Optional[str] = None
467
+ """Only records where updated_at equals this value."""
468
+
469
+ updated_at__gt: Optional[str] = None
470
+ """Only records where updated_at is greater than this value."""
471
+
472
+ updated_at__gte: Optional[str] = None
473
+ """Only records where updated_at is greater than or equal to this value."""
474
+
475
+ updated_at__lt: Optional[str] = None
476
+ """Only records where updated_at is less than this value."""
477
+
478
+ updated_at__lte: Optional[str] = None
479
+ """Only records where updated_at is less than or equal to this value."""
480
+
481
+
482
+ class ListRequest(APIRequestModel):
483
+ filter: Optional[Union[Dict[str, str], FilterList]] = None
484
+ last: Optional[str] = None
485
+ """Reflected value from a previous response to obtain the next page of results."""
486
+
487
+ order: Optional[ItemOrder] = None
488
+ """Order results asc(ending) or desc(ending)."""
489
+
490
+ order_by: Optional[ItemOrderBy] = None
491
+ """Which field to order results by."""
492
+
493
+ size: Optional[int] = None
494
+ """Maximum results to include in the response."""
495
+
496
+ include_external_bucket_key: bool = False
497
+ """If true, include the `external_bucket_key` in results."""
498
+
499
+ bucket_id: Optional[str] = None
500
+ """The bucket to use, if not the default."""
501
+
502
+
503
+ class ListResult(PangeaResponseResult):
504
+ count: int
505
+ """The total number of objects matched by the list request."""
506
+
507
+ last: Optional[str] = None
508
+ """Used to fetch the next page of the current listing when provided in a repeated request's last parameter."""
509
+
510
+ objects: List[ItemData]
511
+
512
+
513
+ class GetArchiveRequest(APIRequestModel):
514
+ ids: List[str] = []
515
+ """The IDs of the objects to include in the archive. Folders include all children."""
516
+
517
+ format: Optional[ArchiveFormat] = None
518
+ """The format to use to build the archive."""
519
+
520
+ transfer_method: Optional[TransferMethod] = None
521
+ """The requested transfer method for the file data."""
522
+
523
+ bucket_id: Optional[str] = None
524
+ """The bucket to use, if not the default."""
525
+
526
+
527
+ class GetArchiveResult(PangeaResponseResult):
528
+ count: int
529
+ """Number of objects included in the archive."""
530
+
531
+ dest_url: Optional[str] = None
532
+ """A location where the archive can be downloaded from. (transfer_method: dest-url)"""
533
+
534
+ objects: List[ItemData] = []
535
+ """A list of all objects included in the archive."""
536
+
537
+
538
+ class Authenticator(PangeaResponseResult):
539
+ auth_type: AuthenticatorType
540
+ """An authentication mechanism."""
541
+
542
+ auth_context: str
543
+ """An email address, a phone number or a password to access share link."""
544
+
545
+
546
+ class ShareLinkItemBase(PangeaResponseResult):
547
+ targets: List[str] = []
548
+ """List of storage IDs."""
549
+
550
+ link_type: Optional[LinkType] = None
551
+ """Type of link."""
552
+
553
+ expires_at: Optional[str] = None
554
+ """The date and time the share link expires."""
555
+
556
+ max_access_count: Optional[int] = None
557
+ """The maximum number of times a user can be authenticated to access the share link."""
558
+
559
+ authenticators: Optional[List[Authenticator]] = None
560
+ """A list of authenticators."""
561
+
562
+ title: Optional[str] = None
563
+ """An optional title to use in accessing shares."""
564
+
565
+ message: Optional[str] = None
566
+ """An optional message to use in accessing shares."""
567
+
568
+ notify_email: Optional[str] = None
569
+ """An email address"""
570
+
571
+ tags: Optional[Tags] = None
572
+ """A list of user-defined tags"""
573
+
574
+
575
+ class ShareLinkCreateItem(ShareLinkItemBase):
576
+ pass
577
+
578
+
579
+ class ShareLinkCreateRequest(APIRequestModel):
580
+ links: List[ShareLinkCreateItem] = []
581
+ bucket_id: Optional[str] = None
582
+ """The bucket to use, if not the default."""
583
+
584
+
585
+ class ShareLinkItem(ShareLinkItemBase):
586
+ id: str
587
+ """The ID of a share link."""
588
+
589
+ access_count: int
590
+ """The number of times a user has authenticated to access the share link."""
591
+
592
+ created_at: str
593
+ """The date and time the share link was created."""
594
+
595
+ last_accessed_at: Optional[str] = None
596
+ """The date and time the share link was last accessed."""
597
+
598
+ link: Optional[str] = None
599
+ """A URL to access the file/folders shared with a link."""
600
+
601
+ bucket_id: str
602
+ """The ID of a share bucket resource."""
603
+
604
+
605
+ class ShareLinkCreateResult(PangeaResponseResult):
606
+ share_link_objects: List[ShareLinkItem] = []
607
+
608
+
609
+ class ShareLinkGetRequest(APIRequestModel):
610
+ id: str
611
+ """The ID of a share link."""
612
+
613
+
614
+ class ShareLinkGetResult(PangeaResponseResult):
615
+ share_link_object: ShareLinkItem
616
+
617
+
618
+ class FilterShareLinkList(APIRequestModel):
619
+ id: Optional[str] = None
620
+ id__contains: Optional[List[str]] = None
621
+ id__in: Optional[List[str]] = None
622
+ target: Optional[str] = None
623
+ target__contains: Optional[List[str]] = None
624
+ target__in: Optional[List[str]] = None
625
+ link_type: Optional[str] = None
626
+ link_type__contains: Optional[List[str]] = None
627
+ link_type__in: Optional[List[str]] = None
628
+ access_count: Optional[int] = None
629
+ access_count__gt: Optional[int] = None
630
+ access_count__gte: Optional[int] = None
631
+ access_count__lt: Optional[int] = None
632
+ access_count__lte: Optional[int] = None
633
+ max_access_count: Optional[int] = None
634
+ max_access_count__gt: Optional[int] = None
635
+ max_access_count__gte: Optional[int] = None
636
+ max_access_count__lt: Optional[int] = None
637
+ max_access_count__lte: Optional[int] = None
638
+ created_at: Optional[str] = None
639
+ created_at__gt: Optional[str] = None
640
+ created_at__gte: Optional[str] = None
641
+ created_at__lt: Optional[str] = None
642
+ created_at__lte: Optional[str] = None
643
+ expires_at: Optional[str] = None
644
+ expires_at__gt: Optional[str] = None
645
+ expires_at__gte: Optional[str] = None
646
+ expires_at__lt: Optional[str] = None
647
+ expires_at__lte: Optional[str] = None
648
+ last_accessed_at: Optional[str] = None
649
+ last_accessed_at__gt: Optional[str] = None
650
+ last_accessed_at__gte: Optional[str] = None
651
+ last_accessed_at__lt: Optional[str] = None
652
+ last_accessed_at__lte: Optional[str] = None
653
+ link: Optional[str] = None
654
+ link__contains: Optional[List[str]] = None
655
+ link__in: Optional[List[str]] = None
656
+ title: Optional[str] = None
657
+ title__contains: Optional[List[str]] = None
658
+ title__in: Optional[List[str]] = None
659
+ message: Optional[str] = None
660
+ message__contains: Optional[List[str]] = None
661
+ message__in: Optional[List[str]] = None
662
+ notify_email: Optional[str] = None
663
+ notify_email__contains: Optional[List[str]] = None
664
+ notify_email__in: Optional[List[str]] = None
665
+ tags: Optional[List[str]] = None
666
+
667
+
668
+ class ShareLinkListRequest(APIRequestModel):
669
+ filter: Optional[Union[FilterShareLinkList, Dict[str, str]]] = None
670
+
671
+ last: Optional[str] = None
672
+ """Reflected value from a previous response to obtain the next page of results."""
673
+
674
+ order: Optional[ItemOrder] = None
675
+ """Order results asc(ending) or desc(ending)."""
676
+
677
+ order_by: Optional[ShareLinkOrderBy] = None
678
+ """Which field to order results by."""
679
+
680
+ size: Optional[int] = None
681
+ """Maximum results to include in the response."""
682
+
683
+ bucket_id: Optional[str] = None
684
+ """The bucket to use, if not the default."""
685
+
686
+
687
+ class ShareLinkListResult(PangeaResponseResult):
688
+ count: int
689
+ """The total number of share links matched by the list request."""
690
+
691
+ last: Optional[str] = None
692
+ """Used to fetch the next page of the current listing when provided in a repeated request's last parameter."""
693
+
694
+ share_link_objects: List[ShareLinkItem] = []
695
+
696
+
697
+ class ShareLinkDeleteRequest(APIRequestModel):
698
+ ids: List[str]
699
+ bucket_id: Optional[str] = None
700
+ """The bucket to use, if not the default."""
701
+
702
+
703
+ class ShareLinkDeleteResult(PangeaResponseResult):
704
+ share_link_objects: List[ShareLinkItem] = []
705
+
706
+
707
+ class ShareLinkSendItem(APIRequestModel):
708
+ id: str
709
+ email: str
710
+
711
+
712
+ class ShareLinkSendRequest(APIRequestModel):
713
+ links: List[ShareLinkSendItem]
714
+
715
+ sender_email: str
716
+ """An email address."""
717
+
718
+ sender_name: Optional[str]
719
+ """The sender name information. Can be sender's full name for example."""
720
+
721
+
722
+ class ShareLinkSendResult(PangeaResponseResult):
723
+ share_link_objects: List[ShareLinkItem]
724
+
725
+
726
+ class Bucket(PangeaResponseResult):
727
+ id: str
728
+ """The ID of a share bucket resource."""
729
+
730
+ default: bool
731
+ """If true, is the default bucket."""
732
+
733
+ name: str
734
+ """The bucket's friendly name."""
735
+
736
+ transfer_methods: List[TransferMethod]
737
+
738
+
739
+ class BucketsResult(PangeaResponseResult):
740
+ buckets: List[Bucket]
741
+ """A list of available buckets."""
742
+
743
+
744
+ class Share(ServiceBase):
745
+ """Secure Share service client."""
746
+
747
+ service_name = "share"
748
+
749
+ def __init__(
750
+ self, token: str, config: PangeaConfig | None = None, logger_name: str = "pangea", config_id: str | None = None
751
+ ) -> None:
752
+ """
753
+ Secure Share client
754
+
755
+ Initializes a new Secure Share client.
756
+
757
+ Args:
758
+ token: Pangea API token.
759
+ config: Configuration.
760
+ logger_name: Logger name.
761
+ config_id: Configuration ID.
762
+
763
+ Examples:
764
+ config = PangeaConfig(domain="aws.us.pangea.cloud")
765
+ authz = Share(token="pangea_token", config=config)
766
+ """
767
+
768
+ super().__init__(token, config, logger_name, config_id=config_id)
769
+
770
+ def buckets(self) -> PangeaResponse[BucketsResult]:
771
+ """
772
+ Buckets
773
+
774
+ Get information on the accessible buckets.
775
+
776
+ OperationId: share_post_v1_buckets
777
+
778
+ Returns:
779
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
780
+
781
+ Examples:
782
+ response = share.buckets()
783
+ """
784
+ return self.request.post("v1/buckets", BucketsResult)
785
+
786
+ def delete(
787
+ self,
788
+ id: Optional[str] = None,
789
+ force: Optional[bool] = None,
790
+ bucket_id: Optional[str] = None,
791
+ ) -> PangeaResponse[DeleteResult]:
792
+ """
793
+ Delete
794
+
795
+ Delete object by ID or path. If both are supplied, the path must match
796
+ that of the object represented by the ID.
797
+
798
+ OperationId: share_post_v1_delete
799
+
800
+ Args:
801
+ id (str, optional): The ID of the object to delete.
802
+ force (bool, optional): If true, delete a folder even if it's not empty.
803
+ bucket_id (str, optional): The bucket to use, if not the default.
804
+
805
+ Returns:
806
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
807
+
808
+ Examples:
809
+ response = share.delete(id="pos_3djfmzg2db4c6donarecbyv5begtj2bm")
810
+ """
811
+ input = DeleteRequest(id=id, force=force, bucket_id=bucket_id)
812
+ return self.request.post("v1/delete", DeleteResult, data=input.model_dump(exclude_none=True))
813
+
814
+ def folder_create(
815
+ self,
816
+ name: Optional[str] = None,
817
+ metadata: Optional[Metadata] = None,
818
+ parent_id: Optional[str] = None,
819
+ folder: Optional[str] = None,
820
+ tags: Optional[Tags] = None,
821
+ bucket_id: Optional[str] = None,
822
+ *,
823
+ file_ttl: Optional[str] = None,
824
+ root_folder: Optional[str] = None,
825
+ root_id: Optional[str] = None,
826
+ tenant_id: Optional[str] = None,
827
+ ) -> PangeaResponse[FolderCreateResult]:
828
+ """
829
+ Create a folder
830
+
831
+ Create a folder, either by name or path and parent_id.
832
+
833
+ OperationId: share_post_v1_folder_create
834
+
835
+ Args:
836
+ name (str, optional): The name of an object.
837
+ metadata (Metadata, optional): A set of string-based key/value pairs used to provide additional data about an object.
838
+ parent_id (str, optional): The ID of a stored object.
839
+ folder (str, optional): The folder to place the folder in. Must
840
+ match `parent_id` if also set.
841
+ tags (Tags, optional): A list of user-defined tags.
842
+ bucket_id (str, optional): The bucket to use, if not the default.
843
+ file_ttl: Duration until files within this folder are automatically
844
+ deleted.
845
+ root_folder: The path of a root folder to restrict the operation to.
846
+ Must resolve to `root_id` if also set.
847
+ root_id: The ID of a root folder to restrict the operation to. Must
848
+ match `root_folder` if also set.
849
+ tenant_id: A tenant to associate with this request
850
+
851
+ Returns:
852
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
853
+
854
+ Examples:
855
+ response = share.folder_create(
856
+ metadata={
857
+ "created_by": "jim",
858
+ "priority": "medium",
859
+ },
860
+ parent_id="pos_3djfmzg2db4c6donarecbyv5begtj2bm",
861
+ folder="/",
862
+ tags=["irs_2023", "personal"],
863
+ )
864
+ """
865
+ input = FolderCreateRequest(
866
+ name=name,
867
+ metadata=metadata,
868
+ parent_id=parent_id,
869
+ folder=folder,
870
+ tags=tags,
871
+ bucket_id=bucket_id,
872
+ file_ttl=file_ttl,
873
+ root_folder=root_folder,
874
+ root_id=root_id,
875
+ tenant_id=tenant_id,
876
+ )
877
+ return self.request.post("v1/folder/create", FolderCreateResult, data=input.model_dump(exclude_none=True))
878
+
879
+ def get(
880
+ self,
881
+ id: Optional[str] = None,
882
+ transfer_method: Optional[TransferMethod] = None,
883
+ bucket_id: Optional[str] = None,
884
+ password: Optional[str] = None,
885
+ *,
886
+ tenant_id: Optional[str] = None,
887
+ ) -> PangeaResponse[GetResult]:
888
+ """
889
+ Get an object
890
+
891
+ Get object. If both ID and Path are supplied, the call will fail if the
892
+ target object doesn't match both properties.
893
+
894
+ OperationId: share_post_v1_get
895
+
896
+ Args:
897
+ id (str, optional): The ID of the object to retrieve.
898
+ transfer_method (TransferMethod, optional): The requested transfer method for the file data.
899
+ bucket_id (str, optional): The bucket to use, if not the default.
900
+ password (str, optional): If the file was protected with a password, the password to decrypt with.
901
+ tenant_id: A tenant to associate with this request.
902
+
903
+ Returns:
904
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
905
+
906
+ Examples:
907
+ response = share.get(
908
+ id="pos_3djfmzg2db4c6donarecbyv5begtj2bm",
909
+ folder="/",
910
+ )
911
+ """
912
+ input = GetRequest(
913
+ id=id, transfer_method=transfer_method, bucket_id=bucket_id, password=password, tenant_id=tenant_id
914
+ )
915
+ return self.request.post("v1/get", GetResult, data=input.model_dump(exclude_none=True))
916
+
917
+ def get_archive(
918
+ self,
919
+ ids: List[str] = [],
920
+ format: Optional[ArchiveFormat] = None,
921
+ transfer_method: Optional[TransferMethod] = None,
922
+ bucket_id: Optional[str] = None,
923
+ ) -> PangeaResponse[GetArchiveResult]:
924
+ """
925
+ Get archive
926
+
927
+ Get an archive file of multiple objects.
928
+
929
+ OperationId: share_post_v1_get_archive
930
+
931
+ Args:
932
+ ids (List[str]): The IDs of the objects to include in the archive. Folders include all children.
933
+ format (ArchiveFormat, optional): The format to use for the built archive.
934
+ transfer_method (TransferMethod, optional): The requested transfer method for the file data.
935
+ bucket_id (str, optional): The bucket to use, if not the default.
936
+
937
+ Returns:
938
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
939
+
940
+ Examples:
941
+ response = share.get_archive(
942
+ ids=["pos_3djfmzg2db4c6donarecbyv5begtj2bm"],
943
+ )
944
+ """
945
+ if (
946
+ transfer_method is not None
947
+ and transfer_method != TransferMethod.DEST_URL
948
+ and transfer_method != TransferMethod.MULTIPART
949
+ ):
950
+ raise ValueError(f"Only {TransferMethod.DEST_URL} and {TransferMethod.MULTIPART} are supported")
951
+
952
+ input = GetArchiveRequest(ids=ids, format=format, transfer_method=transfer_method, bucket_id=bucket_id)
953
+ return self.request.post("v1/get_archive", GetArchiveResult, data=input.model_dump(exclude_none=True))
954
+
955
+ def list(
956
+ self,
957
+ filter: Optional[Union[Dict[str, str], FilterList]] = None,
958
+ last: Optional[str] = None,
959
+ order: Optional[ItemOrder] = None,
960
+ order_by: Optional[ItemOrderBy] = None,
961
+ size: Optional[int] = None,
962
+ bucket_id: Optional[str] = None,
963
+ ) -> PangeaResponse[ListResult]:
964
+ """
965
+ List
966
+
967
+ List or filter/search records.
968
+
969
+ OperationId: share_post_v1_list
970
+
971
+ Args:
972
+ filter (Union[Dict[str, str], FilterList], optional):
973
+ last (str, optional): Reflected value from a previous response to obtain the next page of results.
974
+ order (ItemOrder, optional): Order results asc(ending) or desc(ending).
975
+ order_by (ItemOrderBy, optional): Which field to order results by.
976
+ size (int, optional): Maximum results to include in the response.
977
+ bucket_id (str, optional): The bucket to use, if not the default.
978
+
979
+ Returns:
980
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
981
+
982
+ Examples:
983
+ response = share.list()
984
+ """
985
+ input = ListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size, bucket_id=bucket_id)
986
+ return self.request.post("v1/list", ListResult, data=input.model_dump(exclude_none=True))
987
+
988
+ def put(
989
+ self,
990
+ file: io.BufferedReader,
991
+ name: Optional[str] = None,
992
+ folder: Optional[str] = None,
993
+ format: Optional[FileFormat] = None,
994
+ metadata: Optional[Metadata] = None,
995
+ mimetype: Optional[str] = None,
996
+ parent_id: Optional[str] = None,
997
+ tags: Optional[Tags] = None,
998
+ transfer_method: Optional[TransferMethod] = TransferMethod.POST_URL,
999
+ crc32c: Optional[str] = None,
1000
+ md5: Optional[str] = None,
1001
+ sha1: Optional[str] = None,
1002
+ sha256: Optional[str] = None,
1003
+ sha512: Optional[str] = None,
1004
+ size: Optional[int] = None,
1005
+ bucket_id: Optional[str] = None,
1006
+ password: Optional[str] = None,
1007
+ password_algorithm: Optional[str] = None,
1008
+ *,
1009
+ file_ttl: Optional[str] = None,
1010
+ root_folder: Optional[str] = None,
1011
+ root_id: Optional[str] = None,
1012
+ tenant_id: Optional[str] = None,
1013
+ ) -> PangeaResponse[PutResult]:
1014
+ """
1015
+ Upload a file
1016
+
1017
+ Upload a file.
1018
+
1019
+ OperationId: share_post_v1_put
1020
+
1021
+ Args:
1022
+ file (io.BufferedReader):
1023
+ name (str, optional): The name of the object to store.
1024
+ folder (str, optional): The path to the parent folder. Leave blank
1025
+ for the root folder. Path must resolve to `parent_id` if also set.
1026
+ format (FileFormat, optional): The format of the file, which will be verified by the server if provided. Uploads not matching the supplied format will be rejected.
1027
+ metadata (Metadata, optional): A set of string-based key/value pairs used to provide additional data about an object.
1028
+ mimetype (str, optional): The MIME type of the file, which will be verified by the server if provided. Uploads not matching the supplied MIME type will be rejected.
1029
+ parent_id (str, optional): The parent ID of the object (a folder). Leave blank to keep in the root folder.
1030
+ tags (Tags, optional): A list of user-defined tags.
1031
+ transfer_method (TransferMethod, optional): The transfer method used to upload the file data.
1032
+ crc32c (str, optional): The hexadecimal-encoded CRC32C hash of the file data, which will be verified by the server if provided.
1033
+ md5 (str, optional): The hexadecimal-encoded MD5 hash of the file data, which will be verified by the server if provided.
1034
+ sha1 (str, optional): The hexadecimal-encoded SHA1 hash of the file data, which will be verified by the server if provided.
1035
+ sha256 (str, optional): The SHA256 hash of the file data, which will be verified by the server if provided.
1036
+ sha512 (str, optional): The hexadecimal-encoded SHA512 hash of the file data, which will be verified by the server if provided.
1037
+ size (str, optional): The size (in bytes) of the file. If the upload doesn't match, the call will fail.
1038
+ bucket_id (str, optional): The bucket to use, if not the default.
1039
+ password (str, optional): An optional password to protect the file with. Downloading the file will require this password.
1040
+ password_algorithm (str, optional): An optional password algorithm to protect the file with. See symmetric vault password_algorithm.
1041
+ file_ttl: The TTL before expiry for the file.
1042
+ root_folder: The path of a root folder to restrict the operation to.
1043
+ Must resolve to `root_id` if also set.
1044
+ root_id: The ID of a root folder to restrict the operation to. Must
1045
+ match `root_folder` if also set.
1046
+ tenant_id: A tenant to associate with this request.
1047
+
1048
+ Returns:
1049
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
1050
+
1051
+ Examples:
1052
+ try:
1053
+ with open("./path/to/file.pdf", "rb") as f:
1054
+ response = share.put(file=f)
1055
+ print(f"Response: {response.result}")
1056
+ except pe.PangeaAPIException as e:
1057
+ print(f"Request Error: {e.response.summary}")
1058
+ for err in e.errors:
1059
+ print(f"\\t{err.detail} \\n")
1060
+ """
1061
+ files: List[Tuple] = [("upload", (name, file, "application/octet-stream"))]
1062
+
1063
+ if transfer_method == TransferMethod.POST_URL:
1064
+ params = get_file_upload_params(file)
1065
+ crc32c = params.crc_hex
1066
+ sha256 = params.sha256_hex
1067
+ size = params.size
1068
+ elif size is None and get_file_size(file=file) == 0:
1069
+ # Needed to upload zero byte files
1070
+ size = 0
1071
+
1072
+ input = PutRequest(
1073
+ name=name,
1074
+ format=format,
1075
+ metadata=metadata,
1076
+ mimetype=mimetype,
1077
+ parent_id=parent_id,
1078
+ folder=folder,
1079
+ tags=tags,
1080
+ transfer_method=transfer_method,
1081
+ crc32c=crc32c,
1082
+ md5=md5,
1083
+ sha1=sha1,
1084
+ sha256=sha256,
1085
+ sha512=sha512,
1086
+ size=size,
1087
+ bucket_id=bucket_id,
1088
+ password=password,
1089
+ password_algorithm=password_algorithm,
1090
+ file_ttl=file_ttl,
1091
+ root_folder=root_folder,
1092
+ root_id=root_id,
1093
+ tenant_id=tenant_id,
1094
+ )
1095
+ data = input.model_dump(exclude_none=True)
1096
+ return self.request.post("v1/put", PutResult, data=data, files=files)
1097
+
1098
+ def request_upload_url(
1099
+ self,
1100
+ name: Optional[str] = None,
1101
+ folder: Optional[str] = None,
1102
+ format: Optional[FileFormat] = None,
1103
+ metadata: Optional[Metadata] = None,
1104
+ mimetype: Optional[str] = None,
1105
+ parent_id: Optional[str] = None,
1106
+ tags: Optional[Tags] = None,
1107
+ transfer_method: Optional[TransferMethod] = TransferMethod.PUT_URL,
1108
+ md5: Optional[str] = None,
1109
+ sha1: Optional[str] = None,
1110
+ sha512: Optional[str] = None,
1111
+ crc32c: Optional[str] = None,
1112
+ sha256: Optional[str] = None,
1113
+ size: Optional[int] = None,
1114
+ bucket_id: Optional[str] = None,
1115
+ *,
1116
+ file_ttl: Optional[str] = None,
1117
+ password: Optional[str] = None,
1118
+ password_algorithm: Optional[str] = None,
1119
+ root_folder: Optional[str] = None,
1120
+ root_id: Optional[str] = None,
1121
+ tenant_id: Optional[str] = None,
1122
+ ) -> PangeaResponse[PutResult]:
1123
+ """
1124
+ Request upload URL
1125
+
1126
+ Request an upload URL.
1127
+
1128
+ OperationId: share_post_v1_put 2
1129
+
1130
+ Args:
1131
+ name (str, optional): The name of the object to store.
1132
+ folder (str, optional): The path to the parent folder. Leave blank
1133
+ for the root folder. Path must resolve to `parent_id` if also set.
1134
+ format (FileFormat, optional): The format of the file, which will be verified by the server if provided. Uploads not matching the supplied format will be rejected.
1135
+ metadata (Metadata, optional): A set of string-based key/value pairs used to provide additional data about an object.
1136
+ mimetype (str, optional): The MIME type of the file, which will be verified by the server if provided. Uploads not matching the supplied MIME type will be rejected.
1137
+ parent_id (str, optional): The parent ID of the object (a folder). Leave blank to keep in the root folder.
1138
+ tags (Tags, optional): A list of user-defined tags.
1139
+ transfer_method (TransferMethod, optional): The transfer method used to upload the file data.
1140
+ md5 (str, optional): The hexadecimal-encoded MD5 hash of the file data, which will be verified by the server if provided.
1141
+ sha1 (str, optional): The hexadecimal-encoded SHA1 hash of the file data, which will be verified by the server if provided.
1142
+ sha512 (str, optional): The hexadecimal-encoded SHA512 hash of the file data, which will be verified by the server if provided.
1143
+ crc32c (str, optional): The hexadecimal-encoded CRC32C hash of the file data, which will be verified by the server if provided.
1144
+ sha256 (str, optional): The SHA256 hash of the file data, which will be verified by the server if provided.
1145
+ size (str, optional): The size (in bytes) of the file. If the upload doesn't match, the call will fail.
1146
+ bucket_id (str, optional): The bucket to use, if not the default.
1147
+ file_ttl: The TTL before expiry for the file.
1148
+ password: An optional password to protect the file with. Downloading
1149
+ the file will require this password.
1150
+ password_algorithm: An optional password algorithm to protect the
1151
+ file with. See symmetric vault password_algorithm.
1152
+ root_folder: The path of a root folder to restrict the operation to.
1153
+ Must resolve to `root_id` if also set.
1154
+ root_id: The ID of a root folder to restrict the operation to. Must
1155
+ match `root_folder` if also set.
1156
+ tenant_id: A tenant to associate with this request.
1157
+
1158
+ Returns:
1159
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
1160
+
1161
+ Examples:
1162
+ response = share.request_upload_url(
1163
+ transfer_method=TransferMethod.POST_URL,
1164
+ crc32c="515f7c32",
1165
+ sha256="c0b56b1a154697f79d27d57a3a2aad4c93849aa2239cd23048fc6f45726271cc",
1166
+ size=222089,
1167
+ metadata={
1168
+ "created_by": "jim",
1169
+ "priority": "medium",
1170
+ },
1171
+ parent_id="pos_3djfmzg2db4c6donarecbyv5begtj2bm",
1172
+ folder="/",
1173
+ tags=["irs_2023", "personal"],
1174
+ )
1175
+ """
1176
+ input = PutRequest(
1177
+ name=name,
1178
+ format=format,
1179
+ metadata=metadata,
1180
+ mimetype=mimetype,
1181
+ parent_id=parent_id,
1182
+ folder=folder,
1183
+ tags=tags,
1184
+ transfer_method=transfer_method,
1185
+ crc32c=crc32c,
1186
+ md5=md5,
1187
+ sha1=sha1,
1188
+ sha256=sha256,
1189
+ sha512=sha512,
1190
+ size=size,
1191
+ bucket_id=bucket_id,
1192
+ file_ttl=file_ttl,
1193
+ password=password,
1194
+ password_algorithm=password_algorithm,
1195
+ root_folder=root_folder,
1196
+ root_id=root_id,
1197
+ tenant_id=tenant_id,
1198
+ )
1199
+
1200
+ data = input.model_dump(exclude_none=True)
1201
+ return self.request.request_presigned_url("v1/put", PutResult, data=data)
1202
+
1203
+ def update(
1204
+ self,
1205
+ id: Optional[str] = None,
1206
+ folder: Optional[str] = None,
1207
+ add_metadata: Optional[Metadata] = None,
1208
+ remove_metadata: Optional[Metadata] = None,
1209
+ metadata: Optional[Metadata] = None,
1210
+ add_tags: Optional[Tags] = None,
1211
+ remove_tags: Optional[Tags] = None,
1212
+ tags: Optional[Tags] = None,
1213
+ parent_id: Optional[str] = None,
1214
+ updated_at: Optional[str] = None,
1215
+ bucket_id: Optional[str] = None,
1216
+ *,
1217
+ add_password: Optional[str] = None,
1218
+ add_password_algorithm: Optional[str] = None,
1219
+ remove_password: Optional[str] = None,
1220
+ file_ttl: Optional[str] = None,
1221
+ root_folder: Optional[str] = None,
1222
+ root_id: Optional[str] = None,
1223
+ tenant_id: Optional[str] = None,
1224
+ ) -> PangeaResponse[UpdateResult]:
1225
+ """
1226
+ Update a file
1227
+
1228
+ Update a file.
1229
+
1230
+ OperationId: share_post_v1_update
1231
+
1232
+ Args:
1233
+ id (str, optional): An identifier for the file to update.
1234
+ folder (str, optional): Set the parent (folder). Leave blank for the
1235
+ root folder. Path must resolve to `parent_id` if also set.
1236
+ add_metadata (Metadata, optional): A list of Metadata key/values to set in the object. If a provided key exists, the value will be replaced.
1237
+ remove_metadata (Metadata, optional): A list of Metadata key/values to remove in the object. It is not an error for a provided key to not exist. If a provided key exists but doesn't match the provided value, it will not be removed.
1238
+ metadata (Metadata, optional): Set the object's Metadata.
1239
+ add_tags (Tags, optional): A list of Tags to add. It is not an error to provide a tag which already exists.
1240
+ remove_tags (Tags, optional): A list of Tags to remove. It is not an error to provide a tag which is not present.
1241
+ tags (Tags, optional): Set the object's Tags.
1242
+ parent_id (str, optional): Set the parent (folder) of the object.
1243
+ updated_at (str, optional): The date and time the object was last updated. If included, the update will fail if this doesn't match what's stored.
1244
+ bucket_id (str, optional): The bucket to use, if not the default.
1245
+ add_password: Protect the file with the supplied password.
1246
+ add_password_algorithm: The algorithm to use to password protect the
1247
+ file.
1248
+ remove_password: Remove the supplied password from the file.
1249
+ file_ttl: Set the file TTL.
1250
+ root_folder: The path of a root folder to restrict the operation to.
1251
+ Must resolve to `root_id` if also set.
1252
+ root_id: The ID of a root folder to restrict the operation to. Must
1253
+ match `root_folder` if also set.
1254
+ tenant_id: A tenant to associate with this request.
1255
+
1256
+ Returns:
1257
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
1258
+
1259
+ Examples:
1260
+ response = share.update(
1261
+ id="pos_3djfmzg2db4c6donarecbyv5begtj2bm",
1262
+ remove_metadata={
1263
+ "created_by": "jim",
1264
+ "priority": "medium",
1265
+ },
1266
+ remove_tags=["irs_2023", "personal"],
1267
+ )
1268
+ """
1269
+ input = UpdateRequest(
1270
+ id=id,
1271
+ folder=folder,
1272
+ add_metadata=add_metadata,
1273
+ remove_metadata=remove_metadata,
1274
+ metadata=metadata,
1275
+ add_tags=add_tags,
1276
+ remove_tags=remove_tags,
1277
+ tags=tags,
1278
+ parent_id=parent_id,
1279
+ updated_at=updated_at,
1280
+ bucket_id=bucket_id,
1281
+ add_password=add_password,
1282
+ add_password_algorithm=add_password_algorithm,
1283
+ remove_password=remove_password,
1284
+ file_ttl=file_ttl,
1285
+ root_folder=root_folder,
1286
+ root_id=root_id,
1287
+ tenant_id=tenant_id,
1288
+ )
1289
+ return self.request.post("v1/update", UpdateResult, data=input.model_dump(exclude_none=True))
1290
+
1291
+ def share_link_create(
1292
+ self, links: List[ShareLinkCreateItem], bucket_id: Optional[str] = None
1293
+ ) -> PangeaResponse[ShareLinkCreateResult]:
1294
+ """
1295
+ Create share links
1296
+
1297
+ Create a share link.
1298
+
1299
+ OperationId: share_post_v1_share_link_create
1300
+
1301
+ Args:
1302
+ links (List[ShareLinkCreateItem]):
1303
+ bucket_id (str, optional): The bucket to use, if not the default.
1304
+
1305
+ Returns:
1306
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
1307
+
1308
+ Examples:
1309
+ response = share.share_link_create(
1310
+ links=[
1311
+ {
1312
+ targets: ["pos_3djfmzg2db4c6donarecbyv5begtj2bm"],
1313
+ link_type: LinkType.DOWNLOAD,
1314
+ authenticators: [
1315
+ {
1316
+ "auth_type": AuthenticatorType.PASSWORD,
1317
+ "auth_context": "my_fav_Pa55word",
1318
+ }
1319
+ ],
1320
+ }
1321
+ ],
1322
+ )
1323
+ """
1324
+ input = ShareLinkCreateRequest(links=links, bucket_id=bucket_id)
1325
+ return self.request.post(
1326
+ "v1/share/link/create", ShareLinkCreateResult, data=input.model_dump(exclude_none=True)
1327
+ )
1328
+
1329
+ def share_link_get(self, id: str) -> PangeaResponse[ShareLinkGetResult]:
1330
+ """
1331
+ Get share link
1332
+
1333
+ Get a share link.
1334
+
1335
+ OperationId: share_post_v1_share_link_get
1336
+
1337
+ Args:
1338
+ id (str, optional): The ID of a share link.
1339
+
1340
+ Returns:
1341
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
1342
+
1343
+ Examples:
1344
+ response = share.share_link_get(
1345
+ id="psl_3djfmzg2db4c6donarecbyv5begtj2bm"
1346
+ )
1347
+ """
1348
+ input = ShareLinkGetRequest(id=id)
1349
+ return self.request.post("v1/share/link/get", ShareLinkGetResult, data=input.model_dump(exclude_none=True))
1350
+
1351
+ def share_link_list(
1352
+ self,
1353
+ filter: Optional[Union[Dict[str, str], FilterShareLinkList]] = None,
1354
+ last: Optional[str] = None,
1355
+ order: Optional[ItemOrder] = None,
1356
+ order_by: Optional[ShareLinkOrderBy] = None,
1357
+ size: Optional[int] = None,
1358
+ bucket_id: Optional[str] = None,
1359
+ ) -> PangeaResponse[ShareLinkListResult]:
1360
+ """
1361
+ List share links
1362
+
1363
+ Look up share links by filter options.
1364
+
1365
+ OperationId: share_post_v1_share_link_list
1366
+
1367
+ Args:
1368
+ filter (Union[Dict[str, str], ShareLinkListFilter], optional):
1369
+ last (str, optional): Reflected value from a previous response to obtain the next page of results.
1370
+ order (ItemOrder, optional): Order results asc(ending) or desc(ending).
1371
+ order_by (ItemOrderBy, optional): Which field to order results by.
1372
+ size (int, optional): Maximum results to include in the response.
1373
+ bucket_id (str, optional): The bucket to use, if not the default.
1374
+
1375
+ Returns:
1376
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
1377
+
1378
+ Examples:
1379
+ response = share.share_link_list()
1380
+ """
1381
+ input = ShareLinkListRequest(
1382
+ filter=filter, last=last, order=order, order_by=order_by, size=size, bucket_id=bucket_id
1383
+ )
1384
+ return self.request.post("v1/share/link/list", ShareLinkListResult, data=input.model_dump(exclude_none=True))
1385
+
1386
+ def share_link_delete(
1387
+ self, ids: List[str], bucket_id: Optional[str] = None
1388
+ ) -> PangeaResponse[ShareLinkDeleteResult]:
1389
+ """
1390
+ Delete share links
1391
+
1392
+ Delete share links.
1393
+
1394
+ OperationId: share_post_v1_share_link_delete
1395
+
1396
+ Args:
1397
+ ids (List[str]): list of the share link's id to delete
1398
+ bucket_id (str, optional): The bucket to use, if not the default
1399
+
1400
+ Returns:
1401
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
1402
+
1403
+ Examples:
1404
+ response = share.share_link_delete(
1405
+ ids=["psl_3djfmzg2db4c6donarecbyv5begtj2bm"]
1406
+ )
1407
+ """
1408
+ input = ShareLinkDeleteRequest(ids=ids, bucket_id=bucket_id)
1409
+ return self.request.post(
1410
+ "v1/share/link/delete", ShareLinkDeleteResult, data=input.model_dump(exclude_none=True)
1411
+ )
1412
+
1413
+ def share_link_send(
1414
+ self, links: List[ShareLinkSendItem], sender_email: str, sender_name: Optional[str] = None
1415
+ ) -> PangeaResponse[ShareLinkSendResult]:
1416
+ """
1417
+ Send share links
1418
+
1419
+ Send a secure share-link notification to a set of email addresses. The
1420
+ notification email will contain an Open button that the recipient can
1421
+ use to follow the secured share-link to authenticate and then access the
1422
+ shared content.
1423
+
1424
+ OperationId: share_post_v1_share_link_send
1425
+
1426
+ Args:
1427
+ sender_email: An email address.
1428
+
1429
+ Returns:
1430
+ A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
1431
+
1432
+ Examples:
1433
+ response = share.share_link_send(
1434
+ links=[ShareLinkSendItem(id=link.id, email="foo@example.org")],
1435
+ sender_email="sender@example.org",
1436
+ )
1437
+ """
1438
+
1439
+ input = ShareLinkSendRequest(links=links, sender_email=sender_email, sender_name=sender_name)
1440
+ return self.request.post("v1/share/link/send", ShareLinkSendResult, data=input.model_dump(exclude_none=True))