megfile 3.0.3__py3-none-any.whl → 3.0.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- megfile/config.py +9 -0
- megfile/errors.py +11 -3
- megfile/http_path.py +121 -11
- megfile/lib/base_prefetch_reader.py +2 -2
- megfile/lib/hdfs_prefetch_reader.py +2 -2
- megfile/lib/http_prefetch_reader.py +2 -2
- megfile/lib/s3_prefetch_reader.py +2 -2
- megfile/lib/s3_share_cache_reader.py +2 -2
- megfile/s3_path.py +15 -10
- megfile/sftp_path.py +2 -1
- megfile/version.py +1 -1
- {megfile-3.0.3.dist-info → megfile-3.0.5.dist-info}/METADATA +3 -3
- {megfile-3.0.3.dist-info → megfile-3.0.5.dist-info}/RECORD +18 -18
- {megfile-3.0.3.dist-info → megfile-3.0.5.dist-info}/LICENSE +0 -0
- {megfile-3.0.3.dist-info → megfile-3.0.5.dist-info}/LICENSE.pyre +0 -0
- {megfile-3.0.3.dist-info → megfile-3.0.5.dist-info}/WHEEL +0 -0
- {megfile-3.0.3.dist-info → megfile-3.0.5.dist-info}/entry_points.txt +0 -0
- {megfile-3.0.3.dist-info → megfile-3.0.5.dist-info}/top_level.txt +0 -0
megfile/config.py
CHANGED
|
@@ -7,6 +7,7 @@ DEFAULT_MAX_BUFFER_SIZE = int(
|
|
|
7
7
|
os.getenv('MEGFILE_MAX_BUFFER_SIZE') or DEFAULT_BLOCK_SIZE * 16) # 128MB
|
|
8
8
|
GLOBAL_MAX_WORKERS = int(os.getenv('MEGFILE_MAX_WORKERS') or 32)
|
|
9
9
|
DEFAULT_BLOCK_CAPACITY = int(os.getenv('MEGFILE_BLOCK_CAPACITY') or 16)
|
|
10
|
+
DEFAULT_MAX_RETRY_TIMES = int(os.getenv('MEGFILE_MAX_RETRY_TIMES') or 10)
|
|
10
11
|
|
|
11
12
|
# for logging the size of file had read or wrote
|
|
12
13
|
BACKOFF_INITIAL = 64 * 2**20 # 64MB
|
|
@@ -16,3 +17,11 @@ NEWLINE = ord('\n')
|
|
|
16
17
|
|
|
17
18
|
S3_CLIENT_CACHE_MODE = os.getenv(
|
|
18
19
|
'MEGFILE_S3_CLIENT_CACHE_MODE') or 'thread_local'
|
|
20
|
+
S3_MAX_RETRY_TIMES = int(
|
|
21
|
+
os.getenv('MEGFILE_S3_MAX_RETRY_TIMES') or DEFAULT_MAX_RETRY_TIMES)
|
|
22
|
+
HTTP_MAX_RETRY_TIMES = int(
|
|
23
|
+
os.getenv('MEGFILE_HTTP_MAX_RETRY_TIMES') or DEFAULT_MAX_RETRY_TIMES)
|
|
24
|
+
HDFS_MAX_RETRY_TIMES = int(
|
|
25
|
+
os.getenv('MEGFILE_HDFS_MAX_RETRY_TIMES') or DEFAULT_MAX_RETRY_TIMES)
|
|
26
|
+
SFTP_MAX_RETRY_TIMES = int(
|
|
27
|
+
os.getenv('MEGFILE_SFTP_MAX_RETRY_TIMES') or DEFAULT_MAX_RETRY_TIMES)
|
megfile/errors.py
CHANGED
|
@@ -75,7 +75,8 @@ def full_error_message(error):
|
|
|
75
75
|
|
|
76
76
|
|
|
77
77
|
def client_error_code(error: ClientError) -> str:
|
|
78
|
-
|
|
78
|
+
error_data = error.response.get('Error', {}) # pytype: disable=attribute-error
|
|
79
|
+
return error_data.get('Code') or error_data.get('code', 'Unknown')
|
|
79
80
|
|
|
80
81
|
|
|
81
82
|
def client_error_message(error: ClientError) -> str:
|
|
@@ -111,8 +112,15 @@ def s3_should_retry(error: Exception) -> bool:
|
|
|
111
112
|
return True
|
|
112
113
|
if isinstance(error, botocore.exceptions.ClientError):
|
|
113
114
|
return client_error_code(error) in (
|
|
114
|
-
'
|
|
115
|
-
'
|
|
115
|
+
'499', # Some cloud providers may send response with http code 499 if the connection not send data in 1 min.
|
|
116
|
+
'500',
|
|
117
|
+
'501',
|
|
118
|
+
'502',
|
|
119
|
+
'503',
|
|
120
|
+
'InternalError',
|
|
121
|
+
'ServiceUnavailable',
|
|
122
|
+
'SlowDown',
|
|
123
|
+
'ContextCanceled')
|
|
116
124
|
return False
|
|
117
125
|
|
|
118
126
|
|
megfile/http_path.py
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import io
|
|
2
1
|
import time
|
|
3
2
|
from functools import partial
|
|
4
|
-
from io import BufferedReader
|
|
3
|
+
from io import BufferedReader, BytesIO
|
|
5
4
|
from logging import getLogger as get_logger
|
|
5
|
+
from threading import Lock
|
|
6
6
|
from typing import Iterable, Iterator, Optional, Tuple, Union
|
|
7
7
|
|
|
8
8
|
import requests
|
|
9
|
+
from urllib3 import HTTPResponse
|
|
9
10
|
|
|
10
|
-
from megfile.config import DEFAULT_BLOCK_SIZE
|
|
11
|
+
from megfile.config import DEFAULT_BLOCK_SIZE, HTTP_MAX_RETRY_TIMES
|
|
11
12
|
from megfile.errors import http_should_retry, patch_method, translate_http_error
|
|
12
|
-
from megfile.interfaces import PathLike, StatResult, URIPath
|
|
13
|
+
from megfile.interfaces import PathLike, Readable, StatResult, URIPath
|
|
13
14
|
from megfile.lib.compat import fspath
|
|
14
15
|
from megfile.lib.http_prefetch_reader import HttpPrefetchReader
|
|
15
16
|
from megfile.lib.s3_buffered_writer import DEFAULT_MAX_BUFFER_SIZE
|
|
@@ -27,7 +28,7 @@ __all__ = [
|
|
|
27
28
|
]
|
|
28
29
|
|
|
29
30
|
_logger = get_logger(__name__)
|
|
30
|
-
max_retries =
|
|
31
|
+
max_retries = HTTP_MAX_RETRY_TIMES
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
def get_http_session(
|
|
@@ -81,7 +82,7 @@ def get_http_session(
|
|
|
81
82
|
return file_object
|
|
82
83
|
elif hasattr(file_object, 'name'):
|
|
83
84
|
with SmartPath(file_object.name).open('rb') as f:
|
|
84
|
-
return
|
|
85
|
+
return BytesIO(f.read())
|
|
85
86
|
else:
|
|
86
87
|
_logger.warning(
|
|
87
88
|
f'Can not retry http request, because the file object is not seekable and unsupport "name"'
|
|
@@ -213,8 +214,9 @@ class HttpPath(URIPath):
|
|
|
213
214
|
raise translate_http_error(error, self.path_with_protocol)
|
|
214
215
|
|
|
215
216
|
content_size = int(response.headers['Content-Length'])
|
|
216
|
-
if response.headers.get(
|
|
217
|
-
|
|
217
|
+
if (response.headers.get('Accept-Ranges') == 'bytes' and
|
|
218
|
+
content_size >= block_size * 2 and
|
|
219
|
+
not response.headers.get('Content-Encoding')):
|
|
218
220
|
response.close()
|
|
219
221
|
|
|
220
222
|
block_capacity = max_buffer_size // block_size
|
|
@@ -233,12 +235,15 @@ class HttpPath(URIPath):
|
|
|
233
235
|
block_size=block_size,
|
|
234
236
|
)
|
|
235
237
|
if _is_pickle(reader): # pytype: disable=wrong-arg-types
|
|
236
|
-
reader =
|
|
238
|
+
reader = BufferedReader(reader) # pytype: disable=wrong-arg-types
|
|
237
239
|
return reader
|
|
238
240
|
|
|
239
|
-
response.raw.auto_close = False
|
|
240
241
|
response.raw.name = self.path_with_protocol
|
|
241
|
-
|
|
242
|
+
# TODO: When python version must bigger than 3.10, use urllib3>=2.0.0 instead of 'Response'
|
|
243
|
+
# response.raw.auto_close = False
|
|
244
|
+
# response.raw.decode_content = True
|
|
245
|
+
# return BufferedReader(response.raw)
|
|
246
|
+
return BufferedReader(Response(response.raw)) # pytype: disable=wrong-arg-types
|
|
242
247
|
|
|
243
248
|
def stat(self, follow_symlinks=True) -> StatResult:
|
|
244
249
|
'''
|
|
@@ -316,3 +321,108 @@ class HttpPath(URIPath):
|
|
|
316
321
|
class HttpsPath(HttpPath):
|
|
317
322
|
|
|
318
323
|
protocol = "https"
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
class Response(Readable):
|
|
327
|
+
|
|
328
|
+
def __init__(self, raw: HTTPResponse) -> None:
|
|
329
|
+
super().__init__()
|
|
330
|
+
|
|
331
|
+
raw.auto_close = False
|
|
332
|
+
self._block_size = 128 * 2**10 # 128KB
|
|
333
|
+
self._raw = raw
|
|
334
|
+
self._offset = 0
|
|
335
|
+
self._buffer = BytesIO()
|
|
336
|
+
self._lock = Lock()
|
|
337
|
+
|
|
338
|
+
@property
|
|
339
|
+
def name(self):
|
|
340
|
+
return self._raw.name
|
|
341
|
+
|
|
342
|
+
@property
|
|
343
|
+
def mode(self):
|
|
344
|
+
return 'rb'
|
|
345
|
+
|
|
346
|
+
def tell(self) -> int:
|
|
347
|
+
return self._offset
|
|
348
|
+
|
|
349
|
+
def _clear_buffer(self) -> None:
|
|
350
|
+
self._buffer.seek(0)
|
|
351
|
+
self._buffer.truncate()
|
|
352
|
+
|
|
353
|
+
def read(self, size: Optional[int] = None) -> bytes:
|
|
354
|
+
if size == 0:
|
|
355
|
+
return b''
|
|
356
|
+
if size is not None and size < 0:
|
|
357
|
+
size = None
|
|
358
|
+
|
|
359
|
+
with self._lock:
|
|
360
|
+
while not size or self._buffer.tell() < size:
|
|
361
|
+
data = self._raw.read(self._block_size, decode_content=True)
|
|
362
|
+
if not data:
|
|
363
|
+
break
|
|
364
|
+
self._buffer.write(data)
|
|
365
|
+
self._buffer.seek(0)
|
|
366
|
+
content = self._buffer.read(size)
|
|
367
|
+
residue = self._buffer.read()
|
|
368
|
+
self._clear_buffer()
|
|
369
|
+
if residue:
|
|
370
|
+
self._buffer.write(residue)
|
|
371
|
+
self._offset += len(content)
|
|
372
|
+
return content
|
|
373
|
+
|
|
374
|
+
def readline(self, size: Optional[int] = None) -> bytes:
|
|
375
|
+
if size == 0:
|
|
376
|
+
return b''
|
|
377
|
+
if size is not None and size < 0:
|
|
378
|
+
size = None
|
|
379
|
+
|
|
380
|
+
with self._lock:
|
|
381
|
+
self._buffer.seek(0)
|
|
382
|
+
buffer = self._buffer.read()
|
|
383
|
+
self._clear_buffer()
|
|
384
|
+
if b'\n' in buffer:
|
|
385
|
+
content = buffer[:buffer.index(b'\n') + 1]
|
|
386
|
+
if size:
|
|
387
|
+
content = content[:size]
|
|
388
|
+
self._buffer.write(buffer[len(content):])
|
|
389
|
+
elif size and len(buffer) >= size:
|
|
390
|
+
content = buffer[:size]
|
|
391
|
+
self._buffer.write(buffer[size:])
|
|
392
|
+
else:
|
|
393
|
+
content = None
|
|
394
|
+
self._buffer.write(buffer)
|
|
395
|
+
while True:
|
|
396
|
+
if size and self._buffer.tell() >= size:
|
|
397
|
+
break
|
|
398
|
+
data = self._raw.read(self._block_size, decode_content=True)
|
|
399
|
+
if not data:
|
|
400
|
+
break
|
|
401
|
+
elif b"\n" in data:
|
|
402
|
+
last_content, residue = data.split(b"\n", 1)
|
|
403
|
+
self._buffer.write(last_content)
|
|
404
|
+
self._buffer.write(b"\n")
|
|
405
|
+
self._buffer.seek(0)
|
|
406
|
+
content = self._buffer.read()
|
|
407
|
+
self._clear_buffer()
|
|
408
|
+
if size and len(content) > size:
|
|
409
|
+
self._buffer.write(content[size:])
|
|
410
|
+
content = content[:size]
|
|
411
|
+
if residue:
|
|
412
|
+
self._buffer.write(residue)
|
|
413
|
+
break
|
|
414
|
+
else:
|
|
415
|
+
self._buffer.write(data)
|
|
416
|
+
|
|
417
|
+
if content is None:
|
|
418
|
+
self._buffer.seek(0)
|
|
419
|
+
content = self._buffer.read(size)
|
|
420
|
+
residue = self._buffer.read()
|
|
421
|
+
self._clear_buffer()
|
|
422
|
+
if residue:
|
|
423
|
+
self._buffer.write(residue)
|
|
424
|
+
self._offset += len(content)
|
|
425
|
+
return content
|
|
426
|
+
|
|
427
|
+
def _close(self) -> None:
|
|
428
|
+
return self._raw.close()
|
|
@@ -8,7 +8,7 @@ from math import ceil
|
|
|
8
8
|
from statistics import mean
|
|
9
9
|
from typing import Optional
|
|
10
10
|
|
|
11
|
-
from megfile.config import BACKOFF_FACTOR, BACKOFF_INITIAL, DEFAULT_BLOCK_CAPACITY, DEFAULT_BLOCK_SIZE, GLOBAL_MAX_WORKERS, NEWLINE
|
|
11
|
+
from megfile.config import BACKOFF_FACTOR, BACKOFF_INITIAL, DEFAULT_BLOCK_CAPACITY, DEFAULT_BLOCK_SIZE, DEFAULT_MAX_RETRY_TIMES, GLOBAL_MAX_WORKERS, NEWLINE
|
|
12
12
|
from megfile.interfaces import Readable, Seekable
|
|
13
13
|
from megfile.utils import get_human_size, process_local
|
|
14
14
|
|
|
@@ -39,7 +39,7 @@ class BasePrefetchReader(Readable, Seekable, ABC):
|
|
|
39
39
|
block_size: int = DEFAULT_BLOCK_SIZE,
|
|
40
40
|
block_capacity: int = DEFAULT_BLOCK_CAPACITY,
|
|
41
41
|
block_forward: Optional[int] = None,
|
|
42
|
-
max_retries: int =
|
|
42
|
+
max_retries: int = DEFAULT_MAX_RETRY_TIMES,
|
|
43
43
|
max_workers: Optional[int] = None,
|
|
44
44
|
**kwargs):
|
|
45
45
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
from io import BytesIO
|
|
2
2
|
from typing import Optional
|
|
3
3
|
|
|
4
|
-
from megfile.config import DEFAULT_BLOCK_CAPACITY, DEFAULT_BLOCK_SIZE
|
|
4
|
+
from megfile.config import DEFAULT_BLOCK_CAPACITY, DEFAULT_BLOCK_SIZE, HDFS_MAX_RETRY_TIMES
|
|
5
5
|
from megfile.errors import raise_hdfs_error
|
|
6
6
|
from megfile.lib.base_prefetch_reader import BasePrefetchReader
|
|
7
7
|
|
|
@@ -20,7 +20,7 @@ class HdfsPrefetchReader(BasePrefetchReader):
|
|
|
20
20
|
block_size: int = DEFAULT_BLOCK_SIZE,
|
|
21
21
|
block_capacity: int = DEFAULT_BLOCK_CAPACITY,
|
|
22
22
|
block_forward: Optional[int] = None,
|
|
23
|
-
max_retries: int =
|
|
23
|
+
max_retries: int = HDFS_MAX_RETRY_TIMES,
|
|
24
24
|
max_workers: Optional[int] = None,
|
|
25
25
|
profile_name: Optional[str] = None):
|
|
26
26
|
self._path = hdfs_path
|
|
@@ -4,7 +4,7 @@ from typing import Optional
|
|
|
4
4
|
|
|
5
5
|
import requests
|
|
6
6
|
|
|
7
|
-
from megfile.config import DEFAULT_BLOCK_CAPACITY, DEFAULT_BLOCK_SIZE
|
|
7
|
+
from megfile.config import DEFAULT_BLOCK_CAPACITY, DEFAULT_BLOCK_SIZE, HTTP_MAX_RETRY_TIMES
|
|
8
8
|
from megfile.errors import UnsupportedError, http_should_retry, patch_method
|
|
9
9
|
from megfile.lib.base_prefetch_reader import BasePrefetchReader
|
|
10
10
|
|
|
@@ -25,7 +25,7 @@ class HttpPrefetchReader(BasePrefetchReader):
|
|
|
25
25
|
block_size: int = DEFAULT_BLOCK_SIZE,
|
|
26
26
|
block_capacity: int = DEFAULT_BLOCK_CAPACITY,
|
|
27
27
|
block_forward: Optional[int] = None,
|
|
28
|
-
max_retries: int =
|
|
28
|
+
max_retries: int = HTTP_MAX_RETRY_TIMES,
|
|
29
29
|
max_workers: Optional[int] = None):
|
|
30
30
|
|
|
31
31
|
self._url = url
|
|
@@ -3,7 +3,7 @@ from concurrent.futures import Future
|
|
|
3
3
|
from io import BytesIO
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
|
-
from megfile.config import BACKOFF_FACTOR, BACKOFF_INITIAL, DEFAULT_BLOCK_CAPACITY, DEFAULT_BLOCK_SIZE, GLOBAL_MAX_WORKERS, NEWLINE
|
|
6
|
+
from megfile.config import BACKOFF_FACTOR, BACKOFF_INITIAL, DEFAULT_BLOCK_CAPACITY, DEFAULT_BLOCK_SIZE, GLOBAL_MAX_WORKERS, NEWLINE, S3_MAX_RETRY_TIMES
|
|
7
7
|
from megfile.errors import S3FileChangedError, S3InvalidRangeError, patch_method, raise_s3_error, s3_should_retry
|
|
8
8
|
from megfile.lib.base_prefetch_reader import BasePrefetchReader, LRUCacheFutureManager
|
|
9
9
|
|
|
@@ -34,7 +34,7 @@ class S3PrefetchReader(BasePrefetchReader):
|
|
|
34
34
|
block_size: int = DEFAULT_BLOCK_SIZE,
|
|
35
35
|
block_capacity: int = DEFAULT_BLOCK_CAPACITY,
|
|
36
36
|
block_forward: Optional[int] = None,
|
|
37
|
-
max_retries: int =
|
|
37
|
+
max_retries: int = S3_MAX_RETRY_TIMES,
|
|
38
38
|
max_workers: Optional[int] = None,
|
|
39
39
|
profile_name: Optional[str] = None):
|
|
40
40
|
|
|
@@ -3,7 +3,7 @@ from concurrent.futures import Future
|
|
|
3
3
|
from logging import getLogger as get_logger
|
|
4
4
|
from typing import Optional
|
|
5
5
|
|
|
6
|
-
from megfile.config import DEFAULT_BLOCK_CAPACITY, DEFAULT_BLOCK_SIZE
|
|
6
|
+
from megfile.config import DEFAULT_BLOCK_CAPACITY, DEFAULT_BLOCK_SIZE, S3_MAX_RETRY_TIMES
|
|
7
7
|
from megfile.lib.s3_prefetch_reader import LRUCacheFutureManager, S3PrefetchReader
|
|
8
8
|
from megfile.utils import thread_local
|
|
9
9
|
|
|
@@ -25,7 +25,7 @@ class S3ShareCacheReader(S3PrefetchReader):
|
|
|
25
25
|
block_size: int = DEFAULT_BLOCK_SIZE,
|
|
26
26
|
block_capacity: int = DEFAULT_BLOCK_CAPACITY,
|
|
27
27
|
block_forward: Optional[int] = None,
|
|
28
|
-
max_retries: int =
|
|
28
|
+
max_retries: int = S3_MAX_RETRY_TIMES,
|
|
29
29
|
cache_key: str = 'lru',
|
|
30
30
|
max_workers: Optional[int] = None,
|
|
31
31
|
profile_name: Optional[str] = None):
|
megfile/s3_path.py
CHANGED
|
@@ -12,7 +12,7 @@ import boto3
|
|
|
12
12
|
import botocore
|
|
13
13
|
from botocore.awsrequest import AWSResponse
|
|
14
14
|
|
|
15
|
-
from megfile.config import DEFAULT_BLOCK_SIZE, GLOBAL_MAX_WORKERS, S3_CLIENT_CACHE_MODE
|
|
15
|
+
from megfile.config import DEFAULT_BLOCK_SIZE, GLOBAL_MAX_WORKERS, S3_CLIENT_CACHE_MODE, S3_MAX_RETRY_TIMES
|
|
16
16
|
from megfile.errors import S3BucketNotFoundError, S3ConfigError, S3FileExistsError, S3FileNotFoundError, S3IsADirectoryError, S3NameTooLongError, S3NotADirectoryError, S3NotALinkError, S3PermissionError, S3UnknownError, SameFileError, UnsupportedError, _create_missing_ok_generator
|
|
17
17
|
from megfile.errors import _logger as error_logger
|
|
18
18
|
from megfile.errors import patch_method, raise_s3_error, s3_error_code_should_retry, s3_should_retry, translate_fs_error, translate_s3_error
|
|
@@ -69,7 +69,7 @@ _logger = get_logger(__name__)
|
|
|
69
69
|
content_md5_header = 'megfile-content-md5'
|
|
70
70
|
endpoint_url = 'https://s3.amazonaws.com'
|
|
71
71
|
max_pool_connections = GLOBAL_MAX_WORKERS # for compatibility
|
|
72
|
-
max_retries =
|
|
72
|
+
max_retries = S3_MAX_RETRY_TIMES
|
|
73
73
|
max_keys = 1000
|
|
74
74
|
|
|
75
75
|
|
|
@@ -138,15 +138,20 @@ def get_endpoint_url(profile_name: Optional[str] = None) -> str:
|
|
|
138
138
|
|
|
139
139
|
:returns: S3 endpoint url
|
|
140
140
|
'''
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
141
|
+
if profile_name:
|
|
142
|
+
environ_keys = (f'{profile_name}__OSS_ENDPOINT'.upper(),)
|
|
143
|
+
else:
|
|
144
|
+
environ_keys = (
|
|
145
|
+
'OSS_ENDPOINT', 'AWS_ENDPOINT_URL_S3', 'AWS_ENDPOINT_URL')
|
|
146
|
+
for environ_key in environ_keys:
|
|
147
|
+
environ_endpoint_url = os.environ.get(environ_key)
|
|
148
|
+
if environ_endpoint_url:
|
|
149
|
+
warning_endpoint_url(environ_key, environ_endpoint_url)
|
|
150
|
+
return environ_endpoint_url
|
|
147
151
|
try:
|
|
148
|
-
|
|
149
|
-
|
|
152
|
+
config = get_scoped_config(profile_name=profile_name)
|
|
153
|
+
config_endpoint_url = config.get('s3', {}).get('endpoint_url')
|
|
154
|
+
config_endpoint_url = config_endpoint_url or config.get('endpoint_url')
|
|
150
155
|
if config_endpoint_url:
|
|
151
156
|
warning_endpoint_url('~/.aws/config', config_endpoint_url)
|
|
152
157
|
return config_endpoint_url
|
megfile/sftp_path.py
CHANGED
|
@@ -14,6 +14,7 @@ from urllib.parse import urlsplit, urlunsplit
|
|
|
14
14
|
|
|
15
15
|
import paramiko
|
|
16
16
|
|
|
17
|
+
from megfile.config import SFTP_MAX_RETRY_TIMES
|
|
17
18
|
from megfile.errors import SameFileError, _create_missing_ok_generator, patch_method
|
|
18
19
|
from megfile.interfaces import ContextIterator, FileEntry, PathLike, StatResult
|
|
19
20
|
from megfile.lib.compare import is_same_file
|
|
@@ -47,7 +48,7 @@ SFTP_PRIVATE_KEY_PATH = "SFTP_PRIVATE_KEY_PATH"
|
|
|
47
48
|
SFTP_PRIVATE_KEY_TYPE = "SFTP_PRIVATE_KEY_TYPE"
|
|
48
49
|
SFTP_PRIVATE_KEY_PASSWORD = "SFTP_PRIVATE_KEY_PASSWORD"
|
|
49
50
|
SFTP_MAX_UNAUTH_CONN = "SFTP_MAX_UNAUTH_CONN"
|
|
50
|
-
MAX_RETRIES =
|
|
51
|
+
MAX_RETRIES = SFTP_MAX_RETRY_TIMES
|
|
51
52
|
DEFAULT_SSH_CONNECT_TIMEOUT = 5
|
|
52
53
|
DEFAULT_SSH_KEEPALIVE_INTERVAL = 15
|
|
53
54
|
|
megfile/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
VERSION = "3.0.
|
|
1
|
+
VERSION = "3.0.5"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: megfile
|
|
3
|
-
Version: 3.0.
|
|
3
|
+
Version: 3.0.5
|
|
4
4
|
Summary: Megvii file operation library
|
|
5
5
|
Home-page: https://github.com/megvii-research/megfile
|
|
6
6
|
Author: megvii
|
|
@@ -160,10 +160,10 @@ Using `s3` as an example, the following describes the configuration methods. For
|
|
|
160
160
|
You can use environments and configuration file for configuration, and priority is that environment variables take precedence over configuration file.
|
|
161
161
|
|
|
162
162
|
### Use environments
|
|
163
|
-
You can use environments to setup authentication credentials for your s3 account:
|
|
163
|
+
You can use environments to setup authentication credentials for your `s3` account:
|
|
164
164
|
- `AWS_ACCESS_KEY_ID`: access key
|
|
165
165
|
- `AWS_SECRET_ACCESS_KEY`: secret key
|
|
166
|
-
- `OSS_ENDPOINT`: endpoint url of s3
|
|
166
|
+
- `OSS_ENDPOINT` / `AWS_ENDPOINT_URL_S3` / `AWS_ENDPOINT_URL`: endpoint url of s3
|
|
167
167
|
- `AWS_S3_ADDRESSING_STYLE`: addressing style
|
|
168
168
|
|
|
169
169
|
### Use command
|
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
megfile/__init__.py,sha256=MT8SIXsmEUvtSpd1GHv6e3fFfR1gRnlEdkNNqv3gngo,6534
|
|
2
2
|
megfile/cli.py,sha256=yB2VnSaxrjNS67KL6CYRaMo72VNgyvuxCXuSfcGu6hM,21880
|
|
3
|
-
megfile/config.py,sha256=
|
|
4
|
-
megfile/errors.py,sha256=
|
|
3
|
+
megfile/config.py,sha256=YeLuxsFoJz6ZmZq7Pufe_021PeRWs4H6GN-v0MvsV6E,1136
|
|
4
|
+
megfile/errors.py,sha256=SXaFhPj7Prgt0Zp904g949aP225rngThDho1JAEXI7U,13571
|
|
5
5
|
megfile/fs.py,sha256=OfY0z4GSl8fT3mDGdeqP2hWFsd1QJl-h8RkSbg6-M8I,11547
|
|
6
6
|
megfile/fs_path.py,sha256=sHn-sBcvq7SvYN71onkA_ssLs71NzM1MM3d3Sug8uzo,38237
|
|
7
7
|
megfile/hdfs.py,sha256=aAkHobOO0nDcLoqj0tx_1tvgoLOCooTWuukq0pO-nQA,9156
|
|
8
8
|
megfile/hdfs_path.py,sha256=obfMMKSuBcSGgtEN18jXhEldm4hawMhxk8QoRv4k790,26859
|
|
9
9
|
megfile/http.py,sha256=a3oAuARSSaIU8VMx86Mui0N5Vh-EI0AoHnwxRU5DSMU,2032
|
|
10
|
-
megfile/http_path.py,sha256=
|
|
10
|
+
megfile/http_path.py,sha256=moBUIJmAeOKshi8AVm4OAyk9lGWM4HzOrH5BNFeqc1o,15466
|
|
11
11
|
megfile/interfaces.py,sha256=h3tWE8hVt5S-HopaMAX6lunPJ97vzhv6jH_2HubcDNc,6219
|
|
12
12
|
megfile/pathlike.py,sha256=Ere6tMf2nsI7bDsZo0WBzl_2HRrS_4iKOpYp0zZltAU,29487
|
|
13
13
|
megfile/s3.py,sha256=siBZfveWX1TDA4Mp41UvugcG3zlrhl_iPUbixUp1TmI,12352
|
|
14
|
-
megfile/s3_path.py,sha256=
|
|
14
|
+
megfile/s3_path.py,sha256=Bj1U70pCiVoikf-FcC5Z2hbcV177Qo7n5plnt5K44uE,91341
|
|
15
15
|
megfile/sftp.py,sha256=JCkF2v1ZbHuIy_Bg3l85AesjFDimDzx9Gh1gRoMsahc,12524
|
|
16
|
-
megfile/sftp_path.py,sha256=
|
|
16
|
+
megfile/sftp_path.py,sha256=Fe6yMiolhiAOdvpnT1DeixtLludhsGTKwvAo9yk3SZc,51732
|
|
17
17
|
megfile/smart.py,sha256=y5Dzr7_f0jS2FJDF4tWbEO4SPf39zqYftqkVgMhiJds,33725
|
|
18
18
|
megfile/smart_path.py,sha256=Y0UFh4J2ccydRY2W-wX2ubaf9zzJx1M2nf-VLBGe4mk,6749
|
|
19
19
|
megfile/stdio.py,sha256=yRhlfUA2DHi3bq-9cXsSlbLCnHvS_zvglO2IYYyPsGc,707
|
|
20
20
|
megfile/stdio_path.py,sha256=eQulTXUwHvUKA-5PKCGfVNiEPkJhG9YtVhtU58OcmoM,2873
|
|
21
|
-
megfile/version.py,sha256=
|
|
21
|
+
megfile/version.py,sha256=GG6OWfWAjPQ5lWwRUMjdZhwT0vYC3rWZeMCsigOCJXA,19
|
|
22
22
|
megfile/lib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
|
-
megfile/lib/base_prefetch_reader.py,sha256=
|
|
23
|
+
megfile/lib/base_prefetch_reader.py,sha256=rrHB9FdVX_MKOJD2lGZ00LruTjRY9u0Hj4UdI-CxNO0,13231
|
|
24
24
|
megfile/lib/combine_reader.py,sha256=XFSqEY5A5X5Uf7eQ6AXAzrvNteESSXvKNVPktGjo3KY,4546
|
|
25
25
|
megfile/lib/compare.py,sha256=yG2fZve_gMg32rQVCdwixBdqgYRsjn-24TqhALQaOrA,2233
|
|
26
26
|
megfile/lib/compat.py,sha256=0wt3_atcYhSLCxUj_WuDlQa3E1atjZfwJQ12thiFh5Q,234
|
|
27
27
|
megfile/lib/fnmatch.py,sha256=HgdlnEWBsdFUOZqnW_v1kj1jeH_9lMcCqW85pyMu4vM,4054
|
|
28
28
|
megfile/lib/glob.py,sha256=7i9dIput9rI9JIPyTZX-JDmFS7IP_THlX1k-35foAfw,9732
|
|
29
|
-
megfile/lib/hdfs_prefetch_reader.py,sha256=
|
|
29
|
+
megfile/lib/hdfs_prefetch_reader.py,sha256=50oVBNmEB8KRNwHnyDzxpxvwNABWxbOaIjyiTkmcemU,2080
|
|
30
30
|
megfile/lib/hdfs_tools.py,sha256=t4GeoBxO0HPahIQDrsK17WBsLZtcfAaNwWfappzZ5q8,442
|
|
31
|
-
megfile/lib/http_prefetch_reader.py,sha256=
|
|
31
|
+
megfile/lib/http_prefetch_reader.py,sha256=nD1EN5OmdC7yaL60TC0PA1He48OA8FSH90xDQl3T98E,3392
|
|
32
32
|
megfile/lib/joinpath.py,sha256=D4Px6-lnDDpYs1LMUHkTIGqMPJQ0oCBGfTzREs373iU,929
|
|
33
33
|
megfile/lib/lazy_handler.py,sha256=f1rip2_T57vVo0WRNXve2bAa4LArvVheMfQg1S0vFzg,1915
|
|
34
34
|
megfile/lib/s3_buffered_writer.py,sha256=ZvCtaJsGZdFy-8K6EMHFakzu3oIKXnKof-a6nBa6AY4,7017
|
|
@@ -36,17 +36,17 @@ megfile/lib/s3_cached_handler.py,sha256=xuWiThi6pJtGL_ErSBmcu8rDv1XyXNmEhiFBnRF4
|
|
|
36
36
|
megfile/lib/s3_limited_seekable_writer.py,sha256=14gySEdbS349hpSdUcX5uvRr93HACv7BRZbgIki4b34,6150
|
|
37
37
|
megfile/lib/s3_memory_handler.py,sha256=6Tj89xzc8z-FycVggGpjF_8lEbPsqRVB6undZwWsugo,3971
|
|
38
38
|
megfile/lib/s3_pipe_handler.py,sha256=hG8sEajO9dv9bLTeXsERxDioHHhzi4t8NC61lSbYk94,3557
|
|
39
|
-
megfile/lib/s3_prefetch_reader.py,sha256=
|
|
40
|
-
megfile/lib/s3_share_cache_reader.py,sha256=
|
|
39
|
+
megfile/lib/s3_prefetch_reader.py,sha256=iLvPaJGlJHaZ6jcyNPf-8A8URJgoJ0RN0C1YD--6wZ4,4285
|
|
40
|
+
megfile/lib/s3_share_cache_reader.py,sha256=jyx6f3LAR05qtf-qq_RTu8wE6wqTrqg4qkwWRSdPGQ4,3600
|
|
41
41
|
megfile/lib/shadow_handler.py,sha256=IbFyTw107t-yWH0cGrDjAJX-CS3xeEr77_PTGsnSgk4,2683
|
|
42
42
|
megfile/lib/stdio_handler.py,sha256=QDWtcZxz-hzi-rqQUiSlR3NrihX1fjK_Rj9T2mdTFEg,2044
|
|
43
43
|
megfile/lib/url.py,sha256=VbQLjo0s4AaV0iSk66BcjI68aUTcN9zBZ5x6-cM4Qvs,103
|
|
44
44
|
megfile/utils/__init__.py,sha256=xrBIJcVJTb_yR68ekAyd9u4HQ46s3xgIjUZoH_Lx7hU,9531
|
|
45
45
|
megfile/utils/mutex.py,sha256=-2KH3bNovKRd9zvsXq9n3bWM7rQdoG9hO7tUPxVG_Po,2538
|
|
46
|
-
megfile-3.0.
|
|
47
|
-
megfile-3.0.
|
|
48
|
-
megfile-3.0.
|
|
49
|
-
megfile-3.0.
|
|
50
|
-
megfile-3.0.
|
|
51
|
-
megfile-3.0.
|
|
52
|
-
megfile-3.0.
|
|
46
|
+
megfile-3.0.5.dist-info/LICENSE,sha256=WNHhf_5RCaeuKWyq_K39vmp9F28LxKsB4SpomwSZ2L0,11357
|
|
47
|
+
megfile-3.0.5.dist-info/LICENSE.pyre,sha256=9lf5nT-5ZH25JijpYAequ0bl8E8z5JmZB1qrjiUMp84,1080
|
|
48
|
+
megfile-3.0.5.dist-info/METADATA,sha256=vE3zfEswG2nEZ37V493PCznwEdsGg90C7Zq-sVdytg0,8963
|
|
49
|
+
megfile-3.0.5.dist-info/WHEEL,sha256=oiQVh_5PnQM0E3gPdiz09WCNmwiHDMaGer_elqB3coM,92
|
|
50
|
+
megfile-3.0.5.dist-info/entry_points.txt,sha256=M6ZWSSv5_5_QtIpZafy3vq7WuOJ_5dSGQQnEZbByt2Q,49
|
|
51
|
+
megfile-3.0.5.dist-info/top_level.txt,sha256=i3rMgdU1ZAJekAceojhA-bkm3749PzshtRmLTbeLUPQ,8
|
|
52
|
+
megfile-3.0.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|