pangea-sdk 5.0.0__py3-none-any.whl → 5.2.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.
- pangea/__init__.py +1 -1
- pangea/asyncio/request.py +20 -4
- pangea/asyncio/services/__init__.py +1 -0
- pangea/asyncio/services/audit.py +6 -10
- pangea/asyncio/services/authz.py +23 -2
- pangea/asyncio/services/base.py +21 -2
- pangea/asyncio/services/intel.py +3 -0
- pangea/asyncio/services/sanitize.py +26 -2
- pangea/asyncio/services/share.py +643 -0
- pangea/deep_verify.py +7 -1
- pangea/dump_audit.py +8 -7
- pangea/request.py +20 -6
- pangea/response.py +12 -0
- pangea/services/__init__.py +1 -0
- pangea/services/audit/audit.py +5 -10
- pangea/services/authz.py +21 -1
- pangea/services/base.py +16 -2
- pangea/services/intel.py +18 -0
- pangea/services/redact.py +16 -0
- pangea/services/sanitize.py +22 -0
- pangea/services/share/file_format.py +170 -0
- pangea/services/share/share.py +1278 -0
- pangea/utils.py +88 -17
- {pangea_sdk-5.0.0.dist-info → pangea_sdk-5.2.0.dist-info}/METADATA +11 -10
- {pangea_sdk-5.0.0.dist-info → pangea_sdk-5.2.0.dist-info}/RECORD +26 -23
- {pangea_sdk-5.0.0.dist-info → pangea_sdk-5.2.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,1278 @@
|
|
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
|
+
|
164
|
+
class DeleteResult(PangeaResponseResult):
|
165
|
+
count: int
|
166
|
+
"""Number of objects deleted."""
|
167
|
+
|
168
|
+
|
169
|
+
class FolderCreateRequest(APIRequestModel):
|
170
|
+
name: Optional[str] = None
|
171
|
+
"""The name of an object."""
|
172
|
+
|
173
|
+
metadata: Optional[Metadata] = None
|
174
|
+
"""A set of string-based key/value pairs used to provide additional data about an object."""
|
175
|
+
|
176
|
+
parent_id: Optional[str] = None
|
177
|
+
"""The ID of a stored object."""
|
178
|
+
|
179
|
+
folder: Optional[str] = None
|
180
|
+
"""The folder to place the folder in. Must match `parent_id` if also set."""
|
181
|
+
|
182
|
+
tags: Optional[Tags] = None
|
183
|
+
"""A list of user-defined tags"""
|
184
|
+
|
185
|
+
bucket_id: Optional[str] = None
|
186
|
+
"""The bucket to use, if not the default."""
|
187
|
+
|
188
|
+
|
189
|
+
class FolderCreateResult(PangeaResponseResult):
|
190
|
+
object: ItemData
|
191
|
+
"""Information on the created folder."""
|
192
|
+
|
193
|
+
|
194
|
+
class GetRequest(APIRequestModel):
|
195
|
+
id: Optional[str] = None
|
196
|
+
"""The ID of the object to retrieve."""
|
197
|
+
|
198
|
+
password: Optional[str] = None
|
199
|
+
"""If the file was protected with a password, the password to decrypt with."""
|
200
|
+
|
201
|
+
transfer_method: Optional[TransferMethod] = None
|
202
|
+
"""The requested transfer method for the file data."""
|
203
|
+
|
204
|
+
bucket_id: Optional[str] = None
|
205
|
+
"""The bucket to use, if not the default."""
|
206
|
+
|
207
|
+
|
208
|
+
class GetResult(PangeaResponseResult):
|
209
|
+
object: ItemData
|
210
|
+
"""File information."""
|
211
|
+
|
212
|
+
dest_url: Optional[str] = None
|
213
|
+
"""A URL where the file can be downloaded from. (transfer_method: dest-url)"""
|
214
|
+
|
215
|
+
|
216
|
+
class PutRequest(APIRequestModel):
|
217
|
+
transfer_method: Optional[TransferMethod] = None
|
218
|
+
"""The transfer method used to upload the file data."""
|
219
|
+
|
220
|
+
bucket_id: Optional[str] = None
|
221
|
+
"""The bucket to use, if not the default."""
|
222
|
+
|
223
|
+
size: Optional[int] = None
|
224
|
+
"""The size (in bytes) of the file. If the upload doesn't match, the call will fail."""
|
225
|
+
|
226
|
+
crc32c: Optional[str] = None
|
227
|
+
"""The hexadecimal-encoded CRC32C hash of the file data, which will be verified by the server if provided."""
|
228
|
+
|
229
|
+
sha256: Optional[str] = None
|
230
|
+
"""The SHA256 hash of the file data, which will be verified by the server if provided."""
|
231
|
+
|
232
|
+
md5: Optional[str] = None
|
233
|
+
"""The hexadecimal-encoded MD5 hash of the file data, which will be verified by the server if provided."""
|
234
|
+
|
235
|
+
name: Optional[str] = None
|
236
|
+
"""The name of the object to store."""
|
237
|
+
|
238
|
+
format: Optional[FileFormat] = None
|
239
|
+
"""The format of the file, which will be verified by the server if provided. Uploads not matching the supplied format will be rejected."""
|
240
|
+
|
241
|
+
metadata: Optional[Metadata] = None
|
242
|
+
"""A set of string-based key/value pairs used to provide additional data about an object."""
|
243
|
+
|
244
|
+
mimetype: Optional[str] = None
|
245
|
+
"""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."""
|
246
|
+
|
247
|
+
parent_id: Optional[str] = None
|
248
|
+
"""The parent ID of the object (a folder). Leave blank to keep in the root folder."""
|
249
|
+
|
250
|
+
folder: Optional[str] = None
|
251
|
+
"""The path to the parent folder. Leave blank for the root folder. Path must resolve to `parent_id` if also set."""
|
252
|
+
|
253
|
+
password: Optional[str] = None
|
254
|
+
"""An optional password to protect the file with. Downloading the file will require this password."""
|
255
|
+
|
256
|
+
password_algorithm: Optional[str] = None
|
257
|
+
"""An optional password algorithm to protect the file with. See symmetric vault password_algorithm."""
|
258
|
+
|
259
|
+
sha1: Optional[str] = None
|
260
|
+
"""The hexadecimal-encoded SHA1 hash of the file data, which will be verified by the server if provided."""
|
261
|
+
|
262
|
+
sha512: Optional[str] = None
|
263
|
+
"""The hexadecimal-encoded SHA512 hash of the file data, which will be verified by the server if provided."""
|
264
|
+
|
265
|
+
tags: Optional[Tags] = None
|
266
|
+
"""A list of user-defined tags"""
|
267
|
+
|
268
|
+
|
269
|
+
class PutResult(PangeaResponseResult):
|
270
|
+
object: ItemData
|
271
|
+
|
272
|
+
|
273
|
+
class UpdateRequest(APIRequestModel):
|
274
|
+
id: Optional[str]
|
275
|
+
"""An identifier for the file to update."""
|
276
|
+
|
277
|
+
folder: Optional[str] = None
|
278
|
+
"""
|
279
|
+
Set the parent (folder). Leave blank for the root folder. Path must resolve
|
280
|
+
to `parent_id` if also set.
|
281
|
+
"""
|
282
|
+
|
283
|
+
add_metadata: Optional[Metadata] = None
|
284
|
+
"""A list of Metadata key/values to set in the object. If a provided key exists, the value will be replaced."""
|
285
|
+
|
286
|
+
add_password: Optional[str] = None
|
287
|
+
"""Protect the file with the supplied password."""
|
288
|
+
|
289
|
+
add_password_algorithm: Optional[str] = None
|
290
|
+
"""The algorithm to use to password protect the file."""
|
291
|
+
|
292
|
+
add_tags: Optional[Tags] = None
|
293
|
+
"""A list of Tags to add. It is not an error to provide a tag which already exists."""
|
294
|
+
|
295
|
+
name: Optional[str] = None
|
296
|
+
"""Sets the object's Name."""
|
297
|
+
|
298
|
+
metadata: Optional[Metadata] = None
|
299
|
+
"""Set the object's metadata."""
|
300
|
+
|
301
|
+
remove_metadata: Optional[Metadata] = None
|
302
|
+
"""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."""
|
303
|
+
|
304
|
+
remove_password: Optional[str] = None
|
305
|
+
"""Remove the supplied password from the file."""
|
306
|
+
|
307
|
+
remove_tags: Optional[Tags] = None
|
308
|
+
"""A list of tags to remove. It is not an error to provide a tag which is not present."""
|
309
|
+
|
310
|
+
parent_id: Optional[str] = None
|
311
|
+
"""Set the parent (folder) of the object. Can be an empty string for the root folder."""
|
312
|
+
|
313
|
+
tags: Optional[Tags] = None
|
314
|
+
"""Set the object's tags."""
|
315
|
+
|
316
|
+
updated_at: Optional[str] = None
|
317
|
+
"""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."""
|
318
|
+
|
319
|
+
bucket_id: Optional[str] = None
|
320
|
+
"""The bucket to use, if not the default."""
|
321
|
+
|
322
|
+
|
323
|
+
class UpdateResult(PangeaResponseResult):
|
324
|
+
object: ItemData
|
325
|
+
|
326
|
+
|
327
|
+
class FilterList(APIRequestModel):
|
328
|
+
created_at: Optional[str] = None
|
329
|
+
"""Only records where created_at equals this value."""
|
330
|
+
|
331
|
+
created_at__gt: Optional[str] = None
|
332
|
+
"""Only records where created_at is greater than this value."""
|
333
|
+
|
334
|
+
created_at__gte: Optional[str] = None
|
335
|
+
"""Only records where created_at is greater than or equal to this value."""
|
336
|
+
|
337
|
+
created_at__lt: Optional[str] = None
|
338
|
+
"""Only records where created_at is less than this value."""
|
339
|
+
|
340
|
+
created_at__lte: Optional[str] = None
|
341
|
+
"""Only records where created_at is less than or equal to this value."""
|
342
|
+
|
343
|
+
folder: Optional[str] = None
|
344
|
+
"""Only records where the object exists in the supplied parent folder path name."""
|
345
|
+
|
346
|
+
id: Optional[str] = None
|
347
|
+
"""Only records where id equals this value."""
|
348
|
+
|
349
|
+
id__in: Optional[List[str]] = None
|
350
|
+
"""Only records where id equals one of the provided substrings."""
|
351
|
+
|
352
|
+
name: Optional[str] = None
|
353
|
+
"""Only records where name equals this value."""
|
354
|
+
|
355
|
+
name__contains: Optional[List[str]] = None
|
356
|
+
"""Only records where name includes each substring."""
|
357
|
+
|
358
|
+
name__in: Optional[List[str]] = None
|
359
|
+
"""Only records where name equals one of the provided substrings."""
|
360
|
+
|
361
|
+
parent_id: Optional[str] = None
|
362
|
+
"""Only records where parent_id equals this value."""
|
363
|
+
|
364
|
+
parent_id__in: Optional[List[str]] = None
|
365
|
+
"""Only records where parent_id equals one of the provided substrings."""
|
366
|
+
|
367
|
+
size: Optional[int] = None
|
368
|
+
"""Only records where size equals this value."""
|
369
|
+
|
370
|
+
size__gt: Optional[int] = None
|
371
|
+
"""Only records where size is greater than this value."""
|
372
|
+
|
373
|
+
size__gte: Optional[int] = None
|
374
|
+
"""Only records where size is greater than or equal to this value."""
|
375
|
+
|
376
|
+
size__lt: Optional[int] = None
|
377
|
+
"""Only records where size is less than to this value."""
|
378
|
+
|
379
|
+
size__lte: Optional[int] = None
|
380
|
+
"""Only records where size is less than or equal to this value."""
|
381
|
+
|
382
|
+
tags: Optional[List[str]] = None
|
383
|
+
"""A list of tags that all must be present."""
|
384
|
+
|
385
|
+
type: Optional[str] = None
|
386
|
+
"""Only records where type equals this value."""
|
387
|
+
|
388
|
+
type__contains: Optional[List[str]] = None
|
389
|
+
"""Only records where type includes each substring."""
|
390
|
+
|
391
|
+
type__in: Optional[List[str]] = None
|
392
|
+
"""Only records where type equals one of the provided substrings."""
|
393
|
+
|
394
|
+
updated_at: Optional[str] = None
|
395
|
+
"""Only records where updated_at equals this value."""
|
396
|
+
|
397
|
+
updated_at__gt: Optional[str] = None
|
398
|
+
"""Only records where updated_at is greater than this value."""
|
399
|
+
|
400
|
+
updated_at__gte: Optional[str] = None
|
401
|
+
"""Only records where updated_at is greater than or equal to this value."""
|
402
|
+
|
403
|
+
updated_at__lt: Optional[str] = None
|
404
|
+
"""Only records where updated_at is less than this value."""
|
405
|
+
|
406
|
+
updated_at__lte: Optional[str] = None
|
407
|
+
"""Only records where updated_at is less than or equal to this value."""
|
408
|
+
|
409
|
+
|
410
|
+
class ListRequest(APIRequestModel):
|
411
|
+
filter: Optional[Union[Dict[str, str], FilterList]] = None
|
412
|
+
last: Optional[str] = None
|
413
|
+
"""Reflected value from a previous response to obtain the next page of results."""
|
414
|
+
|
415
|
+
order: Optional[ItemOrder] = None
|
416
|
+
"""Order results asc(ending) or desc(ending)."""
|
417
|
+
|
418
|
+
order_by: Optional[ItemOrderBy] = None
|
419
|
+
"""Which field to order results by."""
|
420
|
+
|
421
|
+
size: Optional[int] = None
|
422
|
+
"""Maximum results to include in the response."""
|
423
|
+
|
424
|
+
include_external_bucket_key: bool = False
|
425
|
+
"""If true, include the `external_bucket_key` in results."""
|
426
|
+
|
427
|
+
bucket_id: Optional[str] = None
|
428
|
+
"""The bucket to use, if not the default."""
|
429
|
+
|
430
|
+
|
431
|
+
class ListResult(PangeaResponseResult):
|
432
|
+
count: int
|
433
|
+
"""The total number of objects matched by the list request."""
|
434
|
+
|
435
|
+
last: Optional[str] = None
|
436
|
+
"""Used to fetch the next page of the current listing when provided in a repeated request's last parameter."""
|
437
|
+
|
438
|
+
objects: List[ItemData]
|
439
|
+
|
440
|
+
|
441
|
+
class GetArchiveRequest(APIRequestModel):
|
442
|
+
ids: List[str] = []
|
443
|
+
"""The IDs of the objects to include in the archive. Folders include all children."""
|
444
|
+
|
445
|
+
format: Optional[ArchiveFormat] = None
|
446
|
+
"""The format to use to build the archive."""
|
447
|
+
|
448
|
+
transfer_method: Optional[TransferMethod] = None
|
449
|
+
"""The requested transfer method for the file data."""
|
450
|
+
|
451
|
+
bucket_id: Optional[str] = None
|
452
|
+
"""The bucket to use, if not the default."""
|
453
|
+
|
454
|
+
|
455
|
+
class GetArchiveResult(PangeaResponseResult):
|
456
|
+
count: int
|
457
|
+
"""Number of objects included in the archive."""
|
458
|
+
|
459
|
+
dest_url: Optional[str] = None
|
460
|
+
"""A location where the archive can be downloaded from. (transfer_method: dest-url)"""
|
461
|
+
|
462
|
+
objects: List[ItemData] = []
|
463
|
+
"""A list of all objects included in the archive."""
|
464
|
+
|
465
|
+
|
466
|
+
class Authenticator(PangeaResponseResult):
|
467
|
+
auth_type: AuthenticatorType
|
468
|
+
"""An authentication mechanism."""
|
469
|
+
|
470
|
+
auth_context: str
|
471
|
+
"""An email address, a phone number or a password to access share link."""
|
472
|
+
|
473
|
+
|
474
|
+
class ShareLinkItemBase(PangeaResponseResult):
|
475
|
+
targets: List[str] = []
|
476
|
+
"""List of storage IDs."""
|
477
|
+
|
478
|
+
link_type: Optional[LinkType] = None
|
479
|
+
"""Type of link."""
|
480
|
+
|
481
|
+
expires_at: Optional[str] = None
|
482
|
+
"""The date and time the share link expires."""
|
483
|
+
|
484
|
+
max_access_count: Optional[int] = None
|
485
|
+
"""The maximum number of times a user can be authenticated to access the share link."""
|
486
|
+
|
487
|
+
authenticators: Optional[List[Authenticator]] = None
|
488
|
+
"""A list of authenticators."""
|
489
|
+
|
490
|
+
title: Optional[str] = None
|
491
|
+
"""An optional title to use in accessing shares."""
|
492
|
+
|
493
|
+
message: Optional[str] = None
|
494
|
+
"""An optional message to use in accessing shares."""
|
495
|
+
|
496
|
+
notify_email: Optional[str] = None
|
497
|
+
"""An email address"""
|
498
|
+
|
499
|
+
tags: Optional[Tags] = None
|
500
|
+
"""A list of user-defined tags"""
|
501
|
+
|
502
|
+
|
503
|
+
class ShareLinkCreateItem(ShareLinkItemBase):
|
504
|
+
pass
|
505
|
+
|
506
|
+
|
507
|
+
class ShareLinkCreateRequest(APIRequestModel):
|
508
|
+
links: List[ShareLinkCreateItem] = []
|
509
|
+
bucket_id: Optional[str] = None
|
510
|
+
"""The bucket to use, if not the default."""
|
511
|
+
|
512
|
+
|
513
|
+
class ShareLinkItem(ShareLinkItemBase):
|
514
|
+
id: str
|
515
|
+
"""The ID of a share link."""
|
516
|
+
|
517
|
+
access_count: int
|
518
|
+
"""The number of times a user has authenticated to access the share link."""
|
519
|
+
|
520
|
+
created_at: str
|
521
|
+
"""The date and time the share link was created."""
|
522
|
+
|
523
|
+
last_accessed_at: Optional[str] = None
|
524
|
+
"""The date and time the share link was last accessed."""
|
525
|
+
|
526
|
+
link: Optional[str] = None
|
527
|
+
"""A URL to access the file/folders shared with a link."""
|
528
|
+
|
529
|
+
bucket_id: str
|
530
|
+
"""The ID of a share bucket resource."""
|
531
|
+
|
532
|
+
|
533
|
+
class ShareLinkCreateResult(PangeaResponseResult):
|
534
|
+
share_link_objects: List[ShareLinkItem] = []
|
535
|
+
|
536
|
+
|
537
|
+
class ShareLinkGetRequest(APIRequestModel):
|
538
|
+
id: str
|
539
|
+
"""The ID of a share link."""
|
540
|
+
|
541
|
+
|
542
|
+
class ShareLinkGetResult(PangeaResponseResult):
|
543
|
+
share_link_object: ShareLinkItem
|
544
|
+
|
545
|
+
|
546
|
+
class FilterShareLinkList(APIRequestModel):
|
547
|
+
id: Optional[str] = None
|
548
|
+
id__contains: Optional[List[str]] = None
|
549
|
+
id__in: Optional[List[str]] = None
|
550
|
+
target: Optional[str] = None
|
551
|
+
target__contains: Optional[List[str]] = None
|
552
|
+
target__in: Optional[List[str]] = None
|
553
|
+
link_type: Optional[str] = None
|
554
|
+
link_type__contains: Optional[List[str]] = None
|
555
|
+
link_type__in: Optional[List[str]] = None
|
556
|
+
access_count: Optional[int] = None
|
557
|
+
access_count__gt: Optional[int] = None
|
558
|
+
access_count__gte: Optional[int] = None
|
559
|
+
access_count__lt: Optional[int] = None
|
560
|
+
access_count__lte: Optional[int] = None
|
561
|
+
max_access_count: Optional[int] = None
|
562
|
+
max_access_count__gt: Optional[int] = None
|
563
|
+
max_access_count__gte: Optional[int] = None
|
564
|
+
max_access_count__lt: Optional[int] = None
|
565
|
+
max_access_count__lte: Optional[int] = None
|
566
|
+
created_at: Optional[str] = None
|
567
|
+
created_at__gt: Optional[str] = None
|
568
|
+
created_at__gte: Optional[str] = None
|
569
|
+
created_at__lt: Optional[str] = None
|
570
|
+
created_at__lte: Optional[str] = None
|
571
|
+
expires_at: Optional[str] = None
|
572
|
+
expires_at__gt: Optional[str] = None
|
573
|
+
expires_at__gte: Optional[str] = None
|
574
|
+
expires_at__lt: Optional[str] = None
|
575
|
+
expires_at__lte: Optional[str] = None
|
576
|
+
last_accessed_at: Optional[str] = None
|
577
|
+
last_accessed_at__gt: Optional[str] = None
|
578
|
+
last_accessed_at__gte: Optional[str] = None
|
579
|
+
last_accessed_at__lt: Optional[str] = None
|
580
|
+
last_accessed_at__lte: Optional[str] = None
|
581
|
+
link: Optional[str] = None
|
582
|
+
link__contains: Optional[List[str]] = None
|
583
|
+
link__in: Optional[List[str]] = None
|
584
|
+
title: Optional[str] = None
|
585
|
+
title__contains: Optional[List[str]] = None
|
586
|
+
title__in: Optional[List[str]] = None
|
587
|
+
message: Optional[str] = None
|
588
|
+
message__contains: Optional[List[str]] = None
|
589
|
+
message__in: Optional[List[str]] = None
|
590
|
+
notify_email: Optional[str] = None
|
591
|
+
notify_email__contains: Optional[List[str]] = None
|
592
|
+
notify_email__in: Optional[List[str]] = None
|
593
|
+
tags: Optional[List[str]] = None
|
594
|
+
|
595
|
+
|
596
|
+
class ShareLinkListRequest(APIRequestModel):
|
597
|
+
filter: Optional[Union[FilterShareLinkList, Dict[str, str]]] = None
|
598
|
+
|
599
|
+
last: Optional[str] = None
|
600
|
+
"""Reflected value from a previous response to obtain the next page of results."""
|
601
|
+
|
602
|
+
order: Optional[ItemOrder] = None
|
603
|
+
"""Order results asc(ending) or desc(ending)."""
|
604
|
+
|
605
|
+
order_by: Optional[ShareLinkOrderBy] = None
|
606
|
+
"""Which field to order results by."""
|
607
|
+
|
608
|
+
size: Optional[int] = None
|
609
|
+
"""Maximum results to include in the response."""
|
610
|
+
|
611
|
+
bucket_id: Optional[str] = None
|
612
|
+
"""The bucket to use, if not the default."""
|
613
|
+
|
614
|
+
|
615
|
+
class ShareLinkListResult(PangeaResponseResult):
|
616
|
+
count: int
|
617
|
+
"""The total number of share links matched by the list request."""
|
618
|
+
|
619
|
+
last: Optional[str] = None
|
620
|
+
"""Used to fetch the next page of the current listing when provided in a repeated request's last parameter."""
|
621
|
+
|
622
|
+
share_link_objects: List[ShareLinkItem] = []
|
623
|
+
|
624
|
+
|
625
|
+
class ShareLinkDeleteRequest(APIRequestModel):
|
626
|
+
ids: List[str]
|
627
|
+
bucket_id: Optional[str] = None
|
628
|
+
"""The bucket to use, if not the default."""
|
629
|
+
|
630
|
+
|
631
|
+
class ShareLinkDeleteResult(PangeaResponseResult):
|
632
|
+
share_link_objects: List[ShareLinkItem] = []
|
633
|
+
|
634
|
+
|
635
|
+
class ShareLinkSendItem(APIRequestModel):
|
636
|
+
id: str
|
637
|
+
email: str
|
638
|
+
|
639
|
+
|
640
|
+
class ShareLinkSendRequest(APIRequestModel):
|
641
|
+
links: List[ShareLinkSendItem]
|
642
|
+
|
643
|
+
sender_email: str
|
644
|
+
"""An email address."""
|
645
|
+
|
646
|
+
sender_name: Optional[str]
|
647
|
+
"""The sender name information. Can be sender's full name for example."""
|
648
|
+
|
649
|
+
|
650
|
+
class ShareLinkSendResult(PangeaResponseResult):
|
651
|
+
share_link_objects: List[ShareLinkItem]
|
652
|
+
|
653
|
+
|
654
|
+
class Bucket(PangeaResponseResult):
|
655
|
+
id: str
|
656
|
+
"""The ID of a share bucket resource."""
|
657
|
+
|
658
|
+
default: bool
|
659
|
+
"""If true, is the default bucket."""
|
660
|
+
|
661
|
+
name: str
|
662
|
+
"""The bucket's friendly name."""
|
663
|
+
|
664
|
+
transfer_methods: List[TransferMethod]
|
665
|
+
|
666
|
+
|
667
|
+
class BucketsResult(PangeaResponseResult):
|
668
|
+
buckets: List[Bucket]
|
669
|
+
"""A list of available buckets."""
|
670
|
+
|
671
|
+
|
672
|
+
class Share(ServiceBase):
|
673
|
+
"""Secure Share service client."""
|
674
|
+
|
675
|
+
service_name = "share"
|
676
|
+
|
677
|
+
def __init__(
|
678
|
+
self, token: str, config: PangeaConfig | None = None, logger_name: str = "pangea", config_id: str | None = None
|
679
|
+
) -> None:
|
680
|
+
"""
|
681
|
+
Secure Share client
|
682
|
+
|
683
|
+
Initializes a new Secure Share client.
|
684
|
+
|
685
|
+
Args:
|
686
|
+
token: Pangea API token.
|
687
|
+
config: Configuration.
|
688
|
+
logger_name: Logger name.
|
689
|
+
config_id: Configuration ID.
|
690
|
+
|
691
|
+
Examples:
|
692
|
+
config = PangeaConfig(domain="aws.us.pangea.cloud")
|
693
|
+
authz = Share(token="pangea_token", config=config)
|
694
|
+
"""
|
695
|
+
|
696
|
+
super().__init__(token, config, logger_name, config_id=config_id)
|
697
|
+
|
698
|
+
def buckets(self) -> PangeaResponse[BucketsResult]:
|
699
|
+
"""
|
700
|
+
Buckets
|
701
|
+
|
702
|
+
Get information on the accessible buckets.
|
703
|
+
|
704
|
+
OperationId: share_post_v1_buckets
|
705
|
+
|
706
|
+
Returns:
|
707
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
708
|
+
|
709
|
+
Examples:
|
710
|
+
response = share.buckets()
|
711
|
+
"""
|
712
|
+
return self.request.post("v1/buckets", BucketsResult)
|
713
|
+
|
714
|
+
def delete(
|
715
|
+
self,
|
716
|
+
id: Optional[str] = None,
|
717
|
+
force: Optional[bool] = None,
|
718
|
+
bucket_id: Optional[str] = None,
|
719
|
+
) -> PangeaResponse[DeleteResult]:
|
720
|
+
"""
|
721
|
+
Delete
|
722
|
+
|
723
|
+
Delete object by ID or path. If both are supplied, the path must match
|
724
|
+
that of the object represented by the ID.
|
725
|
+
|
726
|
+
OperationId: share_post_v1_delete
|
727
|
+
|
728
|
+
Args:
|
729
|
+
id (str, optional): The ID of the object to delete.
|
730
|
+
force (bool, optional): If true, delete a folder even if it's not empty.
|
731
|
+
bucket_id (str, optional): The bucket to use, if not the default.
|
732
|
+
|
733
|
+
Returns:
|
734
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
735
|
+
|
736
|
+
Examples:
|
737
|
+
response = share.delete(id="pos_3djfmzg2db4c6donarecbyv5begtj2bm")
|
738
|
+
"""
|
739
|
+
input = DeleteRequest(id=id, force=force, bucket_id=bucket_id)
|
740
|
+
return self.request.post("v1/delete", DeleteResult, data=input.model_dump(exclude_none=True))
|
741
|
+
|
742
|
+
def folder_create(
|
743
|
+
self,
|
744
|
+
name: Optional[str] = None,
|
745
|
+
metadata: Optional[Metadata] = None,
|
746
|
+
parent_id: Optional[str] = None,
|
747
|
+
folder: Optional[str] = None,
|
748
|
+
tags: Optional[Tags] = None,
|
749
|
+
bucket_id: Optional[str] = None,
|
750
|
+
) -> PangeaResponse[FolderCreateResult]:
|
751
|
+
"""
|
752
|
+
Create a folder
|
753
|
+
|
754
|
+
Create a folder, either by name or path and parent_id.
|
755
|
+
|
756
|
+
OperationId: share_post_v1_folder_create
|
757
|
+
|
758
|
+
Args:
|
759
|
+
name (str, optional): The name of an object.
|
760
|
+
metadata (Metadata, optional): A set of string-based key/value pairs used to provide additional data about an object.
|
761
|
+
parent_id (str, optional): The ID of a stored object.
|
762
|
+
folder (str, optional): The folder to place the folder in. Must
|
763
|
+
match `parent_id` if also set.
|
764
|
+
tags (Tags, optional): A list of user-defined tags.
|
765
|
+
bucket_id (str, optional): The bucket to use, if not the default.
|
766
|
+
|
767
|
+
Returns:
|
768
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
769
|
+
|
770
|
+
Examples:
|
771
|
+
response = share.folder_create(
|
772
|
+
metadata={
|
773
|
+
"created_by": "jim",
|
774
|
+
"priority": "medium",
|
775
|
+
},
|
776
|
+
parent_id="pos_3djfmzg2db4c6donarecbyv5begtj2bm",
|
777
|
+
folder="/",
|
778
|
+
tags=["irs_2023", "personal"],
|
779
|
+
)
|
780
|
+
"""
|
781
|
+
input = FolderCreateRequest(
|
782
|
+
name=name, metadata=metadata, parent_id=parent_id, folder=folder, tags=tags, bucket_id=bucket_id
|
783
|
+
)
|
784
|
+
return self.request.post("v1/folder/create", FolderCreateResult, data=input.model_dump(exclude_none=True))
|
785
|
+
|
786
|
+
def get(
|
787
|
+
self,
|
788
|
+
id: Optional[str] = None,
|
789
|
+
transfer_method: Optional[TransferMethod] = None,
|
790
|
+
bucket_id: Optional[str] = None,
|
791
|
+
password: Optional[str] = None,
|
792
|
+
) -> PangeaResponse[GetResult]:
|
793
|
+
"""
|
794
|
+
Get an object
|
795
|
+
|
796
|
+
Get object. If both ID and Path are supplied, the call will fail if the
|
797
|
+
target object doesn't match both properties.
|
798
|
+
|
799
|
+
OperationId: share_post_v1_get
|
800
|
+
|
801
|
+
Args:
|
802
|
+
id (str, optional): The ID of the object to retrieve.
|
803
|
+
transfer_method (TransferMethod, optional): The requested transfer method for the file data.
|
804
|
+
bucket_id (str, optional): The bucket to use, if not the default.
|
805
|
+
password (str, optional): If the file was protected with a password, the password to decrypt with.
|
806
|
+
|
807
|
+
Returns:
|
808
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
809
|
+
|
810
|
+
Examples:
|
811
|
+
response = share.get(
|
812
|
+
id="pos_3djfmzg2db4c6donarecbyv5begtj2bm",
|
813
|
+
folder="/",
|
814
|
+
)
|
815
|
+
"""
|
816
|
+
input = GetRequest(id=id, transfer_method=transfer_method, bucket_id=bucket_id, password=password)
|
817
|
+
return self.request.post("v1/get", GetResult, data=input.model_dump(exclude_none=True))
|
818
|
+
|
819
|
+
def get_archive(
|
820
|
+
self,
|
821
|
+
ids: List[str] = [],
|
822
|
+
format: Optional[ArchiveFormat] = None,
|
823
|
+
transfer_method: Optional[TransferMethod] = None,
|
824
|
+
bucket_id: Optional[str] = None,
|
825
|
+
) -> PangeaResponse[GetArchiveResult]:
|
826
|
+
"""
|
827
|
+
Get archive
|
828
|
+
|
829
|
+
Get an archive file of multiple objects.
|
830
|
+
|
831
|
+
OperationId: share_post_v1_get_archive
|
832
|
+
|
833
|
+
Args:
|
834
|
+
ids (List[str]): The IDs of the objects to include in the archive. Folders include all children.
|
835
|
+
format (ArchiveFormat, optional): The format to use for the built archive.
|
836
|
+
transfer_method (TransferMethod, optional): The requested transfer method for the file data.
|
837
|
+
bucket_id (str, optional): The bucket to use, if not the default.
|
838
|
+
|
839
|
+
Returns:
|
840
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
841
|
+
|
842
|
+
Examples:
|
843
|
+
response = share.get_archive(
|
844
|
+
ids=["pos_3djfmzg2db4c6donarecbyv5begtj2bm"],
|
845
|
+
)
|
846
|
+
"""
|
847
|
+
if (
|
848
|
+
transfer_method is not None
|
849
|
+
and transfer_method != TransferMethod.DEST_URL
|
850
|
+
and transfer_method != TransferMethod.MULTIPART
|
851
|
+
):
|
852
|
+
raise ValueError(f"Only {TransferMethod.DEST_URL} and {TransferMethod.MULTIPART} are supported")
|
853
|
+
|
854
|
+
input = GetArchiveRequest(ids=ids, format=format, transfer_method=transfer_method, bucket_id=bucket_id)
|
855
|
+
return self.request.post("v1/get_archive", GetArchiveResult, data=input.model_dump(exclude_none=True))
|
856
|
+
|
857
|
+
def list(
|
858
|
+
self,
|
859
|
+
filter: Optional[Union[Dict[str, str], FilterList]] = None,
|
860
|
+
last: Optional[str] = None,
|
861
|
+
order: Optional[ItemOrder] = None,
|
862
|
+
order_by: Optional[ItemOrderBy] = None,
|
863
|
+
size: Optional[int] = None,
|
864
|
+
bucket_id: Optional[str] = None,
|
865
|
+
) -> PangeaResponse[ListResult]:
|
866
|
+
"""
|
867
|
+
List
|
868
|
+
|
869
|
+
List or filter/search records.
|
870
|
+
|
871
|
+
OperationId: share_post_v1_list
|
872
|
+
|
873
|
+
Args:
|
874
|
+
filter (Union[Dict[str, str], FilterList], optional):
|
875
|
+
last (str, optional): Reflected value from a previous response to obtain the next page of results.
|
876
|
+
order (ItemOrder, optional): Order results asc(ending) or desc(ending).
|
877
|
+
order_by (ItemOrderBy, optional): Which field to order results by.
|
878
|
+
size (int, optional): Maximum results to include in the response.
|
879
|
+
bucket_id (str, optional): The bucket to use, if not the default.
|
880
|
+
|
881
|
+
Returns:
|
882
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
883
|
+
|
884
|
+
Examples:
|
885
|
+
response = share.list()
|
886
|
+
"""
|
887
|
+
input = ListRequest(filter=filter, last=last, order=order, order_by=order_by, size=size, bucket_id=bucket_id)
|
888
|
+
return self.request.post("v1/list", ListResult, data=input.model_dump(exclude_none=True))
|
889
|
+
|
890
|
+
def put(
|
891
|
+
self,
|
892
|
+
file: io.BufferedReader,
|
893
|
+
name: Optional[str] = None,
|
894
|
+
folder: Optional[str] = None,
|
895
|
+
format: Optional[FileFormat] = None,
|
896
|
+
metadata: Optional[Metadata] = None,
|
897
|
+
mimetype: Optional[str] = None,
|
898
|
+
parent_id: Optional[str] = None,
|
899
|
+
tags: Optional[Tags] = None,
|
900
|
+
transfer_method: Optional[TransferMethod] = TransferMethod.POST_URL,
|
901
|
+
crc32c: Optional[str] = None,
|
902
|
+
md5: Optional[str] = None,
|
903
|
+
sha1: Optional[str] = None,
|
904
|
+
sha256: Optional[str] = None,
|
905
|
+
sha512: Optional[str] = None,
|
906
|
+
size: Optional[int] = None,
|
907
|
+
bucket_id: Optional[str] = None,
|
908
|
+
password: Optional[str] = None,
|
909
|
+
password_algorithm: Optional[str] = None,
|
910
|
+
) -> PangeaResponse[PutResult]:
|
911
|
+
"""
|
912
|
+
Upload a file
|
913
|
+
|
914
|
+
Upload a file.
|
915
|
+
|
916
|
+
OperationId: share_post_v1_put
|
917
|
+
|
918
|
+
Args:
|
919
|
+
file (io.BufferedReader):
|
920
|
+
name (str, optional): The name of the object to store.
|
921
|
+
folder (str, optional): The path to the parent folder. Leave blank
|
922
|
+
for the root folder. Path must resolve to `parent_id` if also set.
|
923
|
+
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.
|
924
|
+
metadata (Metadata, optional): A set of string-based key/value pairs used to provide additional data about an object.
|
925
|
+
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.
|
926
|
+
parent_id (str, optional): The parent ID of the object (a folder). Leave blank to keep in the root folder.
|
927
|
+
tags (Tags, optional): A list of user-defined tags.
|
928
|
+
transfer_method (TransferMethod, optional): The transfer method used to upload the file data.
|
929
|
+
crc32c (str, optional): The hexadecimal-encoded CRC32C hash of the file data, which will be verified by the server if provided.
|
930
|
+
md5 (str, optional): The hexadecimal-encoded MD5 hash of the file data, which will be verified by the server if provided.
|
931
|
+
sha1 (str, optional): The hexadecimal-encoded SHA1 hash of the file data, which will be verified by the server if provided.
|
932
|
+
sha256 (str, optional): The SHA256 hash of the file data, which will be verified by the server if provided.
|
933
|
+
sha512 (str, optional): The hexadecimal-encoded SHA512 hash of the file data, which will be verified by the server if provided.
|
934
|
+
size (str, optional): The size (in bytes) of the file. If the upload doesn't match, the call will fail.
|
935
|
+
bucket_id (str, optional): The bucket to use, if not the default.
|
936
|
+
password (str, optional): An optional password to protect the file with. Downloading the file will require this password.
|
937
|
+
password_algorithm (str, optional): An optional password algorithm to protect the file with. See symmetric vault password_algorithm.
|
938
|
+
Returns:
|
939
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
940
|
+
|
941
|
+
Examples:
|
942
|
+
try:
|
943
|
+
with open("./path/to/file.pdf", "rb") as f:
|
944
|
+
response = share.put(file=f)
|
945
|
+
print(f"Response: {response.result}")
|
946
|
+
except pe.PangeaAPIException as e:
|
947
|
+
print(f"Request Error: {e.response.summary}")
|
948
|
+
for err in e.errors:
|
949
|
+
print(f"\\t{err.detail} \\n")
|
950
|
+
"""
|
951
|
+
files: List[Tuple] = [("upload", (name, file, "application/octet-stream"))]
|
952
|
+
|
953
|
+
if transfer_method == TransferMethod.POST_URL:
|
954
|
+
params = get_file_upload_params(file)
|
955
|
+
crc32c = params.crc_hex
|
956
|
+
sha256 = params.sha256_hex
|
957
|
+
size = params.size
|
958
|
+
elif size is None and get_file_size(file=file) == 0:
|
959
|
+
# Needed to upload zero byte files
|
960
|
+
size = 0
|
961
|
+
|
962
|
+
input = PutRequest(
|
963
|
+
name=name,
|
964
|
+
format=format,
|
965
|
+
metadata=metadata,
|
966
|
+
mimetype=mimetype,
|
967
|
+
parent_id=parent_id,
|
968
|
+
folder=folder,
|
969
|
+
tags=tags,
|
970
|
+
transfer_method=transfer_method,
|
971
|
+
crc32c=crc32c,
|
972
|
+
md5=md5,
|
973
|
+
sha1=sha1,
|
974
|
+
sha256=sha256,
|
975
|
+
sha512=sha512,
|
976
|
+
size=size,
|
977
|
+
bucket_id=bucket_id,
|
978
|
+
password=password,
|
979
|
+
password_algorithm=password_algorithm,
|
980
|
+
)
|
981
|
+
data = input.model_dump(exclude_none=True)
|
982
|
+
return self.request.post("v1/put", PutResult, data=data, files=files)
|
983
|
+
|
984
|
+
def request_upload_url(
|
985
|
+
self,
|
986
|
+
name: Optional[str] = None,
|
987
|
+
folder: Optional[str] = None,
|
988
|
+
format: Optional[FileFormat] = None,
|
989
|
+
metadata: Optional[Metadata] = None,
|
990
|
+
mimetype: Optional[str] = None,
|
991
|
+
parent_id: Optional[str] = None,
|
992
|
+
tags: Optional[Tags] = None,
|
993
|
+
transfer_method: Optional[TransferMethod] = TransferMethod.PUT_URL,
|
994
|
+
md5: Optional[str] = None,
|
995
|
+
sha1: Optional[str] = None,
|
996
|
+
sha512: Optional[str] = None,
|
997
|
+
crc32c: Optional[str] = None,
|
998
|
+
sha256: Optional[str] = None,
|
999
|
+
size: Optional[int] = None,
|
1000
|
+
bucket_id: Optional[str] = None,
|
1001
|
+
) -> PangeaResponse[PutResult]:
|
1002
|
+
"""
|
1003
|
+
Request upload URL
|
1004
|
+
|
1005
|
+
Request an upload URL.
|
1006
|
+
|
1007
|
+
OperationId: share_post_v1_put 2
|
1008
|
+
|
1009
|
+
Args:
|
1010
|
+
name (str, optional): The name of the object to store.
|
1011
|
+
folder (str, optional): The path to the parent folder. Leave blank
|
1012
|
+
for the root folder. Path must resolve to `parent_id` if also set.
|
1013
|
+
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.
|
1014
|
+
metadata (Metadata, optional): A set of string-based key/value pairs used to provide additional data about an object.
|
1015
|
+
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.
|
1016
|
+
parent_id (str, optional): The parent ID of the object (a folder). Leave blank to keep in the root folder.
|
1017
|
+
tags (Tags, optional): A list of user-defined tags.
|
1018
|
+
transfer_method (TransferMethod, optional): The transfer method used to upload the file data.
|
1019
|
+
md5 (str, optional): The hexadecimal-encoded MD5 hash of the file data, which will be verified by the server if provided.
|
1020
|
+
sha1 (str, optional): The hexadecimal-encoded SHA1 hash of the file data, which will be verified by the server if provided.
|
1021
|
+
sha512 (str, optional): The hexadecimal-encoded SHA512 hash of the file data, which will be verified by the server if provided.
|
1022
|
+
crc32c (str, optional): The hexadecimal-encoded CRC32C hash of the file data, which will be verified by the server if provided.
|
1023
|
+
sha256 (str, optional): The SHA256 hash of the file data, which will be verified by the server if provided.
|
1024
|
+
size (str, optional): The size (in bytes) of the file. If the upload doesn't match, the call will fail.
|
1025
|
+
bucket_id (str, optional): The bucket to use, if not the default.
|
1026
|
+
|
1027
|
+
Returns:
|
1028
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
1029
|
+
|
1030
|
+
Examples:
|
1031
|
+
response = share.request_upload_url(
|
1032
|
+
transfer_method=TransferMethod.POST_URL,
|
1033
|
+
crc32c="515f7c32",
|
1034
|
+
sha256="c0b56b1a154697f79d27d57a3a2aad4c93849aa2239cd23048fc6f45726271cc",
|
1035
|
+
size=222089,
|
1036
|
+
metadata={
|
1037
|
+
"created_by": "jim",
|
1038
|
+
"priority": "medium",
|
1039
|
+
},
|
1040
|
+
parent_id="pos_3djfmzg2db4c6donarecbyv5begtj2bm",
|
1041
|
+
folder="/",
|
1042
|
+
tags=["irs_2023", "personal"],
|
1043
|
+
)
|
1044
|
+
"""
|
1045
|
+
input = PutRequest(
|
1046
|
+
name=name,
|
1047
|
+
format=format,
|
1048
|
+
metadata=metadata,
|
1049
|
+
mimetype=mimetype,
|
1050
|
+
parent_id=parent_id,
|
1051
|
+
folder=folder,
|
1052
|
+
tags=tags,
|
1053
|
+
transfer_method=transfer_method,
|
1054
|
+
crc32c=crc32c,
|
1055
|
+
md5=md5,
|
1056
|
+
sha1=sha1,
|
1057
|
+
sha256=sha256,
|
1058
|
+
sha512=sha512,
|
1059
|
+
size=size,
|
1060
|
+
bucket_id=bucket_id,
|
1061
|
+
)
|
1062
|
+
|
1063
|
+
data = input.model_dump(exclude_none=True)
|
1064
|
+
return self.request.request_presigned_url("v1/put", PutResult, data=data)
|
1065
|
+
|
1066
|
+
def update(
|
1067
|
+
self,
|
1068
|
+
id: Optional[str] = None,
|
1069
|
+
folder: Optional[str] = None,
|
1070
|
+
add_metadata: Optional[Metadata] = None,
|
1071
|
+
remove_metadata: Optional[Metadata] = None,
|
1072
|
+
metadata: Optional[Metadata] = None,
|
1073
|
+
add_tags: Optional[Tags] = None,
|
1074
|
+
remove_tags: Optional[Tags] = None,
|
1075
|
+
tags: Optional[Tags] = None,
|
1076
|
+
parent_id: Optional[str] = None,
|
1077
|
+
updated_at: Optional[str] = None,
|
1078
|
+
bucket_id: Optional[str] = None,
|
1079
|
+
) -> PangeaResponse[UpdateResult]:
|
1080
|
+
"""
|
1081
|
+
Update a file
|
1082
|
+
|
1083
|
+
Update a file.
|
1084
|
+
|
1085
|
+
OperationId: share_post_v1_update
|
1086
|
+
|
1087
|
+
Args:
|
1088
|
+
id (str, optional): An identifier for the file to update.
|
1089
|
+
path (str, optional): Set the parent (folder). Leave blank for the
|
1090
|
+
root folder. Path must resolve to `parent_id` if also set.
|
1091
|
+
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.
|
1092
|
+
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.
|
1093
|
+
metadata (Metadata, optional): Set the object's Metadata.
|
1094
|
+
add_tags (Tags, optional): A list of Tags to add. It is not an error to provide a tag which already exists.
|
1095
|
+
remove_tags (Tags, optional): A list of Tags to remove. It is not an error to provide a tag which is not present.
|
1096
|
+
tags (Tags, optional): Set the object's Tags.
|
1097
|
+
parent_id (str, optional): Set the parent (folder) of the object.
|
1098
|
+
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.
|
1099
|
+
bucket_id (str, optional): The bucket to use, if not the default.
|
1100
|
+
|
1101
|
+
Returns:
|
1102
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
1103
|
+
|
1104
|
+
Examples:
|
1105
|
+
response = share.update(
|
1106
|
+
id="pos_3djfmzg2db4c6donarecbyv5begtj2bm",
|
1107
|
+
remove_metadata={
|
1108
|
+
"created_by": "jim",
|
1109
|
+
"priority": "medium",
|
1110
|
+
},
|
1111
|
+
remove_tags=["irs_2023", "personal"],
|
1112
|
+
)
|
1113
|
+
"""
|
1114
|
+
input = UpdateRequest(
|
1115
|
+
id=id,
|
1116
|
+
folder=folder,
|
1117
|
+
add_metadata=add_metadata,
|
1118
|
+
remove_metadata=remove_metadata,
|
1119
|
+
metadata=metadata,
|
1120
|
+
add_tags=add_tags,
|
1121
|
+
remove_tags=remove_tags,
|
1122
|
+
tags=tags,
|
1123
|
+
parent_id=parent_id,
|
1124
|
+
updated_at=updated_at,
|
1125
|
+
bucket_id=bucket_id,
|
1126
|
+
)
|
1127
|
+
return self.request.post("v1/update", UpdateResult, data=input.model_dump(exclude_none=True))
|
1128
|
+
|
1129
|
+
def share_link_create(
|
1130
|
+
self, links: List[ShareLinkCreateItem], bucket_id: Optional[str] = None
|
1131
|
+
) -> PangeaResponse[ShareLinkCreateResult]:
|
1132
|
+
"""
|
1133
|
+
Create share links
|
1134
|
+
|
1135
|
+
Create a share link.
|
1136
|
+
|
1137
|
+
OperationId: share_post_v1_share_link_create
|
1138
|
+
|
1139
|
+
Args:
|
1140
|
+
links (List[ShareLinkCreateItem]):
|
1141
|
+
bucket_id (str, optional): The bucket to use, if not the default.
|
1142
|
+
|
1143
|
+
Returns:
|
1144
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
1145
|
+
|
1146
|
+
Examples:
|
1147
|
+
response = share.share_link_create(
|
1148
|
+
links=[
|
1149
|
+
{
|
1150
|
+
targets: ["pos_3djfmzg2db4c6donarecbyv5begtj2bm"],
|
1151
|
+
link_type: LinkType.DOWNLOAD,
|
1152
|
+
authenticators: [
|
1153
|
+
{
|
1154
|
+
"auth_type": AuthenticatorType.PASSWORD,
|
1155
|
+
"auth_context": "my_fav_Pa55word",
|
1156
|
+
}
|
1157
|
+
],
|
1158
|
+
}
|
1159
|
+
],
|
1160
|
+
)
|
1161
|
+
"""
|
1162
|
+
input = ShareLinkCreateRequest(links=links, bucket_id=bucket_id)
|
1163
|
+
return self.request.post(
|
1164
|
+
"v1/share/link/create", ShareLinkCreateResult, data=input.model_dump(exclude_none=True)
|
1165
|
+
)
|
1166
|
+
|
1167
|
+
def share_link_get(self, id: str) -> PangeaResponse[ShareLinkGetResult]:
|
1168
|
+
"""
|
1169
|
+
Get share link
|
1170
|
+
|
1171
|
+
Get a share link.
|
1172
|
+
|
1173
|
+
OperationId: share_post_v1_share_link_get
|
1174
|
+
|
1175
|
+
Args:
|
1176
|
+
id (str, optional): The ID of a share link.
|
1177
|
+
|
1178
|
+
Returns:
|
1179
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
1180
|
+
|
1181
|
+
Examples:
|
1182
|
+
response = share.share_link_get(
|
1183
|
+
id="psl_3djfmzg2db4c6donarecbyv5begtj2bm"
|
1184
|
+
)
|
1185
|
+
"""
|
1186
|
+
input = ShareLinkGetRequest(id=id)
|
1187
|
+
return self.request.post("v1/share/link/get", ShareLinkGetResult, data=input.model_dump(exclude_none=True))
|
1188
|
+
|
1189
|
+
def share_link_list(
|
1190
|
+
self,
|
1191
|
+
filter: Optional[Union[Dict[str, str], FilterShareLinkList]] = None,
|
1192
|
+
last: Optional[str] = None,
|
1193
|
+
order: Optional[ItemOrder] = None,
|
1194
|
+
order_by: Optional[ShareLinkOrderBy] = None,
|
1195
|
+
size: Optional[int] = None,
|
1196
|
+
bucket_id: Optional[str] = None,
|
1197
|
+
) -> PangeaResponse[ShareLinkListResult]:
|
1198
|
+
"""
|
1199
|
+
List share links
|
1200
|
+
|
1201
|
+
Look up share links by filter options.
|
1202
|
+
|
1203
|
+
OperationId: share_post_v1_share_link_list
|
1204
|
+
|
1205
|
+
Args:
|
1206
|
+
filter (Union[Dict[str, str], ShareLinkListFilter], optional):
|
1207
|
+
last (str, optional): Reflected value from a previous response to obtain the next page of results.
|
1208
|
+
order (ItemOrder, optional): Order results asc(ending) or desc(ending).
|
1209
|
+
order_by (ItemOrderBy, optional): Which field to order results by.
|
1210
|
+
size (int, optional): Maximum results to include in the response.
|
1211
|
+
bucket_id (str, optional): The bucket to use, if not the default.
|
1212
|
+
|
1213
|
+
Returns:
|
1214
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
1215
|
+
|
1216
|
+
Examples:
|
1217
|
+
response = share.share_link_list()
|
1218
|
+
"""
|
1219
|
+
input = ShareLinkListRequest(
|
1220
|
+
filter=filter, last=last, order=order, order_by=order_by, size=size, bucket_id=bucket_id
|
1221
|
+
)
|
1222
|
+
return self.request.post("v1/share/link/list", ShareLinkListResult, data=input.model_dump(exclude_none=True))
|
1223
|
+
|
1224
|
+
def share_link_delete(
|
1225
|
+
self, ids: List[str], bucket_id: Optional[str] = None
|
1226
|
+
) -> PangeaResponse[ShareLinkDeleteResult]:
|
1227
|
+
"""
|
1228
|
+
Delete share links
|
1229
|
+
|
1230
|
+
Delete share links.
|
1231
|
+
|
1232
|
+
OperationId: share_post_v1_share_link_delete
|
1233
|
+
|
1234
|
+
Args:
|
1235
|
+
ids (List[str]): list of the share link's id to delete
|
1236
|
+
bucket_id (str, optional): The bucket to use, if not the default
|
1237
|
+
|
1238
|
+
Returns:
|
1239
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
1240
|
+
|
1241
|
+
Examples:
|
1242
|
+
response = share.share_link_delete(
|
1243
|
+
ids=["psl_3djfmzg2db4c6donarecbyv5begtj2bm"]
|
1244
|
+
)
|
1245
|
+
"""
|
1246
|
+
input = ShareLinkDeleteRequest(ids=ids, bucket_id=bucket_id)
|
1247
|
+
return self.request.post(
|
1248
|
+
"v1/share/link/delete", ShareLinkDeleteResult, data=input.model_dump(exclude_none=True)
|
1249
|
+
)
|
1250
|
+
|
1251
|
+
def share_link_send(
|
1252
|
+
self, links: List[ShareLinkSendItem], sender_email: str, sender_name: Optional[str] = None
|
1253
|
+
) -> PangeaResponse[ShareLinkSendResult]:
|
1254
|
+
"""
|
1255
|
+
Send share links
|
1256
|
+
|
1257
|
+
Send a secure share-link notification to a set of email addresses. The
|
1258
|
+
notification email will contain an Open button that the recipient can
|
1259
|
+
use to follow the secured share-link to authenticate and then access the
|
1260
|
+
shared content.
|
1261
|
+
|
1262
|
+
OperationId: share_post_v1_share_link_send
|
1263
|
+
|
1264
|
+
Args:
|
1265
|
+
sender_email: An email address.
|
1266
|
+
|
1267
|
+
Returns:
|
1268
|
+
A PangeaResponse. Available response fields can be found in our [API documentation](https://pangea.cloud/docs/api/share).
|
1269
|
+
|
1270
|
+
Examples:
|
1271
|
+
response = share.share_link_send(
|
1272
|
+
links=[ShareLinkSendItem(id=link.id, email="foo@example.org")],
|
1273
|
+
sender_email="sender@example.org",
|
1274
|
+
)
|
1275
|
+
"""
|
1276
|
+
|
1277
|
+
input = ShareLinkSendRequest(links=links, sender_email=sender_email, sender_name=sender_name)
|
1278
|
+
return self.request.post("v1/share/link/send", ShareLinkSendResult, data=input.model_dump(exclude_none=True))
|