Skip to content

Commit fa80504

Browse files
committed
feat(): add customize boto core config for OSS storage provider
1 parent 83f0f31 commit fa80504

1 file changed

Lines changed: 40 additions & 23 deletions

File tree

flow360/cloud/s3_utils.py

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@
88
from abc import ABCMeta, abstractmethod
99
from datetime import datetime
1010
from enum import Enum
11+
from typing import Optional
1112

1213
import boto3
1314
from boto3.s3.transfer import TransferConfig
14-
15+
from botocore.config import Config
1516
# pylint: disable=unused-import
1617
from botocore.exceptions import ClientError as CloudFileNotFoundError
1718
from pydantic.v1 import BaseModel, Field
@@ -110,12 +111,14 @@ class _UserCredential(BaseModel):
110111
expiration: datetime
111112
secret_access_key: str = Field(alias="secretAccessKey")
112113
session_token: str = Field(alias="sessionToken")
114+
storage_provider: Optional[str] = Field(alias="storageProvider", default=None)
113115

114116

115117
class _S3STSToken(BaseModel):
116118
cloud_path_prefix: str = Field(alias="cloudpathPrefix")
117119
cloud_path: str = Field(alias="cloudpath")
118120
user_credential: _UserCredential = Field(alias="userCredentials")
121+
endpoint: Optional[str] = Field(alias="endpoint", default=None)
119122

120123
def get_bucket(self):
121124
"""
@@ -138,14 +141,28 @@ def get_client(self):
138141
Get s3 client.
139142
:return:
140143
"""
144+
customize_boto3_config = None
145+
if (self.user_credential is not None
146+
and self.user_credential.storage_provider is not None
147+
and self.user_credential.storage_provider == "OSS"):
148+
# OSS does not support aws integrity check
149+
customize_boto3_config = Config(request_checksum_calculation="when_required",
150+
response_checksum_validation="when_required",
151+
s3={
152+
"addressing_style": "virtual"
153+
})
141154
# pylint: disable=no-member
142155
kwargs = {
143156
"region_name": Env.current.aws_region,
144157
"aws_access_key_id": self.user_credential.access_key_id,
145158
"aws_secret_access_key": self.user_credential.secret_access_key,
146159
"aws_session_token": self.user_credential.session_token,
160+
"config": customize_boto3_config
147161
}
148162

163+
if self.endpoint is not None:
164+
kwargs["endpoint_url"] = self.endpoint
165+
149166
if Env.current.s3_endpoint_url is not None:
150167
kwargs["endpoint_url"] = Env.current.s3_endpoint_url
151168

@@ -158,8 +175,8 @@ def is_expired(self):
158175
"""
159176
# pylint: disable=no-member
160177
return (
161-
self.user_credential.expiration
162-
- datetime.now(tz=self.user_credential.expiration.tzinfo)
178+
self.user_credential.expiration
179+
- datetime.now(tz=self.user_credential.expiration.tzinfo)
163180
).total_seconds() < 300
164181

165182

@@ -203,9 +220,9 @@ def get_cloud_path_prefix(self, resource_id, file_name):
203220
return base_path
204221

205222
def create_multipart_upload(
206-
self,
207-
resource_id: str,
208-
remote_file_name: str,
223+
self,
224+
resource_id: str,
225+
remote_file_name: str,
209226
):
210227
"""
211228
Creates a multipart upload for the specified resource ID and remote file name.
@@ -226,12 +243,12 @@ def create_multipart_upload(
226243

227244
# pylint: disable=too-many-arguments
228245
def upload_part(
229-
self,
230-
resource_id: str,
231-
remote_file_name: str,
232-
upload_id: str,
233-
part_number: int,
234-
compressed_chunk,
246+
self,
247+
resource_id: str,
248+
remote_file_name: str,
249+
upload_id: str,
250+
part_number: int,
251+
compressed_chunk,
235252
):
236253
"""
237254
Uploads a part of the file as part of a multipart upload.
@@ -260,7 +277,7 @@ def upload_part(
260277
return {"ETag": response["ETag"], "PartNumber": part_number}
261278

262279
def complete_multipart_upload(
263-
self, resource_id: str, remote_file_name: str, upload_id: str, uploaded_parts: dict
280+
self, resource_id: str, remote_file_name: str, upload_id: str, uploaded_parts: dict
264281
):
265282
"""
266283
Completes a multipart upload for the specified resource ID, remote file name, upload ID, e_tag, and part number.
@@ -285,7 +302,7 @@ def complete_multipart_upload(
285302
)
286303

287304
def upload_file(
288-
self, resource_id: str, remote_file_name: str, file_name: str, progress_callback=None
305+
self, resource_id: str, remote_file_name: str, file_name: str, progress_callback=None
289306
):
290307
"""
291308
Upload a file to s3.
@@ -328,15 +345,15 @@ def _call_back(bytes_in_chunk):
328345

329346
# pylint: disable=too-many-arguments
330347
def download_file(
331-
self,
332-
resource_id: str,
333-
remote_file_name: str,
334-
to_file: str = None,
335-
to_folder: str = ".",
336-
overwrite: bool = True,
337-
progress_callback=None,
338-
log_error=True,
339-
verbose=True,
348+
self,
349+
resource_id: str,
350+
remote_file_name: str,
351+
to_file: str = None,
352+
to_folder: str = ".",
353+
overwrite: bool = True,
354+
progress_callback=None,
355+
log_error=True,
356+
verbose=True,
340357
):
341358
"""
342359
Download a file from s3.

0 commit comments

Comments
 (0)