tosnativeclient 1.0.1__tar.gz → 1.0.4__tar.gz
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.
Potentially problematic release.
This version of tosnativeclient might be problematic. Click here for more details.
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/Cargo.lock +18 -1
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/Cargo.toml +2 -1
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/PKG-INFO +1 -1
- tosnativeclient-1.0.4/python/tosnativeclient/__init__.py +25 -0
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/python/tosnativeclient/tosnativeclient.pyi +63 -59
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/src/list_stream.rs +38 -43
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/src/read_stream.rs +14 -3
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/src/tos_client.rs +59 -18
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/src/tos_error.rs +14 -2
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/src/tos_model.rs +2 -2
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/src/tos_raw_client.rs +92 -25
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/src/write_stream.rs +16 -7
- tosnativeclient-1.0.1/python/tosnativeclient/__init__.py +0 -21
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/.github/workflows/CI.yml +0 -0
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/.gitignore +0 -0
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/build.sh +0 -0
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/pyproject.toml +0 -0
- {tosnativeclient-1.0.1 → tosnativeclient-1.0.4}/src/lib.rs +0 -0
|
@@ -472,6 +472,12 @@ version = "0.5.0"
|
|
|
472
472
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
473
473
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
474
474
|
|
|
475
|
+
[[package]]
|
|
476
|
+
name = "hermit-abi"
|
|
477
|
+
version = "0.5.2"
|
|
478
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
479
|
+
checksum = "fc0fef456e4baa96da950455cd02c081ca953b141298e41db3fc7e36b1da849c"
|
|
480
|
+
|
|
475
481
|
[[package]]
|
|
476
482
|
name = "hex"
|
|
477
483
|
version = "0.4.3"
|
|
@@ -859,6 +865,16 @@ dependencies = [
|
|
|
859
865
|
"autocfg",
|
|
860
866
|
]
|
|
861
867
|
|
|
868
|
+
[[package]]
|
|
869
|
+
name = "num_cpus"
|
|
870
|
+
version = "1.17.0"
|
|
871
|
+
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
872
|
+
checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b"
|
|
873
|
+
dependencies = [
|
|
874
|
+
"hermit-abi",
|
|
875
|
+
"libc",
|
|
876
|
+
]
|
|
877
|
+
|
|
862
878
|
[[package]]
|
|
863
879
|
name = "object"
|
|
864
880
|
version = "0.36.7"
|
|
@@ -1505,13 +1521,14 @@ dependencies = [
|
|
|
1505
1521
|
|
|
1506
1522
|
[[package]]
|
|
1507
1523
|
name = "tosnativeclient"
|
|
1508
|
-
version = "1.0.
|
|
1524
|
+
version = "1.0.4"
|
|
1509
1525
|
dependencies = [
|
|
1510
1526
|
"arc-swap",
|
|
1511
1527
|
"async-channel",
|
|
1512
1528
|
"async-trait",
|
|
1513
1529
|
"bytes",
|
|
1514
1530
|
"futures-util",
|
|
1531
|
+
"num_cpus",
|
|
1515
1532
|
"pyo3",
|
|
1516
1533
|
"tokio",
|
|
1517
1534
|
"tracing",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "tosnativeclient"
|
|
3
|
-
version = "1.0.
|
|
3
|
+
version = "1.0.4"
|
|
4
4
|
edition = "2021"
|
|
5
5
|
publish = false
|
|
6
6
|
authors = ["xiangshijian"]
|
|
@@ -23,3 +23,4 @@ async-trait = "0.1.88"
|
|
|
23
23
|
futures-util = "0.3.30"
|
|
24
24
|
async-channel = "2.3.1"
|
|
25
25
|
tracing = { version = "0.1.41", features = ["log"] }
|
|
26
|
+
num_cpus = "1.17.0"
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from .tosnativeclient import TosClient, ListStream, ListObjectsResult, TosObject, ReadStream, WriteStream, TosError, \
|
|
2
|
+
TosException, TosRawClient, \
|
|
3
|
+
HeadObjectInput, HeadObjectOutput, GetObjectOutput, DeleteObjectInput, DeleteObjectOutput, GetObjectInput, \
|
|
4
|
+
PutObjectFromBufferInput, PutObjectFromFileInput, PutObjectOutput
|
|
5
|
+
|
|
6
|
+
__all__ = [
|
|
7
|
+
'TosError',
|
|
8
|
+
'TosException',
|
|
9
|
+
'TosClient',
|
|
10
|
+
'ListStream',
|
|
11
|
+
'ListObjectsResult',
|
|
12
|
+
'TosObject',
|
|
13
|
+
'ReadStream',
|
|
14
|
+
'WriteStream',
|
|
15
|
+
'TosRawClient',
|
|
16
|
+
'HeadObjectInput',
|
|
17
|
+
'HeadObjectOutput',
|
|
18
|
+
'DeleteObjectInput',
|
|
19
|
+
'DeleteObjectOutput',
|
|
20
|
+
'GetObjectInput',
|
|
21
|
+
'GetObjectOutput',
|
|
22
|
+
'PutObjectFromBufferInput',
|
|
23
|
+
'PutObjectFromFileInput',
|
|
24
|
+
'PutObjectOutput'
|
|
25
|
+
]
|
|
@@ -3,31 +3,27 @@ from typing import List, Dict
|
|
|
3
3
|
from typing import Optional
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
class
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
part_size: int
|
|
12
|
-
max_retry_count: int
|
|
13
|
-
max_prefetch_tasks: int
|
|
6
|
+
class TosError(object):
|
|
7
|
+
message: str
|
|
8
|
+
status_code: Optional[int]
|
|
9
|
+
ec: str
|
|
10
|
+
request_id: str
|
|
14
11
|
|
|
15
|
-
def __init__(self, region: str, endpoint: str, ak: str = '', sk: str = '', part_size: int = 8388608,
|
|
16
|
-
max_retry_count: int = 3, max_prefetch_tasks: int = 3, directives: str = '', directory: str = '',
|
|
17
|
-
file_name_prefix: str = '', shared_prefetch_tasks: int = 20):
|
|
18
|
-
...
|
|
19
12
|
|
|
20
|
-
|
|
21
|
-
|
|
13
|
+
class TosException(Exception):
|
|
14
|
+
args: List[TosError]
|
|
22
15
|
|
|
23
|
-
def head_object(self, bucket: str, key: str) -> TosObject:
|
|
24
|
-
...
|
|
25
16
|
|
|
26
|
-
|
|
27
|
-
|
|
17
|
+
class TosObject(object):
|
|
18
|
+
bucket: str
|
|
19
|
+
key: str
|
|
20
|
+
size: int
|
|
21
|
+
etag: str
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
|
|
24
|
+
class ListObjectsResult(object):
|
|
25
|
+
contents: List[TosObject]
|
|
26
|
+
common_prefixes: List[str]
|
|
31
27
|
|
|
32
28
|
|
|
33
29
|
class ListStream(object):
|
|
@@ -43,25 +39,13 @@ class ListStream(object):
|
|
|
43
39
|
def close(self) -> None: ...
|
|
44
40
|
|
|
45
41
|
|
|
46
|
-
class ListObjectsResult(object):
|
|
47
|
-
contents: List[TosObject]
|
|
48
|
-
common_prefixes: List[str]
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
class TosObject(object):
|
|
52
|
-
bucket: str
|
|
53
|
-
key: str
|
|
54
|
-
size: int
|
|
55
|
-
etag: str
|
|
56
|
-
|
|
57
|
-
|
|
58
42
|
class ReadStream(object):
|
|
59
43
|
bucket: str
|
|
60
44
|
key: str
|
|
61
45
|
size: int
|
|
62
46
|
etag: str
|
|
63
47
|
|
|
64
|
-
def read(self, offset: int, length: int) -> bytes:
|
|
48
|
+
def read(self, offset: int, length: int) -> Optional[bytes]:
|
|
65
49
|
...
|
|
66
50
|
|
|
67
51
|
def close(self) -> None:
|
|
@@ -80,44 +64,34 @@ class WriteStream(object):
|
|
|
80
64
|
...
|
|
81
65
|
|
|
82
66
|
|
|
83
|
-
class
|
|
84
|
-
message: str
|
|
85
|
-
status_code: Optional[int]
|
|
86
|
-
ec: str
|
|
87
|
-
request_id: str
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class TosException(Exception):
|
|
91
|
-
args: List[TosError]
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
class TosRawClient(object):
|
|
67
|
+
class TosClient(object):
|
|
95
68
|
region: str
|
|
96
69
|
endpoint: str
|
|
97
70
|
ak: str
|
|
98
71
|
sk: str
|
|
99
|
-
|
|
100
|
-
request_timeout: int
|
|
101
|
-
max_connections: int
|
|
72
|
+
part_size: int
|
|
102
73
|
max_retry_count: int
|
|
74
|
+
max_prefetch_tasks: int
|
|
75
|
+
directives: str
|
|
76
|
+
directory: str
|
|
77
|
+
file_name_prefix: str
|
|
78
|
+
shared_prefetch_tasks: int
|
|
103
79
|
|
|
104
|
-
def __init__(self, region: str, endpoint: str, ak: str = '', sk: str = '',
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def head_object(self, input: HeadObjectInput) -> HeadObjectOutput:
|
|
80
|
+
def __init__(self, region: str, endpoint: str, ak: str = '', sk: str = '', part_size: int = 8388608,
|
|
81
|
+
max_retry_count: int = 3, max_prefetch_tasks: int = 3, directives: str = '', directory: str = '',
|
|
82
|
+
file_name_prefix: str = '', shared_prefetch_tasks: int = 20):
|
|
109
83
|
...
|
|
110
84
|
|
|
111
|
-
def
|
|
85
|
+
def list_objects(self, bucket: str, prefix: str = '', max_keys: int = 1000, delimiter: str = '') -> ListStream:
|
|
112
86
|
...
|
|
113
87
|
|
|
114
|
-
def
|
|
88
|
+
def head_object(self, bucket: str, key: str) -> TosObject:
|
|
115
89
|
...
|
|
116
90
|
|
|
117
|
-
def
|
|
91
|
+
def get_object(self, bucket: str, key: str, etag: str, size: int) -> ReadStream:
|
|
118
92
|
...
|
|
119
93
|
|
|
120
|
-
def
|
|
94
|
+
def put_object(self, bucket: str, key: str, storage_class: Optional[str] = '') -> WriteStream:
|
|
121
95
|
...
|
|
122
96
|
|
|
123
97
|
|
|
@@ -177,10 +151,10 @@ class GetObjectOutput(object):
|
|
|
177
151
|
content_range: str
|
|
178
152
|
hash_crc64ecma: int
|
|
179
153
|
|
|
180
|
-
def read_all(self) -> bytes:
|
|
154
|
+
def read_all(self) -> Optional[bytes]:
|
|
181
155
|
...
|
|
182
156
|
|
|
183
|
-
def read(self) -> bytes:
|
|
157
|
+
def read(self) -> Optional[bytes]:
|
|
184
158
|
...
|
|
185
159
|
|
|
186
160
|
|
|
@@ -209,3 +183,33 @@ class PutObjectOutput(object):
|
|
|
209
183
|
etag: str
|
|
210
184
|
version_id: str
|
|
211
185
|
hash_crc64ecma: int
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
class TosRawClient(object):
|
|
189
|
+
region: str
|
|
190
|
+
endpoint: str
|
|
191
|
+
ak: str
|
|
192
|
+
sk: str
|
|
193
|
+
connection_timeout: int
|
|
194
|
+
request_timeout: int
|
|
195
|
+
max_connections: int
|
|
196
|
+
max_retry_count: int
|
|
197
|
+
|
|
198
|
+
def __init__(self, region: str, endpoint: str, ak: str = '', sk: str = '', connection_timeout: int = 10000,
|
|
199
|
+
request_timeout: int = 120000, max_connections: int = 1024, max_retry_count: int = 3):
|
|
200
|
+
...
|
|
201
|
+
|
|
202
|
+
def head_object(self, input: HeadObjectInput) -> HeadObjectOutput:
|
|
203
|
+
...
|
|
204
|
+
|
|
205
|
+
def delete_object(self, input: DeleteObjectInput) -> DeleteObjectOutput:
|
|
206
|
+
...
|
|
207
|
+
|
|
208
|
+
def get_object(self, input: GetObjectInput) -> GetObjectOutput:
|
|
209
|
+
...
|
|
210
|
+
|
|
211
|
+
def put_object_from_buffer(self, input: PutObjectFromBufferInput) -> PutObjectOutput:
|
|
212
|
+
...
|
|
213
|
+
|
|
214
|
+
def put_object_from_file(self, input: PutObjectFromFileInput) -> PutObjectOutput:
|
|
215
|
+
...
|
|
@@ -3,7 +3,8 @@ use crate::tos_error::{map_error_from_string, map_tos_error};
|
|
|
3
3
|
use crate::tos_model::ListObjectsResult;
|
|
4
4
|
use arc_swap::ArcSwap;
|
|
5
5
|
use async_channel::Receiver;
|
|
6
|
-
use pyo3::
|
|
6
|
+
use pyo3::types::PyTuple;
|
|
7
|
+
use pyo3::{pyclass, pymethods, Bound, IntoPyObject, PyRef, PyRefMut, PyResult, Python};
|
|
7
8
|
use std::sync::atomic::{AtomicI8, Ordering};
|
|
8
9
|
use std::sync::{Arc, RwLock};
|
|
9
10
|
use tokio::runtime::Runtime;
|
|
@@ -12,7 +13,7 @@ use ve_tos_rust_sdk::error::TosError;
|
|
|
12
13
|
use ve_tos_rust_sdk::object::{ListObjectsType2Input, ListObjectsType2Output};
|
|
13
14
|
|
|
14
15
|
const DEFAULT_TASK_COUNT: usize = 5;
|
|
15
|
-
#[pyclass(name = "ListStream")]
|
|
16
|
+
#[pyclass(name = "ListStream", module = "tosnativeclient")]
|
|
16
17
|
pub struct ListStream {
|
|
17
18
|
client: Arc<InnerTosClient>,
|
|
18
19
|
runtime: Arc<Runtime>,
|
|
@@ -46,14 +47,11 @@ impl ListStream {
|
|
|
46
47
|
return Err(map_error_from_string("ListStream is closed"));
|
|
47
48
|
}
|
|
48
49
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
*pg = slf.list_background(slf.py());
|
|
53
|
-
}
|
|
50
|
+
let mut pg = slf.paginator.write().unwrap();
|
|
51
|
+
if pg.is_none() {
|
|
52
|
+
*pg = slf.list_background(slf.py());
|
|
54
53
|
}
|
|
55
|
-
|
|
56
|
-
slf.next_page(slf.paginator.read().unwrap().as_ref(), slf.py())
|
|
54
|
+
slf.next_page(pg.as_ref(), slf.py())
|
|
57
55
|
}
|
|
58
56
|
|
|
59
57
|
pub fn close(&self) {
|
|
@@ -66,6 +64,17 @@ impl ListStream {
|
|
|
66
64
|
}
|
|
67
65
|
}
|
|
68
66
|
}
|
|
67
|
+
|
|
68
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
69
|
+
let py = slf.py();
|
|
70
|
+
let state = [
|
|
71
|
+
slf.bucket.clone().into_pyobject(py)?.into_any(),
|
|
72
|
+
slf.prefix.clone().into_pyobject(py)?.into_any(),
|
|
73
|
+
slf.delimiter.clone().into_pyobject(py)?.into_any(),
|
|
74
|
+
slf.max_keys.clone().into_pyobject(py)?.into_any(),
|
|
75
|
+
];
|
|
76
|
+
PyTuple::new(py, state)
|
|
77
|
+
}
|
|
69
78
|
}
|
|
70
79
|
|
|
71
80
|
impl ListStream {
|
|
@@ -100,67 +109,54 @@ impl ListStream {
|
|
|
100
109
|
py.allow_threads(|| {
|
|
101
110
|
self.runtime.spawn(async move {
|
|
102
111
|
let mut need_break = false;
|
|
103
|
-
if input.delimiter() == "
|
|
104
|
-
let mut prefixes = Vec::with_capacity(16);
|
|
105
|
-
let mut last_page_end = false;
|
|
112
|
+
if input.delimiter() == "" {
|
|
106
113
|
loop {
|
|
107
|
-
if last_page_end {
|
|
108
|
-
if prefixes.is_empty() {
|
|
109
|
-
let _ = sender
|
|
110
|
-
.send((
|
|
111
|
-
true,
|
|
112
|
-
Err(TosError::TosClientError {
|
|
113
|
-
message: "invalid status error".to_string(),
|
|
114
|
-
cause: None,
|
|
115
|
-
}),
|
|
116
|
-
))
|
|
117
|
-
.await;
|
|
118
|
-
break;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
let prefix = prefixes.remove(0);
|
|
122
|
-
input.set_prefix(prefix);
|
|
123
|
-
input.set_start_after("");
|
|
124
|
-
input.set_continuation_token("");
|
|
125
|
-
last_page_end = false;
|
|
126
|
-
}
|
|
127
114
|
let result = client.list_objects_type2(&input).await;
|
|
128
115
|
if let Ok(ref o) = result {
|
|
129
116
|
if o.is_truncated() {
|
|
130
117
|
input.set_continuation_token(o.next_continuation_token());
|
|
131
118
|
} else {
|
|
132
|
-
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
for cp in o.common_prefixes() {
|
|
136
|
-
prefixes.push(cp.prefix().to_string());
|
|
119
|
+
need_break = true;
|
|
137
120
|
}
|
|
138
|
-
need_break = last_page_end && prefixes.is_empty();
|
|
139
121
|
} else {
|
|
140
122
|
need_break = true;
|
|
141
123
|
}
|
|
142
|
-
|
|
143
124
|
if let Err(_) = sender.send((need_break, result)).await {
|
|
144
|
-
need_break = true
|
|
125
|
+
need_break = true
|
|
145
126
|
}
|
|
146
127
|
if need_break {
|
|
147
128
|
break;
|
|
148
129
|
}
|
|
149
130
|
}
|
|
150
131
|
} else {
|
|
132
|
+
let mut prefixes = Vec::with_capacity(16);
|
|
133
|
+
let mut last_page_end = false;
|
|
151
134
|
loop {
|
|
135
|
+
if last_page_end {
|
|
136
|
+
let prefix = prefixes.remove(0);
|
|
137
|
+
input.set_prefix(prefix);
|
|
138
|
+
input.set_start_after("");
|
|
139
|
+
input.set_continuation_token("");
|
|
140
|
+
last_page_end = false;
|
|
141
|
+
}
|
|
152
142
|
let result = client.list_objects_type2(&input).await;
|
|
153
143
|
if let Ok(ref o) = result {
|
|
154
144
|
if o.is_truncated() {
|
|
155
145
|
input.set_continuation_token(o.next_continuation_token());
|
|
156
146
|
} else {
|
|
157
|
-
|
|
147
|
+
last_page_end = true;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
for cp in o.common_prefixes() {
|
|
151
|
+
prefixes.push(cp.prefix().to_string());
|
|
158
152
|
}
|
|
153
|
+
need_break = last_page_end && prefixes.is_empty();
|
|
159
154
|
} else {
|
|
160
155
|
need_break = true;
|
|
161
156
|
}
|
|
157
|
+
|
|
162
158
|
if let Err(_) = sender.send((need_break, result)).await {
|
|
163
|
-
need_break = true
|
|
159
|
+
need_break = true;
|
|
164
160
|
}
|
|
165
161
|
if need_break {
|
|
166
162
|
break;
|
|
@@ -169,7 +165,6 @@ impl ListStream {
|
|
|
169
165
|
}
|
|
170
166
|
});
|
|
171
167
|
});
|
|
172
|
-
|
|
173
168
|
Some(Paginator {
|
|
174
169
|
is_end: ArcSwap::new(Arc::new(false)),
|
|
175
170
|
last_err: ArcSwap::new(Arc::new(None)),
|
|
@@ -4,8 +4,8 @@ use crate::tos_model::TosObject;
|
|
|
4
4
|
use async_channel::{Receiver, Sender};
|
|
5
5
|
use bytes::Bytes;
|
|
6
6
|
use futures_util::StreamExt;
|
|
7
|
-
use pyo3::types::PyBytes;
|
|
8
|
-
use pyo3::{pyclass, pymethods, Bound, PyRef, PyResult};
|
|
7
|
+
use pyo3::types::{PyBytes, PyTuple};
|
|
8
|
+
use pyo3::{pyclass, pymethods, Bound, IntoPyObject, PyRef, PyResult};
|
|
9
9
|
use std::collections::LinkedList;
|
|
10
10
|
use std::sync::atomic::{AtomicI8, AtomicIsize, Ordering};
|
|
11
11
|
use std::sync::Arc;
|
|
@@ -24,7 +24,7 @@ const DEFAULT_PART_SIZE: isize = 8 * 1024 * 1024;
|
|
|
24
24
|
const DEFAULT_FETCH_RETRY_COUNT: isize = 3;
|
|
25
25
|
const DEFAULT_SHARED_PREFETCH_TASK_LIMIT: isize = 100;
|
|
26
26
|
|
|
27
|
-
#[pyclass(name = "ReadStream")]
|
|
27
|
+
#[pyclass(name = "ReadStream", module = "tosnativeclient")]
|
|
28
28
|
pub struct ReadStream {
|
|
29
29
|
object_fetcher: Arc<ObjectFetcher>,
|
|
30
30
|
runtime: Arc<Runtime>,
|
|
@@ -66,6 +66,17 @@ impl ReadStream {
|
|
|
66
66
|
slf.py()
|
|
67
67
|
.allow_threads(|| runtime.block_on(async move { fetcher.close().await }))
|
|
68
68
|
}
|
|
69
|
+
|
|
70
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
71
|
+
let py = slf.py();
|
|
72
|
+
let state = [
|
|
73
|
+
slf.bucket.clone().into_pyobject(py)?.into_any(),
|
|
74
|
+
slf.key.clone().into_pyobject(py)?.into_any(),
|
|
75
|
+
slf.etag.clone().into_pyobject(py)?.into_any(),
|
|
76
|
+
slf.size.clone().into_pyobject(py)?.into_any(),
|
|
77
|
+
];
|
|
78
|
+
PyTuple::new(py, state)
|
|
79
|
+
}
|
|
69
80
|
}
|
|
70
81
|
|
|
71
82
|
impl ReadStream {
|
|
@@ -5,13 +5,14 @@ use crate::tos_model::TosObject;
|
|
|
5
5
|
use crate::write_stream::WriteStream;
|
|
6
6
|
use async_trait::async_trait;
|
|
7
7
|
use futures_util::future::BoxFuture;
|
|
8
|
-
use pyo3::
|
|
8
|
+
use pyo3::prelude::PyDictMethods;
|
|
9
|
+
use pyo3::types::{PyDict, PyTuple};
|
|
10
|
+
use pyo3::{pyclass, pymethods, Bound, IntoPyObject, PyAny, PyObject, PyRef, PyRefMut, PyResult};
|
|
9
11
|
use std::future::Future;
|
|
10
12
|
use std::sync::atomic::{AtomicIsize, Ordering};
|
|
11
13
|
use std::sync::Arc;
|
|
12
14
|
use std::time::Duration;
|
|
13
|
-
use tokio::runtime;
|
|
14
|
-
use tokio::runtime::{Handle, Runtime};
|
|
15
|
+
use tokio::runtime::{Builder, Handle, Runtime};
|
|
15
16
|
use tracing_appender::non_blocking::WorkerGuard;
|
|
16
17
|
use ve_tos_rust_sdk::asynchronous::object::ObjectAPI;
|
|
17
18
|
use ve_tos_rust_sdk::asynchronous::tos;
|
|
@@ -54,7 +55,7 @@ impl AsyncRuntime for TokioRuntime {
|
|
|
54
55
|
pub(crate) type InnerTosClient =
|
|
55
56
|
TosClientImpl<CommonCredentialsProvider<CommonCredentials>, CommonCredentials, TokioRuntime>;
|
|
56
57
|
|
|
57
|
-
#[pyclass(name = "TosClient")]
|
|
58
|
+
#[pyclass(name = "TosClient", module = "tosnativeclient")]
|
|
58
59
|
pub struct TosClient {
|
|
59
60
|
rclient: Arc<InnerTosClient>,
|
|
60
61
|
wclient: Arc<InnerTosClient>,
|
|
@@ -76,6 +77,14 @@ pub struct TosClient {
|
|
|
76
77
|
max_retry_count: isize,
|
|
77
78
|
#[pyo3(get)]
|
|
78
79
|
max_prefetch_tasks: isize,
|
|
80
|
+
#[pyo3(get)]
|
|
81
|
+
directives: String,
|
|
82
|
+
#[pyo3(get)]
|
|
83
|
+
directory: String,
|
|
84
|
+
#[pyo3(get)]
|
|
85
|
+
file_name_prefix: String,
|
|
86
|
+
#[pyo3(get)]
|
|
87
|
+
shared_prefetch_tasks: isize,
|
|
79
88
|
}
|
|
80
89
|
|
|
81
90
|
#[pymethods]
|
|
@@ -98,10 +107,19 @@ impl TosClient {
|
|
|
98
107
|
) -> PyResult<Self> {
|
|
99
108
|
let mut _guard = None;
|
|
100
109
|
if directives != "" {
|
|
101
|
-
_guard = Some(init_tracing_log(
|
|
110
|
+
_guard = Some(init_tracing_log(
|
|
111
|
+
directives.clone(),
|
|
112
|
+
directory.clone(),
|
|
113
|
+
file_name_prefix.clone(),
|
|
114
|
+
));
|
|
102
115
|
}
|
|
103
116
|
|
|
104
|
-
let
|
|
117
|
+
let logical_cores = num_cpus::get();
|
|
118
|
+
let mut builder = Builder::new_multi_thread();
|
|
119
|
+
if logical_cores > 0 {
|
|
120
|
+
builder.worker_threads(logical_cores);
|
|
121
|
+
}
|
|
122
|
+
let runtime = Arc::new(builder.enable_all().build()?);
|
|
105
123
|
let mut clients = Vec::with_capacity(2);
|
|
106
124
|
for _ in 0..2 {
|
|
107
125
|
match tos::builder()
|
|
@@ -138,6 +156,10 @@ impl TosClient {
|
|
|
138
156
|
part_size,
|
|
139
157
|
max_retry_count,
|
|
140
158
|
max_prefetch_tasks,
|
|
159
|
+
directives,
|
|
160
|
+
directory,
|
|
161
|
+
file_name_prefix,
|
|
162
|
+
shared_prefetch_tasks,
|
|
141
163
|
})
|
|
142
164
|
}
|
|
143
165
|
|
|
@@ -188,22 +210,41 @@ impl TosClient {
|
|
|
188
210
|
|
|
189
211
|
#[pyo3(signature = (bucket, key, storage_class=None))]
|
|
190
212
|
pub fn put_object(
|
|
191
|
-
|
|
213
|
+
slf: PyRef<'_, Self>,
|
|
192
214
|
bucket: String,
|
|
193
215
|
key: String,
|
|
194
216
|
storage_class: Option<String>,
|
|
195
217
|
) -> PyResult<WriteStream> {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
218
|
+
let client = slf.wclient.clone();
|
|
219
|
+
let runtime = slf.runtime.clone();
|
|
220
|
+
let part_size = slf.part_size;
|
|
221
|
+
slf.py().allow_threads(|| {
|
|
222
|
+
runtime.clone().block_on(async move {
|
|
223
|
+
match WriteStream::new(client, runtime, bucket, key, storage_class, part_size).await
|
|
224
|
+
{
|
|
225
|
+
Err(ex) => Err(map_tos_error(ex)),
|
|
226
|
+
Ok(ws) => Ok(ws),
|
|
227
|
+
}
|
|
228
|
+
})
|
|
229
|
+
})
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
233
|
+
let py = slf.py();
|
|
234
|
+
let state = [
|
|
235
|
+
slf.region.clone().into_pyobject(py)?.into_any(),
|
|
236
|
+
slf.endpoint.clone().into_pyobject(py)?.into_any(),
|
|
237
|
+
slf.ak.clone().into_pyobject(py)?.into_any(),
|
|
238
|
+
slf.sk.clone().into_pyobject(py)?.into_any(),
|
|
239
|
+
slf.part_size.into_pyobject(py)?.into_any(),
|
|
240
|
+
slf.max_retry_count.into_pyobject(py)?.into_any(),
|
|
241
|
+
slf.max_prefetch_tasks.into_pyobject(py)?.into_any(),
|
|
242
|
+
"".into_pyobject(py)?.into_any(),
|
|
243
|
+
"".into_pyobject(py)?.into_any(),
|
|
244
|
+
"".into_pyobject(py)?.into_any(),
|
|
245
|
+
slf.shared_prefetch_tasks.into_pyobject(py)?.into_any(),
|
|
246
|
+
];
|
|
247
|
+
PyTuple::new(py, state)
|
|
207
248
|
}
|
|
208
249
|
}
|
|
209
250
|
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
use pyo3::exceptions::PyException;
|
|
2
|
-
use pyo3::
|
|
2
|
+
use pyo3::types::PyTuple;
|
|
3
|
+
use pyo3::{create_exception, pyclass, pymethods, Bound, IntoPyObject, PyErr, PyRef, PyResult};
|
|
3
4
|
use std::error::Error;
|
|
4
5
|
|
|
5
|
-
#[pyclass]
|
|
6
6
|
#[derive(Clone)]
|
|
7
|
+
#[pyclass(name = "TosError", module = "tosnativeclient")]
|
|
7
8
|
pub struct TosError {
|
|
8
9
|
#[pyo3(get)]
|
|
9
10
|
message: String,
|
|
@@ -43,6 +44,17 @@ impl TosError {
|
|
|
43
44
|
request_id,
|
|
44
45
|
}
|
|
45
46
|
}
|
|
47
|
+
|
|
48
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
49
|
+
let py = slf.py();
|
|
50
|
+
let state = [
|
|
51
|
+
slf.message.clone().into_pyobject(py)?.into_any(),
|
|
52
|
+
slf.status_code.clone().into_pyobject(py)?.into_any(),
|
|
53
|
+
slf.ec.clone().into_pyobject(py)?.into_any(),
|
|
54
|
+
slf.request_id.clone().into_pyobject(py)?.into_any(),
|
|
55
|
+
];
|
|
56
|
+
PyTuple::new(py, state)
|
|
57
|
+
}
|
|
46
58
|
}
|
|
47
59
|
|
|
48
60
|
create_exception!(tosnativeclient, TosException, PyException);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use pyo3::pyclass;
|
|
2
2
|
use ve_tos_rust_sdk::object::{HeadObjectOutput, ListObjectsType2Output};
|
|
3
3
|
|
|
4
|
-
#[pyclass(name = "ListObjectsResult")]
|
|
4
|
+
#[pyclass(name = "ListObjectsResult", module = "tosnativeclient")]
|
|
5
5
|
pub struct ListObjectsResult {
|
|
6
6
|
#[pyo3(get)]
|
|
7
7
|
contents: Vec<TosObject>,
|
|
@@ -33,7 +33,7 @@ impl ListObjectsResult {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
#[derive(Clone)]
|
|
36
|
-
#[pyclass(name = "TosObject")]
|
|
36
|
+
#[pyclass(name = "TosObject", module = "tosnativeclient")]
|
|
37
37
|
pub struct TosObject {
|
|
38
38
|
#[pyo3(get)]
|
|
39
39
|
pub(crate) bucket: String,
|
|
@@ -2,8 +2,10 @@ use crate::tos_client::{InnerTosClient, TokioRuntime};
|
|
|
2
2
|
use crate::tos_error::{map_error, map_tos_error};
|
|
3
3
|
use bytes::Buf;
|
|
4
4
|
use futures_util::StreamExt;
|
|
5
|
-
use pyo3::
|
|
5
|
+
use pyo3::types::PyTuple;
|
|
6
|
+
use pyo3::{pyclass, pymethods, Bound, IntoPyObject, PyRef, PyRefMut, PyResult};
|
|
6
7
|
use std::collections::HashMap;
|
|
8
|
+
use std::sync::atomic::{AtomicI8, Ordering};
|
|
7
9
|
use std::sync::Arc;
|
|
8
10
|
use tokio::runtime;
|
|
9
11
|
use tokio::runtime::Runtime;
|
|
@@ -11,7 +13,7 @@ use tokio::sync::Mutex;
|
|
|
11
13
|
use ve_tos_rust_sdk::asynchronous::object::{ObjectAPI, ObjectContent};
|
|
12
14
|
use ve_tos_rust_sdk::asynchronous::tos;
|
|
13
15
|
|
|
14
|
-
#[pyclass(name = "TosRawClient")]
|
|
16
|
+
#[pyclass(name = "TosRawClient", module = "tosnativeclient")]
|
|
15
17
|
pub struct TosRawClient {
|
|
16
18
|
client: Arc<InnerTosClient>,
|
|
17
19
|
runtime: Arc<Runtime>,
|
|
@@ -158,7 +160,7 @@ impl TosRawClient {
|
|
|
158
160
|
content_range: output.content_range().to_string(),
|
|
159
161
|
hash_crc64ecma: output.hash_crc64ecma(),
|
|
160
162
|
output: Arc::new(Mutex::new(output)),
|
|
161
|
-
runtime
|
|
163
|
+
runtime,
|
|
162
164
|
}),
|
|
163
165
|
}
|
|
164
166
|
})
|
|
@@ -218,9 +220,24 @@ impl TosRawClient {
|
|
|
218
220
|
})
|
|
219
221
|
})
|
|
220
222
|
}
|
|
223
|
+
|
|
224
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
225
|
+
let py = slf.py();
|
|
226
|
+
let state = [
|
|
227
|
+
slf.region.clone().into_pyobject(py)?.into_any(),
|
|
228
|
+
slf.endpoint.clone().into_pyobject(py)?.into_any(),
|
|
229
|
+
slf.ak.clone().into_pyobject(py)?.into_any(),
|
|
230
|
+
slf.sk.clone().into_pyobject(py)?.into_any(),
|
|
231
|
+
slf.connection_timeout.clone().into_pyobject(py)?.into_any(),
|
|
232
|
+
slf.request_timeout.clone().into_pyobject(py)?.into_any(),
|
|
233
|
+
slf.max_connections.clone().into_pyobject(py)?.into_any(),
|
|
234
|
+
slf.max_retry_count.clone().into_pyobject(py)?.into_any(),
|
|
235
|
+
];
|
|
236
|
+
PyTuple::new(py, state)
|
|
237
|
+
}
|
|
221
238
|
}
|
|
222
239
|
|
|
223
|
-
#[pyclass(name = "HeadObjectInput")]
|
|
240
|
+
#[pyclass(name = "HeadObjectInput", module = "tosnativeclient")]
|
|
224
241
|
pub struct HeadObjectInput {
|
|
225
242
|
#[pyo3(get, set)]
|
|
226
243
|
pub(crate) bucket: String,
|
|
@@ -241,9 +258,18 @@ impl HeadObjectInput {
|
|
|
241
258
|
version_id: version_id.to_string(),
|
|
242
259
|
})
|
|
243
260
|
}
|
|
261
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
262
|
+
let py = slf.py();
|
|
263
|
+
let state = [
|
|
264
|
+
slf.bucket.clone().into_pyobject(py)?.into_any(),
|
|
265
|
+
slf.key.clone().into_pyobject(py)?.into_any(),
|
|
266
|
+
slf.version_id.clone().into_pyobject(py)?.into_any(),
|
|
267
|
+
];
|
|
268
|
+
PyTuple::new(py, state)
|
|
269
|
+
}
|
|
244
270
|
}
|
|
245
271
|
|
|
246
|
-
#[pyclass(name = "HeadObjectOutput")]
|
|
272
|
+
#[pyclass(name = "HeadObjectOutput", module = "tosnativeclient")]
|
|
247
273
|
pub struct HeadObjectOutput {
|
|
248
274
|
#[pyo3(get)]
|
|
249
275
|
pub(crate) request_id: String,
|
|
@@ -261,7 +287,7 @@ pub struct HeadObjectOutput {
|
|
|
261
287
|
pub(crate) hash_crc64ecma: u64,
|
|
262
288
|
}
|
|
263
289
|
|
|
264
|
-
#[pyclass(name = "DeleteObjectInput")]
|
|
290
|
+
#[pyclass(name = "DeleteObjectInput", module = "tosnativeclient")]
|
|
265
291
|
pub struct DeleteObjectInput {
|
|
266
292
|
#[pyo3(get, set)]
|
|
267
293
|
pub(crate) bucket: String,
|
|
@@ -282,9 +308,18 @@ impl DeleteObjectInput {
|
|
|
282
308
|
version_id: version_id.to_string(),
|
|
283
309
|
})
|
|
284
310
|
}
|
|
311
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
312
|
+
let py = slf.py();
|
|
313
|
+
let state = [
|
|
314
|
+
slf.bucket.clone().into_pyobject(py)?.into_any(),
|
|
315
|
+
slf.key.clone().into_pyobject(py)?.into_any(),
|
|
316
|
+
slf.version_id.clone().into_pyobject(py)?.into_any(),
|
|
317
|
+
];
|
|
318
|
+
PyTuple::new(py, state)
|
|
319
|
+
}
|
|
285
320
|
}
|
|
286
321
|
|
|
287
|
-
#[pyclass(name = "DeleteObjectOutput")]
|
|
322
|
+
#[pyclass(name = "DeleteObjectOutput", module = "tosnativeclient")]
|
|
288
323
|
pub struct DeleteObjectOutput {
|
|
289
324
|
#[pyo3(get)]
|
|
290
325
|
pub(crate) request_id: String,
|
|
@@ -297,7 +332,7 @@ pub struct DeleteObjectOutput {
|
|
|
297
332
|
#[pyo3(get)]
|
|
298
333
|
pub(crate) version_id: String,
|
|
299
334
|
}
|
|
300
|
-
#[pyclass(name = "GetObjectInput")]
|
|
335
|
+
#[pyclass(name = "GetObjectInput", module = "tosnativeclient")]
|
|
301
336
|
pub struct GetObjectInput {
|
|
302
337
|
#[pyo3(get, set)]
|
|
303
338
|
pub(crate) bucket: String,
|
|
@@ -321,9 +356,19 @@ impl GetObjectInput {
|
|
|
321
356
|
range: range.to_string(),
|
|
322
357
|
})
|
|
323
358
|
}
|
|
359
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
360
|
+
let py = slf.py();
|
|
361
|
+
let state = [
|
|
362
|
+
slf.bucket.clone().into_pyobject(py)?.into_any(),
|
|
363
|
+
slf.key.clone().into_pyobject(py)?.into_any(),
|
|
364
|
+
slf.version_id.clone().into_pyobject(py)?.into_any(),
|
|
365
|
+
slf.range.clone().into_pyobject(py)?.into_any(),
|
|
366
|
+
];
|
|
367
|
+
PyTuple::new(py, state)
|
|
368
|
+
}
|
|
324
369
|
}
|
|
325
370
|
|
|
326
|
-
#[pyclass(name = "GetObjectOutput")]
|
|
371
|
+
#[pyclass(name = "GetObjectOutput", module = "tosnativeclient")]
|
|
327
372
|
pub struct GetObjectOutput {
|
|
328
373
|
#[pyo3(get)]
|
|
329
374
|
pub(crate) request_id: String,
|
|
@@ -350,30 +395,34 @@ impl GetObjectOutput {
|
|
|
350
395
|
pub fn read_all(slf: PyRefMut<'_, Self>) -> PyResult<Option<Vec<u8>>> {
|
|
351
396
|
let runtime = slf.runtime.clone();
|
|
352
397
|
let output = slf.output.clone();
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
398
|
+
slf.py().allow_threads(|| {
|
|
399
|
+
runtime.block_on(async move {
|
|
400
|
+
match output.lock().await.read_all().await {
|
|
401
|
+
Err(ex) => Err(map_tos_error(ex)),
|
|
402
|
+
Ok(buf) => Ok(Some(buf)),
|
|
403
|
+
}
|
|
404
|
+
})
|
|
358
405
|
})
|
|
359
406
|
}
|
|
360
407
|
|
|
361
408
|
pub fn read(slf: PyRefMut<'_, Self>) -> PyResult<Option<Vec<u8>>> {
|
|
362
409
|
let runtime = slf.runtime.clone();
|
|
363
410
|
let output = slf.output.clone();
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
411
|
+
slf.py().allow_threads(|| {
|
|
412
|
+
runtime.block_on(async move {
|
|
413
|
+
match output.lock().await.next().await {
|
|
414
|
+
None => Ok(None),
|
|
415
|
+
Some(result) => match result {
|
|
416
|
+
Err(ex) => Err(map_error(ex)),
|
|
417
|
+
Ok(buf) => Ok(Some(buf.chunk().to_vec())),
|
|
418
|
+
},
|
|
419
|
+
}
|
|
420
|
+
})
|
|
372
421
|
})
|
|
373
422
|
}
|
|
374
423
|
}
|
|
375
424
|
|
|
376
|
-
#[pyclass(name = "PutObjectFromBufferInput")]
|
|
425
|
+
#[pyclass(name = "PutObjectFromBufferInput", module = "tosnativeclient")]
|
|
377
426
|
pub struct PutObjectFromBufferInput {
|
|
378
427
|
#[pyo3(get, set)]
|
|
379
428
|
pub(crate) bucket: String,
|
|
@@ -394,9 +443,18 @@ impl PutObjectFromBufferInput {
|
|
|
394
443
|
content: content.to_vec(),
|
|
395
444
|
})
|
|
396
445
|
}
|
|
446
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
447
|
+
let py = slf.py();
|
|
448
|
+
let state = [
|
|
449
|
+
slf.bucket.clone().into_pyobject(py)?.into_any(),
|
|
450
|
+
slf.key.clone().into_pyobject(py)?.into_any(),
|
|
451
|
+
slf.content.clone().into_pyobject(py)?.into_any(),
|
|
452
|
+
];
|
|
453
|
+
PyTuple::new(py, state)
|
|
454
|
+
}
|
|
397
455
|
}
|
|
398
456
|
|
|
399
|
-
#[pyclass(name = "PutObjectFromFileInput")]
|
|
457
|
+
#[pyclass(name = "PutObjectFromFileInput", module = "tosnativeclient")]
|
|
400
458
|
pub struct PutObjectFromFileInput {
|
|
401
459
|
#[pyo3(get, set)]
|
|
402
460
|
pub(crate) bucket: String,
|
|
@@ -417,9 +475,18 @@ impl PutObjectFromFileInput {
|
|
|
417
475
|
file_path: file_path.to_string(),
|
|
418
476
|
})
|
|
419
477
|
}
|
|
478
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
479
|
+
let py = slf.py();
|
|
480
|
+
let state = [
|
|
481
|
+
slf.bucket.clone().into_pyobject(py)?.into_any(),
|
|
482
|
+
slf.key.clone().into_pyobject(py)?.into_any(),
|
|
483
|
+
slf.file_path.clone().into_pyobject(py)?.into_any(),
|
|
484
|
+
];
|
|
485
|
+
PyTuple::new(py, state)
|
|
486
|
+
}
|
|
420
487
|
}
|
|
421
488
|
|
|
422
|
-
#[pyclass(name = "PutObjectOutput")]
|
|
489
|
+
#[pyclass(name = "PutObjectOutput", module = "tosnativeclient")]
|
|
423
490
|
pub struct PutObjectOutput {
|
|
424
491
|
#[pyo3(get)]
|
|
425
492
|
pub(crate) request_id: String,
|
|
@@ -2,7 +2,8 @@ use crate::tos_client::InnerTosClient;
|
|
|
2
2
|
use crate::tos_error::map_tos_error;
|
|
3
3
|
use async_channel::{Receiver, Sender};
|
|
4
4
|
use futures_util::future::join_all;
|
|
5
|
-
use pyo3::
|
|
5
|
+
use pyo3::types::PyTuple;
|
|
6
|
+
use pyo3::{pyclass, pymethods, Bound, IntoPyObject, PyRef, PyRefMut, PyResult};
|
|
6
7
|
use std::collections::HashMap;
|
|
7
8
|
use std::sync::atomic::{AtomicI8, AtomicIsize, Ordering};
|
|
8
9
|
use std::sync::Arc;
|
|
@@ -29,7 +30,7 @@ const MAX_PART_NUMBER: isize = 10000;
|
|
|
29
30
|
const OTHER_MU_KICK_OFF: i8 = 1;
|
|
30
31
|
const RELEASE_MU_KICK_OFF: i8 = 2;
|
|
31
32
|
|
|
32
|
-
#[pyclass(name = "WriteStream")]
|
|
33
|
+
#[pyclass(name = "WriteStream", module = "tosnativeclient")]
|
|
33
34
|
pub struct WriteStream {
|
|
34
35
|
object_writer: Arc<ObjectWriter>,
|
|
35
36
|
runtime: Arc<Runtime>,
|
|
@@ -71,10 +72,20 @@ impl WriteStream {
|
|
|
71
72
|
Ok(_) => Ok(()),
|
|
72
73
|
}
|
|
73
74
|
}
|
|
75
|
+
|
|
76
|
+
pub fn __getnewargs__(slf: PyRef<'_, Self>) -> PyResult<Bound<'_, PyTuple>> {
|
|
77
|
+
let py = slf.py();
|
|
78
|
+
let state = [
|
|
79
|
+
slf.bucket.clone().into_pyobject(py)?.into_any(),
|
|
80
|
+
slf.key.clone().into_pyobject(py)?.into_any(),
|
|
81
|
+
slf.storage_class.clone().into_pyobject(py)?.into_any(),
|
|
82
|
+
];
|
|
83
|
+
PyTuple::new(py, state)
|
|
84
|
+
}
|
|
74
85
|
}
|
|
75
86
|
|
|
76
87
|
impl WriteStream {
|
|
77
|
-
pub(crate) fn new(
|
|
88
|
+
pub(crate) async fn new(
|
|
78
89
|
client: Arc<InnerTosClient>,
|
|
79
90
|
runtime: Arc<Runtime>,
|
|
80
91
|
bucket: String,
|
|
@@ -93,10 +104,8 @@ impl WriteStream {
|
|
|
93
104
|
let _key = key.clone();
|
|
94
105
|
let _storage_class = storage_class.clone();
|
|
95
106
|
|
|
96
|
-
let object_writer =
|
|
97
|
-
ObjectWriter::new(client, _bucket, _key, _storage_class, part_size).await
|
|
98
|
-
})?;
|
|
99
|
-
|
|
107
|
+
let object_writer =
|
|
108
|
+
ObjectWriter::new(client, _bucket, _key, _storage_class, part_size).await?;
|
|
100
109
|
Ok(Self {
|
|
101
110
|
object_writer: Arc::new(object_writer),
|
|
102
111
|
runtime,
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
from .tosnativeclient import TosClient, ListStream, ListObjectsResult, TosObject, TosError, TosException, TosRawClient, \
|
|
2
|
-
HeadObjectInput, HeadObjectOutput, GetObjectOutput, DeleteObjectInput, DeleteObjectOutput, GetObjectInput, \
|
|
3
|
-
PutObjectFromBufferInput, PutObjectFromFileInput, PutObjectOutput
|
|
4
|
-
|
|
5
|
-
__all__ = ['TosClient',
|
|
6
|
-
'ListStream',
|
|
7
|
-
'ListObjectsResult',
|
|
8
|
-
'TosObject',
|
|
9
|
-
'TosError',
|
|
10
|
-
'TosException',
|
|
11
|
-
'TosRawClient',
|
|
12
|
-
'HeadObjectInput',
|
|
13
|
-
'HeadObjectOutput',
|
|
14
|
-
'DeleteObjectInput',
|
|
15
|
-
'DeleteObjectOutput',
|
|
16
|
-
'GetObjectInput',
|
|
17
|
-
'GetObjectOutput',
|
|
18
|
-
'PutObjectFromBufferInput',
|
|
19
|
-
'PutObjectFromFileInput',
|
|
20
|
-
'PutObjectOutput'
|
|
21
|
-
]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|