models.py
77.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
# -*- coding: utf-8 -*-
"""
oss2.models
~~~~~~~~~~
该模块包含Python SDK API接口所需要的输入参数以及返回值类型。
"""
from . import utils
from .utils import http_to_unixtime, make_progress_adapter, make_crc_adapter, b64encode_as_string, b64decode_from_string
from .exceptions import ClientError, InconsistentError
from .compat import urlunquote, to_string, urlquote
from .select_response import SelectResponseAdapter
from .headers import *
import json
import logging
import copy
import struct
from requests.structures import CaseInsensitiveDict
logger = logging.getLogger(__name__)
class PartInfo(object):
"""表示分片信息的文件。
该文件既用于 :func:`list_parts <oss2.Bucket.list_parts>` 的输出,也用于 :func:`complete_multipart_upload
<oss2.Bucket.complete_multipart_upload>` 的输入。
:param int part_number: 分片号
:param str etag: 分片的ETag
:param int size: 分片的大小。用在 `list_parts` 的结果里,也用与分片对象做crc combine得到整个对象crc64值
:param int last_modified: 该分片最后修改的时间戳,类型为int。参考 :ref:`unix_time`
:param int part_crc: 该分片的crc64值
"""
def __init__(self, part_number, etag, size=None, last_modified=None, part_crc=None):
self.part_number = part_number
self.etag = etag
self.size = size
self.last_modified = last_modified
self.part_crc = part_crc
class ContentCryptoMaterial(object):
def __init__(self, cipher, wrap_alg, encrypted_key=None, encrypted_iv=None, mat_desc=None):
self.cipher = cipher
self.cek_alg = cipher.alg
self.wrap_alg = wrap_alg
self.encrypted_key = encrypted_key
self.encrypted_iv = encrypted_iv
self.mat_desc = mat_desc
self.deprecated = False
def to_object_meta(self, headers=None, multipart_upload_context=None):
if not isinstance(headers, CaseInsensitiveDict):
headers = CaseInsensitiveDict(headers)
if 'content-md5' in headers:
headers[OSS_CLIENT_SIDE_ENCRYPTION_UNENCRYPTED_CONTENT_MD5] = headers['content-md5']
del headers['content-md5']
if 'content-length' in headers:
headers[OSS_CLIENT_SIDE_ENCRYPTION_UNENCRYPTED_CONTENT_LENGTH] = headers['content-length']
del headers['content-length']
headers[OSS_CLIENT_SIDE_ENCRYPTION_KEY] = b64encode_as_string(self.encrypted_key)
headers[OSS_CLIENT_SIDE_ENCRYPTION_START] = b64encode_as_string(self.encrypted_iv)
headers[OSS_CLIENT_SIDE_ENCRYPTION_CEK_ALG] = self.cek_alg
headers[OSS_CLIENT_SIDE_ENCRYPTION_WRAP_ALG] = self.wrap_alg
if multipart_upload_context and multipart_upload_context.data_size and multipart_upload_context.part_size:
headers[OSS_CLIENT_SIDE_ENCRYPTION_DATA_SIZE] = str(multipart_upload_context.data_size)
headers[OSS_CLIENT_SIDE_ENCRYPTION_PART_SIZE] = str(multipart_upload_context.part_size)
if self.mat_desc:
headers[OSS_CLIENT_SIDE_ENCRYTPION_MATDESC] = json.dumps(self.mat_desc)
return headers
def from_object_meta(self, headers):
if not isinstance(headers, CaseInsensitiveDict):
headers = CaseInsensitiveDict(headers)
if DEPRECATED_CLIENT_SIDE_ENCRYPTION_KEY in headers:
self.deprecated = True
if self.deprecated:
undecode_encrypted_key = _hget(headers, DEPRECATED_CLIENT_SIDE_ENCRYPTION_KEY)
undecode_encrypted_iv = _hget(headers, DEPRECATED_CLIENT_SIDE_ENCRYPTION_START)
cek_alg = _hget(headers, DEPRECATED_CLIENT_SIDE_ENCRYPTION_CEK_ALG)
wrap_alg = _hget(headers, DEPRECATED_CLIENT_SIDE_ENCRYPTION_WRAP_ALG)
mat_desc = _hget(headers, DEPRECATED_CLIENT_SIDE_ENCRYTPION_MATDESC)
if wrap_alg == "kms":
self.encrypted_key = undecode_encrypted_key
self.encrypted_iv = undecode_encrypted_iv
wrap_alg = KMS_ALI_WRAP_ALGORITHM
else:
if undecode_encrypted_key:
self.encrypted_key = b64decode_from_string(undecode_encrypted_key)
if undecode_encrypted_iv:
self.encrypted_iv = b64decode_from_string(undecode_encrypted_iv)
wrap_alg = RSA_NONE_OAEPWithSHA1AndMGF1Padding
if cek_alg == utils.AES_GCM:
cek_alg = utils.AES_CTR
else:
undecode_encrypted_key = _hget(headers, OSS_CLIENT_SIDE_ENCRYPTION_KEY)
undecode_encrypted_iv = _hget(headers, OSS_CLIENT_SIDE_ENCRYPTION_START)
if undecode_encrypted_key:
self.encrypted_key = b64decode_from_string(undecode_encrypted_key)
if undecode_encrypted_iv:
self.encrypted_iv = b64decode_from_string(undecode_encrypted_iv)
cek_alg = _hget(headers, OSS_CLIENT_SIDE_ENCRYPTION_CEK_ALG)
wrap_alg = _hget(headers, OSS_CLIENT_SIDE_ENCRYPTION_WRAP_ALG)
mat_desc = _hget(headers, OSS_CLIENT_SIDE_ENCRYTPION_MATDESC)
if mat_desc:
self.mat_desc = json.loads(mat_desc)
if cek_alg and cek_alg != self.cek_alg:
logger.error("CEK algorithm or is inconsistent, object meta: cek_alg:{0}, material: cek_alg:{1}".
format(cek_alg, self.cek_alg))
err_msg = 'Data encryption/decryption algorithm is inconsistent'
raise InconsistentError(err_msg, self)
if wrap_alg and wrap_alg != self.wrap_alg:
logger.error("WRAP algorithm or is inconsistent, object meta: wrap_alg:{0}, material: wrap_alg:{1}".
format(wrap_alg, self.wrap_alg))
err_msg = 'Envelope encryption/decryption algorithm is inconsistent'
raise InconsistentError(err_msg, self)
self.cek_alg = cek_alg
self.wrap_alg = wrap_alg
def is_unencrypted(self):
if not self.encrypted_key and not self.encrypted_iv and not self.cek_alg and not self.wrap_alg:
return True
else:
return False
class MultipartUploadCryptoContext(object):
def __init__(self, data_size=None, part_size=None, content_crypto_material=None):
self.content_crypto_material = content_crypto_material
self.data_size = data_size
self.part_size = part_size
def _hget(headers, key, converter=lambda x: x):
if key in headers:
return converter(headers[key])
else:
return None
def _get_etag(headers):
return _hget(headers, 'etag', lambda x: x.strip('"'))
class RequestResult(object):
def __init__(self, resp):
#: HTTP响应
self.resp = resp
#: HTTP状态码
self.status = resp.status
#: HTTP头
self.headers = resp.headers
#: 请求ID,用于跟踪一个OSS请求。提交工单时,最后能够提供请求ID
self.request_id = resp.request_id
self.versionid = _hget(self.headers, 'x-oss-version-id')
self.delete_marker = _hget(self.headers, 'x-oss-delete-marker', bool)
class HeadObjectResult(RequestResult):
def __init__(self, resp):
super(HeadObjectResult, self).__init__(resp)
#: 文件类型,可以是'Normal'、'Multipart'、'Appendable'等
self.object_type = _hget(self.headers, OSS_OBJECT_TYPE)
#: 文件最后修改时间,类型为int。参考 :ref:`unix_time` 。
self.last_modified = _hget(self.headers, 'last-modified', http_to_unixtime)
#: 文件的MIME类型
self.content_type = _hget(self.headers, 'content-type')
#: Content-Length,可能是None。
self.content_length = _hget(self.headers, 'content-length', int)
#: HTTP ETag
self.etag = _get_etag(self.headers)
#: 文件 server_crc
self._server_crc = _hget(self.headers, 'x-oss-hash-crc64ecma', int)
@property
def server_crc(self):
return self._server_crc
class GetSelectObjectMetaResult(HeadObjectResult):
def __init__(self, resp):
super(GetSelectObjectMetaResult, self).__init__(resp)
self.select_resp = SelectResponseAdapter(resp, None, None, False)
for data in self.select_resp: # waiting the response body to finish
pass
self.csv_rows = self.select_resp.rows # to be compatible with previous version.
self.csv_splits = self.select_resp.splits # to be compatible with previous version.
self.rows = self.csv_rows
self.splits = self.csv_splits
class GetObjectMetaResult(RequestResult):
def __init__(self, resp):
super(GetObjectMetaResult, self).__init__(resp)
#: 文件最后修改时间,类型为int。参考 :ref:`unix_time` 。
self.last_modified = _hget(self.headers, 'last-modified', http_to_unixtime)
#: Content-Length,文件大小,类型为int。
self.content_length = _hget(self.headers, 'content-length', int)
#: HTTP ETag
self.etag = _get_etag(self.headers)
class GetSymlinkResult(RequestResult):
def __init__(self, resp):
super(GetSymlinkResult, self).__init__(resp)
#: 符号连接的目标文件
self.target_key = urlunquote(_hget(self.headers, OSS_SYMLINK_TARGET))
class GetObjectResult(HeadObjectResult):
def __init__(self, resp, progress_callback=None, crc_enabled=False, crypto_provider=None, discard=0):
super(GetObjectResult, self).__init__(resp)
self.__crc_enabled = crc_enabled
self.__crypto_provider = crypto_provider
self.content_range = _hget(resp.headers, 'Content-Range')
if self.content_range:
byte_range = self._parse_range_str(self.content_range)
if progress_callback:
self.stream = make_progress_adapter(self.resp, progress_callback, self.content_length)
else:
self.stream = self.resp
if self.__crc_enabled:
self.stream = make_crc_adapter(self.stream, discard=discard)
if self.__crypto_provider:
content_crypto_material = ContentCryptoMaterial(self.__crypto_provider.cipher,
self.__crypto_provider.wrap_alg)
content_crypto_material.from_object_meta(resp.headers)
if content_crypto_material.is_unencrypted():
logger.info("The object is not encrypted, use crypto provider is not recommended")
else:
crypto_provider = self.__crypto_provider
if content_crypto_material.mat_desc != self.__crypto_provider.mat_desc:
logger.warn("The material description of the object and the provider is inconsistent")
encryption_materials = self.__crypto_provider.get_encryption_materials(
content_crypto_material.mat_desc)
if encryption_materials:
crypto_provider = self.__crypto_provider.reset_encryption_materials(encryption_materials)
else:
raise ClientError(
'There is no encryption materials match the material description of the object')
plain_key = crypto_provider.decrypt_encrypted_key(content_crypto_material.encrypted_key)
if content_crypto_material.deprecated:
if content_crypto_material.wrap_alg == KMS_ALI_WRAP_ALGORITHM:
plain_counter = int(
crypto_provider.decrypt_encrypted_iv(content_crypto_material.encrypted_iv, True))
else:
plain_counter = int(crypto_provider.decrypt_encrypted_iv(content_crypto_material.encrypted_iv))
else:
plain_iv = crypto_provider.decrypt_encrypted_iv(content_crypto_material.encrypted_iv)
offset = 0
if self.content_range:
start, end = crypto_provider.adjust_range(byte_range[0], byte_range[1])
offset = content_crypto_material.cipher.calc_offset(start)
cipher = copy.copy(content_crypto_material.cipher)
if content_crypto_material.deprecated:
cipher.initial_by_counter(plain_key, plain_counter + offset)
else:
cipher.initialize(plain_key, plain_iv, offset)
self.stream = crypto_provider.make_decrypt_adapter(self.stream, cipher, discard)
else:
if OSS_CLIENT_SIDE_ENCRYPTION_KEY in resp.headers or DEPRECATED_CLIENT_SIDE_ENCRYPTION_KEY in resp.headers:
logger.warn(
"Using Bucket to get an encrypted object will return raw data, please confirm if you really want to do this")
@staticmethod
def _parse_range_str(content_range):
# :param str content_range: sample 'bytes 0-128/1024'
range_data = (content_range.split(' ', 2)[1]).split('/', 2)[0]
range_start, range_end = range_data.split('-', 2)
return int(range_start), int(range_end)
def read(self, amt=None):
return self.stream.read(amt)
def close(self):
self.resp.response.close()
def __iter__(self):
return iter(self.stream)
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
@property
def client_crc(self):
if self.__crc_enabled:
return self.stream.crc
else:
return None
class SelectObjectResult(HeadObjectResult):
def __init__(self, resp, progress_callback=None, crc_enabled=False):
super(SelectObjectResult, self).__init__(resp)
self.__crc_enabled = crc_enabled
self.select_resp = SelectResponseAdapter(resp, progress_callback, None, enable_crc = self.__crc_enabled)
def read(self):
return self.select_resp.read()
def close(self):
self.resp.response.close()
def __iter__(self):
return iter(self.select_resp)
def __next__(self):
return self.select_resp.next()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
class PutObjectResult(RequestResult):
def __init__(self, resp):
super(PutObjectResult, self).__init__(resp)
#: HTTP ETag
self.etag = _get_etag(self.headers)
#: 文件上传后,OSS上文件的CRC64值
self.crc = _hget(resp.headers, OSS_HASH_CRC64_ECMA, int)
class AppendObjectResult(RequestResult):
def __init__(self, resp):
super(AppendObjectResult, self).__init__(resp)
#: HTTP ETag
self.etag = _get_etag(self.headers)
#: 本次追加写完成后,OSS上文件的CRC64值
self.crc = _hget(resp.headers, OSS_HASH_CRC64_ECMA, int)
#: 下次追加写的偏移
self.next_position = _hget(resp.headers, OSS_NEXT_APPEND_POSITION, int)
class BatchDeleteObjectVersion(object):
def __init__(self, key=None, versionid=None):
self.key = key or ''
self.versionid = versionid or ''
class BatchDeleteObjectVersionList(object):
def __init__(self, object_version_list=None):
self.object_version_list = object_version_list or []
def append(self, object_version):
self.object_version_list.append(object_version)
def len(self):
return len(self.object_version_list)
class BatchDeleteObjectVersionResult(object):
def __init__(self, key, versionid=None, delete_marker=None, delete_marker_versionid=None):
self.key = key
self.versionid = versionid or ''
self.delete_marker = delete_marker or False
self.delete_marker_versionid = delete_marker_versionid or ''
class BatchDeleteObjectsResult(RequestResult):
def __init__(self, resp):
super(BatchDeleteObjectsResult, self).__init__(resp)
#: 已经删除的文件名列表
self.deleted_keys = []
#:已经删除的带版本信息的文件信息列表
self.delete_versions = []
class InitMultipartUploadResult(RequestResult):
def __init__(self, resp):
super(InitMultipartUploadResult, self).__init__(resp)
#: 新生成的Upload ID
self.upload_id = None
# 客户端加密Bucket关于Multipart文件的context
# self.crypto_multipart_context = None
class ListObjectsResult(RequestResult):
def __init__(self, resp):
super(ListObjectsResult, self).__init__(resp)
#: True表示还有更多的文件可以罗列;False表示已经列举完毕。
self.is_truncated = False
#: 下一次罗列的分页标记符,即,可以作为 :func:`list_objects <oss2.Bucket.list_objects>` 的 `marker` 参数。
self.next_marker = ''
#: 本次罗列得到的文件列表。其中元素的类型为 :class:`SimplifiedObjectInfo` 。
self.object_list = []
#: 本次罗列得到的公共前缀列表,类型为str列表。
self.prefix_list = []
class ListObjectsV2Result(RequestResult):
def __init__(self, resp):
super(ListObjectsV2Result, self).__init__(resp)
#: True表示还有更多的文件可以罗列;False表示已经列举完毕。
self.is_truncated = False
#: 下次罗列操作携带的token
self.next_continuation_token = ''
#: 本次罗列得到的文件列表。其中元素的类型为 :class:`SimplifiedObjectInfo` 。
self.object_list = []
#: 本次罗列得到的公共前缀列表,类型为str列表。
self.prefix_list = []
class SimplifiedObjectInfo(object):
def __init__(self, key, last_modified, etag, type, size, storage_class, owner=None):
#: 文件名,或公共前缀名。
self.key = key
#: 文件的最后修改时间
self.last_modified = last_modified
#: HTTP ETag
self.etag = etag
#: 文件类型
self.type = type
#: 文件大小
self.size = size
#: 文件的存储类别,是一个字符串。
self.storage_class = storage_class
#: owner信息, 类型为: class:`Owner <oss2.models.Owner>`
self.owner = owner
def is_prefix(self):
"""如果是公共前缀,返回True;是文件,则返回False"""
return self.last_modified is None
OBJECT_ACL_DEFAULT = 'default'
OBJECT_ACL_PRIVATE = 'private'
OBJECT_ACL_PUBLIC_READ = 'public-read'
OBJECT_ACL_PUBLIC_READ_WRITE = 'public-read-write'
class GetObjectAclResult(RequestResult):
def __init__(self, resp):
super(GetObjectAclResult, self).__init__(resp)
#: 文件的ACL,其值可以是 `OBJECT_ACL_DEFAULT`、`OBJECT_ACL_PRIVATE`、`OBJECT_ACL_PUBLIC_READ`或
#: `OBJECT_ACL_PUBLIC_READ_WRITE`
self.acl = ''
class SimplifiedBucketInfo(object):
""":func:`list_buckets <oss2.Service.list_objects>` 结果中的单个元素类型。"""
def __init__(self, name, location, creation_date, extranet_endpoint, intranet_endpoint, storage_class):
#: Bucket名
self.name = name
#: Bucket的区域
self.location = location
#: Bucket的创建时间,类型为int。参考 :ref:`unix_time`。
self.creation_date = creation_date
#: Bucket访问的外网域名
self.extranet_endpoint = extranet_endpoint
#: 同区域ECS访问Bucket的内网域名
self.intranet_endpoint = intranet_endpoint
#: Bucket存储类型,支持“Standard”、“IA”、“Archive”、“ColdArchive”
self.storage_class = storage_class
class ListBucketsResult(RequestResult):
def __init__(self, resp):
super(ListBucketsResult, self).__init__(resp)
#: True表示还有更多的Bucket可以罗列;False表示已经列举完毕。
self.is_truncated = False
#: 下一次罗列的分页标记符,即,可以作为 :func:`list_buckets <oss2.Service.list_buckets>` 的 `marker` 参数。
self.next_marker = ''
#: 得到的Bucket列表,类型为 :class:`SimplifiedBucketInfo` 。
self.buckets = []
class MultipartUploadInfo(object):
def __init__(self, key, upload_id, initiation_date):
#: 文件名
self.key = key
#: 分片上传ID
self.upload_id = upload_id
#: 分片上传初始化的时间,类型为int。参考 :ref:`unix_time`
self.initiation_date = initiation_date
def is_prefix(self):
"""如果是公共前缀则返回True"""
return self.upload_id is None
class ListMultipartUploadsResult(RequestResult):
def __init__(self, resp):
super(ListMultipartUploadsResult, self).__init__(resp)
#: True表示还有更多的为完成分片上传可以罗列;False表示已经列举完毕。
self.is_truncated = False
#: 文件名分页符
self.next_key_marker = ''
#: 分片上传ID分页符
self.next_upload_id_marker = ''
#: 分片上传列表。类型为`MultipartUploadInfo`列表。
self.upload_list = []
#: 公共前缀列表。类型为str列表。
self.prefix_list = []
class ListPartsResult(RequestResult):
def __init__(self, resp):
super(ListPartsResult, self).__init__(resp)
# True表示还有更多的Part可以罗列;False表示已经列举完毕。
self.is_truncated = False
# 下一个分页符
self.next_marker = ''
# 罗列出的Part信息,类型为 `PartInfo` 列表。
self.parts = []
BUCKET_ACL_PRIVATE = 'private'
BUCKET_ACL_PUBLIC_READ = 'public-read'
BUCKET_ACL_PUBLIC_READ_WRITE = 'public-read-write'
BUCKET_STORAGE_CLASS_STANDARD = 'Standard'
BUCKET_STORAGE_CLASS_IA = 'IA'
BUCKET_STORAGE_CLASS_ARCHIVE = 'Archive'
BUCKET_STORAGE_CLASS_COLD_ARCHIVE = "ColdArchive"
BUCKET_DATA_REDUNDANCY_TYPE_LRS = "LRS"
BUCKET_DATA_REDUNDANCY_TYPE_ZRS = "ZRS"
REDIRECT_TYPE_MIRROR = 'Mirror'
REDIRECT_TYPE_EXTERNAL = 'External'
REDIRECT_TYPE_INTERNAL = 'Internal'
REDIRECT_TYPE_ALICDN = 'AliCDN'
PAYER_BUCKETOWNER = 'BucketOwner'
PAYER_REQUESTER = 'Requester'
class GetBucketAclResult(RequestResult):
def __init__(self, resp):
super(GetBucketAclResult, self).__init__(resp)
#: Bucket的ACL,其值可以是 `BUCKET_ACL_PRIVATE`、`BUCKET_ACL_PUBLIC_READ`或`BUCKET_ACL_PUBLIC_READ_WRITE`。
self.acl = ''
class GetBucketLocationResult(RequestResult):
def __init__(self, resp):
super(GetBucketLocationResult, self).__init__(resp)
#: Bucket所在的数据中心
self.location = ''
class BucketLogging(object):
"""Bucket日志配置信息。
:param str target_bucket: 存储日志到这个Bucket。
:param str target_prefix: 生成的日志文件名加上该前缀。
"""
def __init__(self, target_bucket, target_prefix):
self.target_bucket = target_bucket
self.target_prefix = target_prefix
class GetBucketLoggingResult(RequestResult, BucketLogging):
def __init__(self, resp):
RequestResult.__init__(self, resp)
BucketLogging.__init__(self, '', '')
class BucketCreateConfig(object):
def __init__(self, storage_class, data_redundancy_type=None):
self.storage_class = storage_class
self.data_redundancy_type = data_redundancy_type
class BucketStat(object):
def __init__(self, storage_size_in_bytes, object_count, multi_part_upload_count):
self.storage_size_in_bytes = storage_size_in_bytes
self.object_count = object_count
self.multi_part_upload_count = multi_part_upload_count
class AccessControlList(object):
def __init__(self, grant):
self.grant = grant
class Owner(object):
def __init__(self, display_name, owner_id):
self.display_name = display_name
self.id = owner_id
class BucketInfo(object):
def __init__(self, name=None, owner=None, location=None, storage_class=None, intranet_endpoint=None,
extranet_endpoint=None, creation_date=None, acl=None, data_redundancy_type=None, comment=None,
bucket_encryption_rule=None, versioning_status=None):
self.name = name
self.owner = owner
self.location = location
self.storage_class = storage_class
self.intranet_endpoint = intranet_endpoint
self.extranet_endpoint = extranet_endpoint
self.creation_date = creation_date
self.acl = acl
self.data_redundancy_type = data_redundancy_type
self.comment = comment
self.bucket_encryption_rule = bucket_encryption_rule
self.versioning_status = versioning_status
class GetBucketStatResult(RequestResult, BucketStat):
def __init__(self, resp):
RequestResult.__init__(self, resp)
BucketStat.__init__(self, 0, 0, 0)
class GetBucketInfoResult(RequestResult, BucketInfo):
def __init__(self, resp):
RequestResult.__init__(self, resp)
BucketInfo.__init__(self)
class BucketReferer(object):
"""Bucket防盗链设置。
:param bool allow_empty_referer: 是否允许空的Referer。
:param referers: Referer列表,每个元素是一个str。
"""
def __init__(self, allow_empty_referer, referers):
self.allow_empty_referer = allow_empty_referer
self.referers = referers
class GetBucketRefererResult(RequestResult, BucketReferer):
def __init__(self, resp):
RequestResult.__init__(self, resp)
BucketReferer.__init__(self, False, [])
class Condition(object):
""" 匹配规则
:父节点: class `RoutingRule <oss2.models.RoutingRule>`
:param key_prefix_equals: 匹配object的前缀,
:type key_prefix_equals: string str
:param http_err_code_return_equals: 匹配访问object时返回的status。
:type http_err_code_return_equals: int
:param include_header_list: 匹配指定的header
:type include_header_list: list of :class:`ConditionInlcudeHeader`
"""
def __init__(self, key_prefix_equals=None, http_err_code_return_equals=None, include_header_list=None):
if (include_header_list is not None):
if not isinstance(include_header_list, list):
raise ClientError('class of include_header should be list')
if len(include_header_list) > 5:
raise ClientError('capacity of include_header_list should not > 5, please check!')
self.key_prefix_equals = key_prefix_equals
self.http_err_code_return_equals = http_err_code_return_equals
self.include_header_list = include_header_list or []
class ConditionInlcudeHeader(object):
""" 指定匹配的header
:父节点: class `Condition <oss2.models.Condition>`
:param key: header key
:type key: str
:param key: header value
:type key: str
"""
def __init__(self, key=None, equals= None):
self.key = key
self.equals = equals
class Redirect(object):
"""匹配规则之后执行的动作
:父节点: class `RoutingRule <oss2.models.RoutingRule>`
:param redirect_type: 跳转类型, 取值为Mirror, External, Internal, AliCDN其中一个。
:type redirect_type: class: str
:param pass_query_string: 执行跳转或者镜像回源时,是否要携带发起请求的请求参数,默认false。
:type pass_query_string: bool
:param replace_key_with: Redirect的时候object name将替换成这个值,可以支持变量(目前支持的变量是${key}
当RedirectType为Internal, External或者AliCDN时有效。
:type replace_key_with: str
:param replace_key_prefix_with: Redirect的时候object name的前缀将替换成这个值。如果前缀为空则将这个字符串插入在object namde的最前面。
当RedirectType为Internal, External或者AliCDN时有效。
:type replace_key_prefix_with: str
:param proto: 跳转时的协议,只能取值为http或者https。
当RedirectType为External或者AliCDN时有效。
:type proto: class: str
:param host_name: 跳转时的域名
当RedirectType为External或者AliCDN时有效。
:type host_name: str
:param http_redirect_code: 跳转时返回的状态码,取值为301、302或307。
当RedirectType为External或者AliCDN时有效。
:type http_redirect_code: int (HTTP状态码)
:mirror相关当参数只有当RedirectType为Mirror时有效。
:param mirror_url: 镜像回源的源站地址,
:type mirror_url: str
:param mirror_url_slave: 镜像回源的备站地址
:type mirror_url_slave: str
:param mirror_url_probe: 主备切换模式的探测url,这个url需要代表主源站的健康程度,mirror_url_slave指定时,此项必须指定。
:type mirror_url_probe: str
:param mirror_pass_query_string: 作用同pass_query_string,默认false。
:type mirror_pass_query_string: bool
:param mirror_follow_redirect: 如果镜像回源获取的结果是3xx,是否要继续跳转到指定的Location获取数据。默认true。
:type mirror_follow_redirect: bool
:param mirror_check_md5: 是否要检查回源body的md5, 默认false。
:type mirror_check_md5: bool
:param mirror_headers: 指定匹配此规则后执行的动作。
:type mirror_headers: class:`RedirectMirrorHeaders <oss2.models.RedirectMirrorHeaders>`
"""
def __init__(self, redirect_type=None, pass_query_string= None, replace_key_with=None, replace_key_prefix_with=None,
proto=None, host_name=None, http_redirect_code=None, mirror_url=None, mirror_url_slave=None,
mirror_url_probe=None, mirror_pass_query_string=None, mirror_follow_redirect=None,
mirror_check_md5=None, mirror_headers=None):
if redirect_type not in [REDIRECT_TYPE_MIRROR, REDIRECT_TYPE_EXTERNAL, REDIRECT_TYPE_INTERNAL, REDIRECT_TYPE_ALICDN]:
raise ClientError('redirect_type must be Internal, External, Mirror or AliCDN.')
if redirect_type == REDIRECT_TYPE_INTERNAL:
if any((host_name, proto, http_redirect_code)):
raise ClientError('host_name, proto, http_redirect_code must be empty when redirect_type is Internal.')
if redirect_type in [REDIRECT_TYPE_EXTERNAL, REDIRECT_TYPE_ALICDN]:
if http_redirect_code is not None:
if http_redirect_code < 300 or http_redirect_code > 399:
raise ClientError("http_redirect_code must be a valid HTTP 3xx status code.")
if redirect_type in [REDIRECT_TYPE_EXTERNAL, REDIRECT_TYPE_ALICDN, REDIRECT_TYPE_INTERNAL]:
if all((replace_key_with, replace_key_prefix_with)):
raise ClientError("replace_key_with or replace_key_prefix_with only choose one.")
elif redirect_type == REDIRECT_TYPE_MIRROR:
if any((proto, host_name, replace_key_with, replace_key_prefix_with, http_redirect_code)):
raise ClientError('host_name, replace_key_with, replace_key_prefix_with, http_redirect_code and proto must be empty when redirect_type is Mirror.')
if mirror_url is None:
raise ClientError('mirror_url should not be None when redirect_type is Mirror.')
if (not mirror_url.startswith('http://') and not mirror_url.startswith('https://')) or not mirror_url.endswith('/'):
raise ClientError(r'mirror_url is invalid, should startwith "http://" or "https://", and endwith "/"')
if mirror_url_slave is not None:
if mirror_url_probe is None:
raise ClientError('mirror_url_probe should not be none when mirror_url_slave is indicated')
if (not mirror_url_slave.startswith('http://') and not mirror_url_slave.startswith('https://')) or not mirror_url_slave.endswith('/'):
raise ClientError(r'mirror_url_salve is invalid, should startwith "http://" or "https://", and endwith "/"')
self.redirect_type = redirect_type
self.pass_query_string = pass_query_string
self.replace_key_with = replace_key_with
self.replace_key_prefix_with = replace_key_prefix_with
self.proto = proto
self.host_name = host_name
self.http_redirect_code = http_redirect_code
self.mirror_url = mirror_url
self.mirror_url_slave = mirror_url_slave
self.mirror_url_probe = mirror_url_probe
self.mirror_pass_query_string = mirror_pass_query_string
self.mirror_check_md5 = mirror_check_md5
self.mirror_follow_redirect = mirror_follow_redirect
self.mirror_headers = mirror_headers
class RedirectMirrorHeaders(object):
"""指定镜像回源时携带的header
:父节点: class `Redirect <oss2.models.Redirect>`
:param pass_all: 是否透传请求中所有的header(除了保留的几个header以及以oss-/x-oss-/x-drs-开头的header)到源站。默认false
:type pass_all: bool
:param pass_list: 透传指定的header到源站,最多10个,只有在RedirectType为Mirror时生效
:type pass_list: list of str
:param remove_list: 禁止透传指定的header到源站,这个字段可以重复,最多10个
:type remove_list: list of str
:param set_list: 设置一个header传到源站,不管请求中是否携带这些指定的header,回源时都会设置这些header。
该容器可以重复,最多10组。只有在RedirectType为Mirror时生效。
:type set_list: list of :class:`MirrorHeadersSet <oss2.models.MirrorHeadersSet>`
"""
def __init__(self,pass_all=None, pass_list=None, remove_list=None, set_list=None):
if pass_list is not None:
if not isinstance(pass_list, list):
raise ClientError('The type of pass_list should be list.')
if len(pass_list) > 10:
raise ClientError('The capacity of pass_list should not > 10!')
if remove_list is not None:
if not isinstance(remove_list, list):
raise ClientError('The type of remove_list should be list.')
if len(remove_list) > 10:
raise ClientError('The capacity of remove_list should not > 10!')
if set_list is not None:
if not isinstance(set_list, list):
raise ClientError('The type of set_list should be list.')
if len(set_list) > 10:
raise ClientError('The capacity of set_list should not > 10!')
self.pass_all = pass_all
self.pass_list = pass_list or []
self.remove_list = remove_list or []
self.set_list = set_list or []
class MirrorHeadersSet(object):
"""父节点: class `RedirectMirrorHeaders <oss2.models.RedirectMirrorHeaders>`
:param key:设置header的key,最多1024个字节,字符集与Pass相同。只有在RedirectType为Mirror时生效。
:type key: str
:param value:设置header的value,最多1024个字节,不能出现”\r\n” 。只有在RedirectType为Mirror时生效。
:type value: str
"""
def __init__(self, key=None, value=None):
self.key = key
self.value = value
class RoutingRule(object):
"""设置静态网站托管模式中的跳转规则
:param rule_num: RoutingRule的序号, 必须为正整数
:type rule_num: int
:param condition: 匹配条件
:type condition: class:`Condition <oss2.models.Condition>`
:param redirect: 指定匹配此规则后执行的动作
:type redirect: class:`Redirect <oss2.models.Redirect>`
"""
def __init__(self, rule_num=None, condition=None, redirect=None):
if (rule_num is None) or (not isinstance(rule_num, int)) or (rule_num <= 0):
raise ClientError('rule_num should be positive integer.')
if(condition is None) or (redirect is None):
raise ClientError('condition and redirect should be effective.')
if(redirect.redirect_type == REDIRECT_TYPE_MIRROR) and condition.http_err_code_return_equals != 404:
raise ClientError('http_err_code not match redirect_type, it should be 404!')
self.rule_num = rule_num
self.condition = condition
self.redirect = redirect
class BucketWebsite(object):
"""静态网站托管配置。
:param str index_file: 索引页面文件
:param str error_file: 404页面文件
:param rules : list of class:`RoutingRule <oss2.models.RoutingRule>`
"""
def __init__(self, index_file, error_file, rules=None):
if rules is not None:
if not isinstance(rules, list):
raise ClientError('rules type should be list.')
if len(rules) > 5:
raise ClientError('capacity of rules should not be > 5.')
self.index_file = index_file
self.error_file = error_file
self.rules = rules or []
class GetBucketWebsiteResult(RequestResult, BucketWebsite):
def __init__(self, resp):
RequestResult.__init__(self, resp)
BucketWebsite.__init__(self, '', '', [])
class LifecycleExpiration(object):
"""过期删除操作。
:param days: 表示在文件修改后过了这么多天,就会匹配规则,从而被删除
:type days: int
:param date: 表示在该日期之后,规则就一直生效。即每天都会对符合前缀的文件执行删除操作(如,删除),而不管文件是什么时候生成的。*不建议使用*
:type date: `datetime.date`
:param created_before_date: delete files if their last modified time earlier than created_before_date
:type created_before_date: `datetime.date`
:param expired_detete_marker: 真实文件删除之后是否自动移除删除标记,适用于多版本场景。
:param expired_detete_marker: bool
"""
def __init__(self, days=None, date=None, created_before_date=None, expired_detete_marker=None):
not_none_fields = 0
if days is not None:
not_none_fields += 1
if date is not None:
not_none_fields += 1
if created_before_date is not None:
not_none_fields += 1
if expired_detete_marker is not None:
not_none_fields += 1
if not_none_fields > 1:
raise ClientError('More than one field(days, date and created_before_date, expired_detete_marker) has been specified')
self.days = days
self.date = date
self.created_before_date = created_before_date
self.expired_detete_marker = expired_detete_marker
class AbortMultipartUpload(object):
"""删除parts
:param days: 删除相对最后修改时间days天之后的parts
:param created_before_date: 删除最后修改时间早于created_before_date的parts
"""
def __init__(self, days=None, created_before_date=None):
if days is not None and created_before_date is not None:
raise ClientError('days and created_before_date should not be both specified')
self.days = days
self.created_before_date = created_before_date
class StorageTransition(object):
"""transit objects
:param days: 将相对最后修改时间days天之后的Object转储
:param created_before_date: 将最后修改时间早于created_before_date的对象转储
:param storage_class: 对象转储到OSS的目标存储类型
"""
def __init__(self, days=None, created_before_date=None, storage_class=None):
if days is not None and created_before_date is not None:
raise ClientError('days and created_before_date should not be both specified')
self.days = days
self.created_before_date = created_before_date
self.storage_class = storage_class
class NoncurrentVersionExpiration(object):
"""OSS何时将非当前版本的object删除
:param noncurrent_days: 指定多少天之后删除
:type noncurrent_days: int
"""
def __init__(self, noncurrent_days):
self.noncurrent_days = noncurrent_days
class NoncurrentVersionStorageTransition(object):
"""生命周期内,OSS何时将指定Object的非当前版本转储为IA或者Archive存储类型。
:param noncurrent_days: 多少天之后转存储
:type noncurrent_days: int
"""
def __init__(self, noncurrent_days, storage_class):
self.noncurrent_days = noncurrent_days
self.storage_class = storage_class
class LifecycleRule(object):
"""生命周期规则。
:param id: 规则名
:type id: str
:param prefix: 只有文件名匹配该前缀的文件才适用本规则
:type prefix: str
:param expiration: 过期删除操作。
:type expiration: :class:`LifecycleExpiration`
:param status: 启用还是禁止该规则。可选值为 `LifecycleRule.ENABLED` 或 `LifecycleRule.DISABLED`
:param storage_transitions: 存储类型转换规则
:type storage_transitions: list of class:`StorageTransition <oss2.models.StorageTransition>`
:param tagging: object tagging 规则
:type tagging: :class:`Tagging <oss2.models.StorageTransition>`
:param noncurrent_version_expiration: 指定Object非当前版本生命周期规则的过期属性。适用于多版本场景。
:type noncurrent_version_expiration class:`NoncurrentVersionExpiration <oss2.models.NoncurrentVersionExpiration>`
:param noncurrent_version_sotrage_transitions: 在有效生命周期中,OSS何时将指定Object的非当前版本转储为IA或者Archive存储类型,适用于多版本场景。
:type noncurrent_version_sotrage_transitions: list of class:`NoncurrentVersionStorageTransition <oss2.models.NoncurrentVersionStorageTransition>`
"""
ENABLED = 'Enabled'
DISABLED = 'Disabled'
def __init__(self, id, prefix,
status=ENABLED, expiration=None,
abort_multipart_upload=None,
storage_transitions=None, tagging=None,
noncurrent_version_expiration=None,
noncurrent_version_sotrage_transitions=None):
self.id = id
self.prefix = prefix
self.status = status
self.expiration = expiration
self.abort_multipart_upload = abort_multipart_upload
self.storage_transitions = storage_transitions
self.tagging = tagging
self.noncurrent_version_expiration = noncurrent_version_expiration
self.noncurrent_version_sotrage_transitions = noncurrent_version_sotrage_transitions
class BucketLifecycle(object):
"""Bucket的生命周期配置。
:param rules: 规则列表,
:type rules: list of :class:`LifecycleRule <oss2.models.LifecycleRule>`
"""
def __init__(self, rules=None):
self.rules = rules or []
class GetBucketLifecycleResult(RequestResult, BucketLifecycle):
def __init__(self, resp):
RequestResult.__init__(self, resp)
BucketLifecycle.__init__(self)
class CorsRule(object):
"""CORS(跨域资源共享)规则。
:param allowed_origins: 允许跨域访问的域。
:type allowed_origins: list of str
:param allowed_methods: 允许跨域访问的HTTP方法,如'GET'等。
:type allowed_methods: list of str
:param allowed_headers: 允许跨域访问的HTTP头部。
:type allowed_headers: list of str
"""
def __init__(self,
allowed_origins=None,
allowed_methods=None,
allowed_headers=None,
expose_headers=None,
max_age_seconds=None):
self.allowed_origins = allowed_origins or []
self.allowed_methods = allowed_methods or []
self.allowed_headers = allowed_headers or []
self.expose_headers = expose_headers or []
self.max_age_seconds = max_age_seconds
class BucketCors(object):
def __init__(self, rules=None):
self.rules = rules or []
class GetBucketCorsResult(RequestResult, BucketCors):
def __init__(self, resp):
RequestResult.__init__(self, resp)
BucketCors.__init__(self)
class LiveChannelInfoTarget(object):
"""Live channel中的Target节点,包含目标协议的一些参数。
:param type: 协议,目前仅支持HLS。
:type type: str
:param frag_duration: HLS协议下生成的ts文件的期望时长,单位为秒。
:type frag_duration: int
:param frag_count: HLS协议下m3u8文件里ts文件的数量。
:type frag_count: int"""
def __init__(self,
type = 'HLS',
frag_duration = 5,
frag_count = 3,
playlist_name = ''):
self.type = type
self.frag_duration = frag_duration
self.frag_count = frag_count
self.playlist_name = playlist_name
class LiveChannelInfo(object):
"""Live channel(直播频道)配置。
:param status: 直播频道的状态,合法的值为"enabled"和"disabled"。
:type status: str
:param description: 直播频道的描述信息,最长为128字节。
:type description: str
:param target: 直播频道的推流目标节点,包含目标协议相关的参数。
:type class:`LiveChannelInfoTarget <oss2.models.LiveChannelInfoTarget>`
:param last_modified: 直播频道的最后修改时间,这个字段仅在`ListLiveChannel`时使用。
:type last_modified: int, 参考 :ref:`unix_time`。
:param name: 直播频道的名称。
:type name: str
:param play_url: 播放地址。
:type play_url: str
:param publish_url: 推流地址。
:type publish_url: str"""
def __init__(self,
status = 'enabled',
description = '',
target = LiveChannelInfoTarget(),
last_modified = None,
name = None,
play_url = None,
publish_url = None):
self.status = status
self.description = description
self.target = target
self.last_modified = last_modified
self.name = name
self.play_url = play_url
self.publish_url = publish_url
class LiveChannelList(object):
"""List直播频道的结果。
:param prefix: List直播频道使用的前缀。
:type prefix: str
:param marker: List直播频道使用的marker。
:type marker: str
:param max_keys: List时返回的最多的直播频道的条数。
:type max_keys: int
:param is_truncated: 本次List是否列举完所有的直播频道
:type is_truncated: bool
:param next_marker: 下一次List直播频道使用的marker。
:type marker: str
:param channels: List返回的直播频道列表
:type channels: list,类型为 :class:`LiveChannelInfo`"""
def __init__(self,
prefix = '',
marker = '',
max_keys = 100,
is_truncated = False,
next_marker = ''):
self.prefix = prefix
self.marker = marker
self.max_keys = max_keys
self.is_truncated = is_truncated
self.next_marker = next_marker
self.channels = []
class LiveChannelVideoStat(object):
"""LiveStat中的Video节点。
:param width: 视频的宽度。
:type width: int
:param height: 视频的高度。
:type height: int
:param frame_rate: 帧率。
:type frame_rate: int
:param codec: 编码方式。
:type codec: str
:param bandwidth: 码率。
:type bandwidth: int"""
def __init__(self,
width = 0,
height = 0,
frame_rate = 0,
codec = '',
bandwidth = 0):
self.width = width
self.height = height
self.frame_rate = frame_rate
self.codec = codec
self.bandwidth = bandwidth
class LiveChannelAudioStat(object):
"""LiveStat中的Audio节点。
:param codec: 编码方式。
:type codec: str
:param sample_rate: 采样率。
:type sample_rate: int
:param bandwidth: 码率。
:type bandwidth: int"""
def __init__(self,
codec = '',
sample_rate = 0,
bandwidth = 0):
self.codec = codec
self.sample_rate = sample_rate
self.bandwidth = bandwidth
class LiveChannelStat(object):
"""LiveStat结果。
:param status: 直播状态。
:type codec: str
:param remote_addr: 客户端的地址。
:type remote_addr: str
:param connected_time: 本次推流开始时间。
:type connected_time: int, unix time
:param video: 视频描述信息。
:type video: class:`LiveChannelVideoStat <oss2.models.LiveChannelVideoStat>`
:param audio: 音频描述信息。
:type audio: class:`LiveChannelAudioStat <oss2.models.LiveChannelAudioStat>`"""
def __init__(self,
status = '',
remote_addr = '',
connected_time = '',
video = None,
audio = None):
self.status = status
self.remote_addr = remote_addr
self.connected_time = connected_time
self.video = video
self.audio = audio
class LiveRecord(object):
"""直播频道中的推流记录信息
:param start_time: 本次推流开始时间。
:type start_time: int,参考 :ref:`unix_time`。
:param end_time: 本次推流结束时间。
:type end_time: int, 参考 :ref:`unix_time`。
:param remote_addr: 推流时客户端的地址。
:type remote_addr: str"""
def __init__(self,
start_time = '',
end_time = '',
remote_addr = ''):
self.start_time = start_time
self.end_time = end_time
self.remote_addr = remote_addr
class LiveChannelHistory(object):
"""直播频道下的推流记录。"""
def __init__(self):
self.records = []
class CreateLiveChannelResult(RequestResult, LiveChannelInfo):
def __init__(self, resp):
RequestResult.__init__(self, resp)
LiveChannelInfo.__init__(self)
class GetLiveChannelResult(RequestResult, LiveChannelInfo):
def __init__(self, resp):
RequestResult.__init__(self, resp)
LiveChannelInfo.__init__(self)
class ListLiveChannelResult(RequestResult, LiveChannelList):
def __init__(self, resp):
RequestResult.__init__(self, resp)
LiveChannelList.__init__(self)
class GetLiveChannelStatResult(RequestResult, LiveChannelStat):
def __init__(self, resp):
RequestResult.__init__(self, resp)
LiveChannelStat.__init__(self)
class GetLiveChannelHistoryResult(RequestResult, LiveChannelHistory):
def __init__(self, resp):
RequestResult.__init__(self, resp)
LiveChannelHistory.__init__(self)
class GetVodPlaylistResult(RequestResult):
def __init__(self, resp):
RequestResult.__init__(self, resp)
self.playlist = to_string(resp.read())
class ProcessObjectResult(RequestResult):
def __init__(self, resp):
RequestResult.__init__(self, resp)
self.bucket = ""
self.fileSize = 0
self.object = ""
self.process_status = ""
result = json.loads(to_string(resp.read()))
if 'bucket' in result:
self.bucket = result['bucket']
if 'fileSize' in result:
self.fileSize = result['fileSize']
if 'object' in result:
self.object = result['object']
if 'status' in result:
self.process_status = result['status']
_MAX_OBJECT_TAGGING_KEY_LENGTH=128
_MAX_OBJECT_TAGGING_VALUE_LENGTH=256
class Tagging(object):
def __init__(self, tagging_rules=None):
self.tag_set = tagging_rules or TaggingRule()
def __str__(self):
tag_str = ""
tagging_rule = self.tag_set.tagging_rule
for key in tagging_rule:
tag_str += key
tag_str += "#" + tagging_rule[key] + " "
return tag_str
class TaggingRule(object):
def __init__(self):
self.tagging_rule = dict()
def add(self, key, value):
if key is None or key == '':
raise ClientError("Tagging key should not be empty")
if len(key) > _MAX_OBJECT_TAGGING_KEY_LENGTH:
raise ClientError("Tagging key is too long")
if len(value) > _MAX_OBJECT_TAGGING_VALUE_LENGTH:
raise ClientError("Tagging value is too long")
self.tagging_rule[key] = value
def delete(self, key):
del self.tagging_rule[key]
def len(self):
return len(self.tagging_rule)
def to_query_string(self):
query_string = ''
for key in self.tagging_rule:
query_string += urlquote(key)
query_string += '='
query_string += urlquote(self.tagging_rule[key])
query_string += '&'
if len(query_string) == 0:
return ''
else:
query_string = query_string[:-1]
return query_string
class GetTaggingResult(RequestResult, Tagging):
def __init__(self, resp):
RequestResult.__init__(self, resp)
Tagging.__init__(self)
SERVER_SIDE_ENCRYPTION_AES256 = 'AES256'
SERVER_SIDE_ENCRYPTION_KMS = 'KMS'
SERVER_SIDE_ENCRYPTION_SM4 = 'SM4'
KMS_DATA_ENCRYPTION_SM4 = 'SM4'
class ServerSideEncryptionRule(object):
def __init__(self, sse_algorithm=None, kms_master_keyid=None, kms_data_encryption=None):
self.sse_algorithm = sse_algorithm
self.kms_master_keyid = kms_master_keyid
self.kms_data_encryption = kms_data_encryption
class GetServerSideEncryptionResult(RequestResult, ServerSideEncryptionRule):
def __init__(self, resp):
RequestResult.__init__(self, resp)
ServerSideEncryptionRule.__init__(self)
class ListObjectVersionsResult(RequestResult):
def __init__(self, resp):
super(ListObjectVersionsResult, self).__init__(resp)
#: True表示还有更多的文件可以罗列;False表示已经列举完毕。
self.is_truncated = False
#: 本次使用的分页标记符
self.key_marker = ''
#: 下一次罗列的分页标记符,即,可以作为 :func:`list_object_versions <oss2.Bucket.list_object_versions>` 的 `key_marker` 参数。
self.next_key_marker = ''
#: 本次使用的versionid分页标记符
self.versionid_marker = ''
#: 下一次罗列的versionid分页标记符,即,可以作为 :func:`list_object_versions <oss2.Bucket.list_object_versions>` 的 `versionid_marker` 参数。
self.next_versionid_marker = ''
self.name = ''
self.owner = ''
self.prefix = ''
self.max_keys = ''
self.delimiter = ''
#: 本次罗列得到的delete marker列表。其中元素的类型为 :class:`DeleteMarkerInfo` 。
self.delete_marker = []
#: 本次罗列得到的文件version列表。其中元素的类型为 :class:`ObjectVersionInfo` 。
self.versions = []
self.common_prefix = []
class DeleteMarkerInfo(object):
def __init__(self):
self.key = ''
self.versionid = ''
self.is_latest = False
self.last_modified = ''
self.owner = Owner('', '')
class ObjectVersionInfo(object):
def __init__(self):
self.key = ''
self.versionid = ''
self.is_latest = False
self.last_modified = ''
self.owner = Owner('', '')
self.type = ''
self.storage_class = ''
self.size = ''
self.etag = ''
BUCKET_VERSIONING_ENABLE = 'Enabled'
BUCKET_VERSIONING_SUSPEND = 'Suspended'
class BucketVersioningConfig(object):
def __init__(self, status=None):
self.status = status
class GetBucketVersioningResult(RequestResult, BucketVersioningConfig):
def __init__(self, resp):
RequestResult.__init__(self,resp)
BucketVersioningConfig.__init__(self)
class GetBucketPolicyResult(RequestResult):
def __init__(self, resp):
RequestResult.__init__(self, resp)
self.policy = to_string(resp.read())
class GetBucketRequestPaymentResult(RequestResult):
def __init__(self, resp):
RequestResult.__init__(self, resp)
self.payer = ''
class BucketQosInfo(object):
"""bucket的Qos信息
:以下参数如果设置为0则表示完全禁止指定类型的访问,如果为-1则表示不单独限制
:param total_upload_bw: 总上传带宽, 单位Gbps
:type total_upload_bw: int
:param intranet_upload_bw: 内网上传带宽, 单位Gbps
:type intranet_upload_bw: int
:param extranet_upload_bw: 外网上传带宽, 单位Gbps
:type extranet_upload_bw: int
:param total_download_bw: 总下载带宽, 单位Gbps
:type total_download_bw: int
:param intranet_download_bw: 内外下载带宽, 单位Gbps
:type intranet_download_bw: int
:param extranet_download_bw: 外网下载带宽, 单位Gbps
:type extranet_download_bw: int
:param total_qps: 总qps, 单位请求数/s
:type total_qps: int
:param intranet_qps: 内网访问qps, 单位请求数/s
:type intranet_qps: int
:param extranet_qps: 外网访问qps, 单位请求数/s
:type extranet_qps: int
"""
def __init__(self,
total_upload_bw = None,
intranet_upload_bw = None,
extranet_upload_bw = None,
total_download_bw = None,
intranet_download_bw = None,
extranet_download_bw = None,
total_qps = None,
intranet_qps = None,
extranet_qps = None):
self.total_upload_bw = total_upload_bw
self.intranet_upload_bw = intranet_upload_bw
self.extranet_upload_bw = extranet_upload_bw
self.total_download_bw = total_download_bw
self.intranet_download_bw = intranet_download_bw
self.extranet_download_bw = extranet_download_bw
self.total_qps = total_qps
self.intranet_qps = intranet_qps
self.extranet_qps = extranet_qps
class UserQosInfo(object):
"""User的Qos信息
:param region: 查询的qos配置生效的区域
:type region: str
:以下参数如果为0则表示完全禁止指定类型的访问,如果为-1表示不单独限制
:param total_upload_bw: 总上传带宽, 单位Gbps
:type total_upload_bw: int
:param intranet_upload_bw: 内网上传带宽, 单位:Gbps
:type intranet_upload_bw: int
:param extranet_upload_bw: 外网上传带宽, 单位:Gbps
:type extranet_upload_bw: int
:param total_download_bw: 总下载带宽, 单位:Gbps
:type total_download_bw: int
:param intranet_download_bw: 内外下载带宽, 单位:Gbps
:type intranet_download_bw: int
:param extranet_download_bw: 外网下载带宽, 单位:Gbps
:type extranet_download_bw: int
:param total_qps: 总qps限制
:type total_qps: int
:param intranet_qps: 内网访问qps
:type intranet_qps: int
:param extranet_qps: 外网访问qps
:type extranet_qps: int
"""
def __init__(self,
region=None,
total_upload_bw = None,
intranet_upload_bw = None,
extranet_upload_bw = None,
total_download_bw = None,
intranet_download_bw = None,
extranet_download_bw = None,
total_qps = None,
intranet_qps = None,
extranet_qps = None):
self.region = region
self.total_upload_bw = total_upload_bw
self.intranet_upload_bw = intranet_upload_bw
self.extranet_upload_bw = extranet_upload_bw
self.total_download_bw = total_download_bw
self.intranet_download_bw = intranet_download_bw
self.extranet_download_bw = extranet_download_bw
self.total_qps = total_qps
self.intranet_qps = intranet_qps
self.extranet_qps = extranet_qps
class GetUserQosInfoResult(RequestResult, UserQosInfo):
def __init__(self, resp):
RequestResult.__init__(self, resp)
UserQosInfo.__init__(self)
class GetBucketQosInfoResult(RequestResult, BucketQosInfo):
def __init__(self, resp):
RequestResult.__init__(self, resp)
BucketQosInfo.__init__(self)
class BucketUserQos(object):
"""用户服务质量。
:param int storage_capacity: 容量大小,单位GB
"""
def __init__(self, storage_capacity=None):
self.storage_capacity = storage_capacity
class GetBucketUserQosResult(RequestResult, BucketUserQos):
def __init__(self, resp):
RequestResult.__init__(self, resp)
BucketUserQos.__init__(self)
ASYNC_FETCH_TASK_STATE_RUNNING = 'Running'
ASYNC_FETCH_TASK_STATE_RETRY = 'Retry'
ASYNC_FETCH_TASK_STATE_FETCH_SUCCESS_CALLBACK_FAILED = 'FetchSuccessCallbackFailed'
ASYNC_FETCH_TASK_STATE_FAILED= 'Failed'
ASYNC_FETCH_TASK_STATE_SUCCESS = 'Success'
class AsyncFetchTaskConfiguration(object):
"""异步获取文件到bucket到任务配置项
:param url: 源文件url
:type url: str
:param object_name: 文件的名称。
:type task_state: str
:param host: 文件所在服务器的host,如果不指定则会根据url解析填充。
:type host: str
:param content_md5: 指定校验源文件的md5
:type content_md5: str
:param callback: 指定fetch成功知乎回调给用户的引用服务器,如果不指定则不回调。
callback格式与OSS上传回调的请求头callback一致,详情见官网。
:type callback: str
:param ignore_same_key: 默认为True表示如果文件已存在则忽略本次任务,api调用将会报错。如果为False,则会覆盖已存在的object。
:type ignore_same_key: bool
"""
def __init__(self,
url,
object_name,
host = None,
content_md5 = None,
callback = None,
ignore_same_key = None):
self.url = url
self.object_name = object_name
self.host = host
self.content_md5 = content_md5
self.callback = callback
self.ignore_same_key = ignore_same_key
class PutAsyncFetchTaskResult(RequestResult):
def __init__(self, resp, task_id=None):
RequestResult.__init__(self, resp)
self.task_id = task_id
class GetAsyncFetchTaskResult(RequestResult):
"""获取异步获取文件到bucket的任务的返回结果
:param task_id: 任务id
:type task_id: str
:param task_state: 取值范围:oss2.models.ASYNC_FETCH_TASK_STATE_RUNNING, oss2.models.ASYNC_FETCH_TASK_STATE_RETRY,
oss2.models.ASYNC_FETCH_TASK_STATE_FETCH_SUCCESS_CALLBACK_FAILED, oss2.models.ASYNC_FETCH_TASK_STATE_FAILED,
oss2.models.ASYNC_FETCH_TASK_STATE_SUCCESS。
:type task_state: str
:param error_msg: 错误信息
:type error_msg: str
:param task_config: 任务配置信息
:type task_config: class:`AsyncFetchTaskConfiguration <oss2.models.AsyncFetchTaskConfiguration>`
"""
def __init__(self, resp,
task_id=None,
task_state=None,
error_msg=None,
task_config=None):
RequestResult.__init__(self, resp)
self.task_id = task_id
self.task_state = task_state
self.error_msg = error_msg
self.task_config = task_config
INVENTORY_INCLUDED_OBJECT_VERSIONS_CURRENT = "Current"
INVENTORY_INCLUDED_OBJECT_VERSIONS_ALL = "All"
INVENTORY_FREQUENCY_DAILY = "Daily"
INVENTORY_FREQUENCY_WEEKLY = "Weekly"
INVENTORY_FORMAT_CSV = "CSV"
FIELD_SIZE = "Size"
FIELD_LAST_MODIFIED_DATE = "LastModifiedDate"
FIELD_STORAG_CLASS = "StorageClass"
FIELD_ETAG = "ETag"
FIELD_IS_MULTIPART_UPLOADED = "IsMultipartUploaded"
FIELD_ENCRYPTION_STATUS = "EncryptionStatus"
class InventoryConfiguration(object):
"""清单配置
:param str inventory_id: 清单的识别id
:type inventory_id: str
:param is_enabled: 是否生效
:type is_enabled: bool
:param include_object_versions: 包含的对象版本,
取值可以是 INVENTORY_INCLUDE_OBJECT_VERSIONS_CURRENT 或者 INVENTORY_INCLUDE_OBJECT_VERSIONS_ALL.
:type include_object_versions: str
:param inventory_filter: 清单的过滤器
:type inventory_filter: class:`InventoryFilter <oss2.models.InventoryFilter>`
:param inventory_destination: 清单的目标地址
:type inventory_destination: class:`InventoryDestination <oss2.models.InventoryDestination>`
:param inventory_schedule: 清单的生成周期
:type inventory_schedule: class:`InventoryDestination <oss2.models.InventorySchedule>`
:param optional_fields: 清单中包含的字段
:type optional_fields: str
"""
def __init__(self,
inventory_id=None,
is_enabled=None,
included_object_versions=None,
inventory_filter=None,
inventory_destination=None,
inventory_schedule=None,
optional_fields=None):
self.inventory_id = inventory_id
self.is_enabled = is_enabled
self.included_object_versions = included_object_versions
self.inventory_filter = inventory_filter
self.inventory_destination = inventory_destination
self.inventory_schedule = inventory_schedule
self.optional_fields = optional_fields or []
class InventoryFilter(object):
"""清单过滤器
:param prefix: 清单筛选的前缀, 指定前缀后,清单将筛选出符合前缀设置的对象。
:type prefix: str
"""
def __init__(self, prefix=None):
self.prefix = prefix
class InventorySchedule(object):
"""清单的生成周期
:param frequency: 清单的生成周期,可以是oss2.models.INVENTORY_FREQUENCY_DAILY 或者 oss2.models.INVENTORY_FREQUENCY_WEEKLY
:type frequency: str
"""
def __init__(self, frequency):
self.frequency = frequency
class InventoryDestination(object):
"""清单的接收目的地址
:param bucket_destination: OSS Bucket作为目的地,需要配置的OSS Bucket信息。
:type bucket_destination: class:`InventoryBucketDestination <oss2.models.InventoryBucketDestination>`
"""
def __init__(self, bucket_destination=None):
self.bucket_destination = bucket_destination
class InventoryBucketDestination(object):
"""OSS Bucket作为清单目的地的配置
:param account_id: 接收方的account id
:type account_id: class:`InventoryBucketDestination <oss2.models.InventoryBucketDestination>`
:param role_arn: 接收方的ram role arn
:type role_arn: str
:param bucket: OSS Bucket名称
:type bucket: str
:param inventory_format: 清单格式,可以是 oss2.models.INVENTORY_FORMAT_CSV。
:type inventory_format: str
:param prefix: 清单文件的存储路径前缀
:type prefix: str
:param sse_kms_encryption: 服务端使用kms作为清单的加密项
:type sse_kms_encryption: class:`InventoryServerSideEncryptionKMS <oss2.models.InventoryServerSideEncryptionKMS>`
:param sse_oss_encryption: OSS服务端为清单提供加密支持。
:type sse_oss_encryption: class:`InventoryServerSideEncryptionOSS <oss2.models.InventoryServerSideEncryptionOSS>`
"""
def __init__(self,
account_id=None,
role_arn=None,
bucket=None,
inventory_format=None,
prefix=None,
sse_kms_encryption=None,
sse_oss_encryption=None):
if all((sse_kms_encryption, sse_oss_encryption)):
raise ClientError('only one encryption method between sse_kms_encryption and sse_oss_encryption can be chosen.')
self.account_id = account_id
self.role_arn = role_arn
self.bucket = bucket
self.inventory_format = inventory_format
self.prefix = prefix
self.sse_kms_encryption = sse_kms_encryption
self.sse_oss_encryption = sse_oss_encryption
class InventoryServerSideEncryptionKMS(object):
"""服务端使用kms加密清单的加密项。
:param key_id: kms key id
:type key_id: str
"""
def __init__(self, key_id):
self.key_id = key_id
class InventoryServerSideEncryptionOSS(object):
"""OSS服务端加密清单的加密项。
"""
pass
class GetInventoryConfigurationResult(RequestResult, InventoryConfiguration):
"""获取清单配置的操作返回结果
"""
def __init__(self, resp):
RequestResult.__init__(self, resp)
InventoryConfiguration.__init__(self)
class ListInventoryConfigurationsResult(RequestResult):
"""列出清单配置的操作返回结果
:param inventory_configurations: list of class:`InventoryConfiguration <oss2.models.InventoryConfiguration>`
:type inventory_configurations: list
:param is_truncated: 罗列结果是否是截断的, true: 本地罗列结果并不完整, False: 所有清单配置项已经罗列完毕。
:type is_truncated: bool
:param continuaiton_token: 本地罗列操作所携带的continuaiton_token
:type continuaiton_token: str
:param next_continuation_token: 下一个罗列操作携带的token
:type next_continuation_token: str
"""
def __init__(self, resp):
RequestResult.__init__(self, resp)
self.inventory_configurations= []
self.is_truncated = None
self.continuaiton_token = None
self.next_continuation_token = None
RESTORE_TIER_EXPEDITED = 'Expedited'
RESTORE_TIER_STANDARD = 'Standard'
RESTORE_TIER_BULK = 'Bulk'
class ResotreJobParameters(object):
"""冷归档类型(ColdArchive)文件的解冻优先级配置。
请使用class:`RestoreJobParameters <oss2.models.RestoreJobParameters>`代替此类。
:param tier: 解冻优先级, 取值范围:
oss2.models.RESTORE_TIER_EXPEDITED: 1个小时之内解冻完成。
oss2.models.RESTORE_TIER_STANDARD: 5小时之内解冻完成。
oss2.models.RESTORE_TIER_BULK: 10小时之内解冻完成。
:type tier: str
"""
def __init__(self, tier):
self.tier = tier
class RestoreJobParameters(object):
"""冷归档类型(ColdArchive)文件的解冻优先级配置。
:param tier: 解冻优先级, 取值范围:
oss2.models.RESTORE_TIER_EXPEDITED: 1个小时之内解冻完成。
oss2.models.RESTORE_TIER_STANDARD: 5小时之内解冻完成。
oss2.models.RESTORE_TIER_BULK: 10小时之内解冻完成。
:type tier: str
"""
def __init__(self, tier):
self.tier = tier
class RestoreConfiguration(object):
"""Archive, ColdArchive类型文件的解冻配置
:param days: 解冻之后保持解冻状态的天数。
:type days: int
:param job_parameters: 解冻优先级配置, 解冻冷归档(ColdArchive)类型的文件才需要此配置。如果不配置此项,
解冻优先级默认为 oss2.models.RESTORE_TIER_STANDARD: 5小时之内解冻完成。
:type job_parameters: class:`RestoreJobParameters <oss2.models.RestoreJobParameters>`
"""
def __init__(self, days, job_parameters=None):
self.days = days
self.job_parameters = job_parameters
class InitBucketWormResult(RequestResult):
"""创建合规保留策略的返回结果
:param str worm_id: 合规保留策略的id
"""
def __init__(self, resp):
super(InitBucketWormResult, self).__init__(resp)
self.worm_id = None
class GetBucketWormResult(RequestResult):
"""获取合规保留策略的返回结果
:param str worm_id: 合规保留策略的id
"""
def __init__(self, resp):
super(GetBucketWormResult, self).__init__(resp)
# 合规保留策略的id
self.worm_id = None
# 合规保留策略的状态
self.worm_state = None
# object的保留天数
self.retention_period_days = None
# 合规保留策略的创建日期
self.creation_date = None
class ReplicationRule(object):
"""创建Bucket指定跨区域复制规则
:param str rule_id: 规则ID。
:param str target_bucket_name: 目的地Bucket名称。
:param str target_bucket_location: 目的地Bucket所处地域。
:param str target_transfer_type: 跨区域复制时使用的数据链路。
:param list prefix_list: 待复制Object的前缀,只有匹配该前缀的Object才会被复制。
:param list action_list: 新写入的数据与历史数据需要遵循的Action类型, 其中"ALL" 表示"PUT", "ABORT"与"DELETE"操作。
均会被同步到Bucket,"PUT"表示同步到目标Bucket的写入操作。
:param bool is_enable_historical_object_replication: 指定是否复制历史数据。
:param str sync_role_name: 授权OSS使用哪个角色来进行数据复制。如果指定使用SSE-KMS加密目标对象,则必须指定sync_role。
:param str replica_kms_keyid: 指定SSE-KMS密钥ID。
:param str sse_kms_encrypted_objects_status: 指定OSS是否复制通过SSE-KMS加密创建的对象。
取值范围[ReplicationRule.ENABLED, ReplicationRule.DISABLED]。
:param str status: 复制状态,由服务端赋值,可能为:starting, doing 或closing。
"""
ENABLED = 'Enabled'
DISABLED = 'Disabled'
ALL = 'ALL'
PUT = 'PUT'
DELETE = 'DELETE'
ABORT = 'ABORT'
STARTING = 'starting'
DOING = 'doing'
CLOSING = 'closing'
def __init__(self,
rule_id=None,
target_bucket_name=None,
target_bucket_location=None,
target_transfer_type=None,
prefix_list=None,
action_list=None,
is_enable_historical_object_replication=None,
sync_role_name=None,
replica_kms_keyid=None,
sse_kms_encrypted_objects_status=None,
status=None):
self.rule_id = rule_id
self.target_bucket_name = target_bucket_name
self.target_bucket_location = target_bucket_location
self.target_transfer_type = target_transfer_type
self.prefix_list = prefix_list or []
self.action_list = action_list or []
if is_enable_historical_object_replication is not None and not isinstance(is_enable_historical_object_replication, bool):
raise ClientError('is_enable_historical_object_replication should be instance of bool.')
self.is_enable_historical_object_replication = is_enable_historical_object_replication
self.sync_role_name = sync_role_name
self.replica_kms_keyid = replica_kms_keyid
if sse_kms_encrypted_objects_status is not None and sse_kms_encrypted_objects_status not in [self.ENABLED, self.DISABLED]:
raise ClientError('sse_kms_encrypted_objects_status should be "Enabled" or "Disabled".')
self.sse_kms_encrypted_objects_status = sse_kms_encrypted_objects_status
self.status = status
class BucketReplicationProgress(object):
"""Bucket跨区域复制进度
:param str rule_id: 规则ID。
:param str target_bucket_name: 目的地Bucket名称。
:param str target_bucket_location: 目的地Bucket所处地域。
:param str target_transfer_type: 跨区域复制时使用的数据链路。
:param list prefix_list: 待复制Object的前缀,只有匹配该前缀的Object才会被复制。
:param list action_list: 新写入的数据与历史数据需要遵循的Action类型, 其中"ALL" 表示"PUT", "ABORT"与"DELETE"操作。
均会被同步到Bucket,"PUT"表示同步到目标Bucket的写入操作。
:param bool is_enable_historical_object_replication: 指定是否复制历史数据。
:param str status: 复制状态,可能为starting, doing 或closing。
:param float historical_object_progress: 已复制历史数据的百分比。
:param str new_object_progress: 数据复制到目标Bucket的时间点。
例如Thu, 24 Sep 2015 15:39:18 GMT,表示早于这个时间点写入的数据都已复制到目标Bucket。
"""
def __init__(self,
rule_id=None,
target_bucket_name=None,
target_bucket_location=None,
target_transfer_type=None,
prefix_list=None,
action_list=None,
is_enable_historical_object_replication=None,
status=None,
historical_object_progress=None,
new_object_progress=None):
self.rule_id = rule_id
self.target_bucket_name = target_bucket_name
self.target_bucket_location = target_bucket_location
self.target_transfer_type = target_transfer_type
self.prefix_list = prefix_list or []
self.action_list = action_list or []
self.is_enable_historical_object_replication = is_enable_historical_object_replication
self.status = status
self.historical_object_progress = historical_object_progress or 0
self.new_object_progress = new_object_progress
class LocationTransferType(object):
"""包含TransferType到Location信息
:param str location: 可复制到的目标Bucket所在的地域。
:param str transfer_type: 跨区域复制时使用的数据传输类型。
"""
def __init__(self):
self.location = None
self.transfer_type = None
class GetBucketReplicationResult(RequestResult):
"""获取Bucket跨区域复制规则的结果
:param rule_list: Bucket跨区域复制到规则集合,目前只允许配置一条规则,所以返回list大小最多为1。
:type rule_list: list, 元素类型为class:`ReplicationRule <oss2.models.ReplicationRule>`。
"""
def __init__(self, resp):
super(GetBucketReplicationResult, self).__init__(resp)
self.rule_list = []
class GetBucketReplicationLocationResult(RequestResult):
"""获取可复制到的目标存储空间(Bucket)所在的地域信息
:param location_list: 可复制到的目标Bucket所在的地域集合
:type location_list: list, 元素类型为str, 比如'oss-cn-beijing'
:param location_transfer_type_list: 包含TransferType到Location信息列表。
:type location_transfer_type_list: list, 元素类型为:class:`LocationTransferType <oss2.models.LocationTransferType>`。
"""
def __init__(self, resp):
super(GetBucketReplicationLocationResult, self).__init__(resp)
self.location_list = []
self.location_transfer_type_list = []
class GetBucketReplicationProgressResult(RequestResult):
"""获取某个存储空间(Bucket)的跨区域复制进度结果。
:param progress: Bucket跨区域复制进度
:type progress: class:`BucketReplicationProgress <oss2.models.BucketReplicationProgress>`。
"""
def __init__(self, resp):
super(GetBucketReplicationProgressResult, self).__init__(resp)
self.progress = None
class GetBucketTransferAccelerationResult(RequestResult):
"""获取目标存储空间(Bucket)的传输加速配置。
:param enabled: Bucket传输加速状态
:type progress: class:`GetBucketTransferAccelerationResult <oss2.models.GetBucketTransferAccelerationResult>`。
"""
def __init__(self, resp):
super(GetBucketTransferAccelerationResult, self).__init__(resp)
self.enabled = None