iker-python-common 1.0.58__tar.gz → 1.0.59__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.
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/PKG-INFO +1 -3
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/pyproject.toml +0 -4
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/shutils.py +9 -5
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker_python_common.egg-info/PKG-INFO +1 -3
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker_python_common.egg-info/SOURCES.txt +0 -12
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker_python_common.egg-info/requires.txt +0 -2
- iker_python_common-1.0.58/resources/unittest/shutils/dir.baz/file.bar.baz +0 -0
- iker_python_common-1.0.58/resources/unittest/shutils/dir.baz/file.foo.bar +0 -0
- iker_python_common-1.0.58/resources/unittest/shutils/dir.baz/file.foo.baz +0 -0
- iker_python_common-1.0.58/resources/unittest/shutils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
- iker_python_common-1.0.58/resources/unittest/shutils/dir.foo/dir.foo.bar/file.bar.baz +0 -0
- iker_python_common-1.0.58/resources/unittest/shutils/dir.foo/dir.foo.bar/file.foo.bar +0 -0
- iker_python_common-1.0.58/resources/unittest/shutils/dir.foo/dir.foo.bar/file.foo.baz +0 -0
- iker_python_common-1.0.58/resources/unittest/shutils/dir.foo/file.bar +0 -0
- iker_python_common-1.0.58/resources/unittest/shutils/dir.foo/file.baz +0 -0
- iker_python_common-1.0.58/resources/unittest/shutils/dir.foo/file.foo +0 -0
- iker_python_common-1.0.58/src/iker/common/utils/s3utils.py +0 -270
- iker_python_common-1.0.58/test/iker_tests/common/utils/s3utils_test.py +0 -422
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/.editorconfig +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/.github/workflows/pr.yml +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/.github/workflows/push.yml +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/.gitignore +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/MANIFEST.in +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/README.md +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/VERSION +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/resources/unittest/config/config.cfg +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/resources/unittest/csv/data.csv +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/resources/unittest/csv/data.tsv +0 -0
- {iker_python_common-1.0.58/resources/unittest/s3utils → iker_python_common-1.0.59/resources/unittest/shutils}/dir.baz/file.bar.baz +0 -0
- {iker_python_common-1.0.58/resources/unittest/s3utils → iker_python_common-1.0.59/resources/unittest/shutils}/dir.baz/file.foo.bar +0 -0
- {iker_python_common-1.0.58/resources/unittest/s3utils → iker_python_common-1.0.59/resources/unittest/shutils}/dir.baz/file.foo.baz +0 -0
- {iker_python_common-1.0.58/resources/unittest/s3utils → iker_python_common-1.0.59/resources/unittest/shutils}/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz +0 -0
- {iker_python_common-1.0.58/resources/unittest/s3utils → iker_python_common-1.0.59/resources/unittest/shutils}/dir.foo/dir.foo.bar/file.bar.baz +0 -0
- {iker_python_common-1.0.58/resources/unittest/s3utils → iker_python_common-1.0.59/resources/unittest/shutils}/dir.foo/dir.foo.bar/file.foo.bar +0 -0
- {iker_python_common-1.0.58/resources/unittest/s3utils → iker_python_common-1.0.59/resources/unittest/shutils}/dir.foo/dir.foo.bar/file.foo.baz +0 -0
- {iker_python_common-1.0.58/resources/unittest/s3utils → iker_python_common-1.0.59/resources/unittest/shutils}/dir.foo/file.bar +0 -0
- {iker_python_common-1.0.58/resources/unittest/s3utils → iker_python_common-1.0.59/resources/unittest/shutils}/dir.foo/file.baz +0 -0
- {iker_python_common-1.0.58/resources/unittest/s3utils → iker_python_common-1.0.59/resources/unittest/shutils}/dir.foo/file.foo +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/setup.cfg +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/setup.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/__init__.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/__init__.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/argutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/config.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/csv.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/dbutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/dockerutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/dtutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/funcutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/jsonutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/logger.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/numutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/randutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/retry.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/sequtils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/span.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/strutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/testutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/typeutils.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker_python_common.egg-info/dependency_links.txt +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker_python_common.egg-info/not-zip-safe +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker_python_common.egg-info/top_level.txt +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/__init__.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/argutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/config_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/csv_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/dbutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/dockerutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/dtutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/funcutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/jsonutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/logger_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/numutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/randutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/retry_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/sequtils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/shutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/span_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/strutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/testutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/typeutils_test.py +0 -0
- {iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/docker_fixtures.py +0 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iker-python-common
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.59
|
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.12
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.13
|
|
7
7
|
Classifier: Programming Language :: Python :: 3.14
|
|
8
8
|
Requires-Python: <3.15,>=3.12
|
|
9
|
-
Requires-Dist: boto3>=1.35
|
|
10
9
|
Requires-Dist: docker>=7.1
|
|
11
10
|
Requires-Dist: numpy>=2.3
|
|
12
11
|
Requires-Dist: psycopg>=3.2
|
|
@@ -16,7 +15,6 @@ Provides-Extra: all
|
|
|
16
15
|
Requires-Dist: iker-python-common; extra == "all"
|
|
17
16
|
Provides-Extra: test
|
|
18
17
|
Requires-Dist: ddt>=1.7; extra == "test"
|
|
19
|
-
Requires-Dist: moto[all,ec2,s3]>=5.0; extra == "test"
|
|
20
18
|
Requires-Dist: pytest-cov>=5.0; extra == "test"
|
|
21
19
|
Requires-Dist: pytest-mysql>=3.0; extra == "test"
|
|
22
20
|
Requires-Dist: pytest-order>=1.3; extra == "test"
|
|
@@ -8,7 +8,6 @@ build-backend = "setuptools.build_meta"
|
|
|
8
8
|
|
|
9
9
|
[dependency-groups]
|
|
10
10
|
dev = [
|
|
11
|
-
"boto3>=1.35",
|
|
12
11
|
"docker>=7.1",
|
|
13
12
|
"numpy>=2.3",
|
|
14
13
|
"psycopg>=3.2",
|
|
@@ -17,7 +16,6 @@ dev = [
|
|
|
17
16
|
]
|
|
18
17
|
test = [
|
|
19
18
|
"ddt>=1.7",
|
|
20
|
-
"moto[ec2,s3,all]>=5.0",
|
|
21
19
|
"pytest-cov>=5.0",
|
|
22
20
|
"pytest-mysql>=3.0",
|
|
23
21
|
"pytest-order>=1.3",
|
|
@@ -36,7 +34,6 @@ classifiers = [
|
|
|
36
34
|
"Programming Language :: Python :: 3.14",
|
|
37
35
|
]
|
|
38
36
|
dependencies = [
|
|
39
|
-
"boto3>=1.35",
|
|
40
37
|
"docker>=7.1",
|
|
41
38
|
"numpy>=2.3",
|
|
42
39
|
"psycopg>=3.2",
|
|
@@ -50,7 +47,6 @@ all = [
|
|
|
50
47
|
]
|
|
51
48
|
test = [
|
|
52
49
|
"ddt>=1.7",
|
|
53
|
-
"moto[ec2,s3,all]>=5.0",
|
|
54
50
|
"pytest-cov>=5.0",
|
|
55
51
|
"pytest-mysql>=3.0",
|
|
56
52
|
"pytest-order>=1.3",
|
|
@@ -95,7 +95,11 @@ def path_depth(root: str, child: str) -> int:
|
|
|
95
95
|
return child_expanded[len(root_expanded):].count(os.sep)
|
|
96
96
|
|
|
97
97
|
|
|
98
|
-
def glob_match(
|
|
98
|
+
def glob_match(
|
|
99
|
+
names: list[str],
|
|
100
|
+
include_patterns: list[str] | None = None,
|
|
101
|
+
exclude_patterns: list[str] | None = None,
|
|
102
|
+
) -> list[str]:
|
|
99
103
|
"""
|
|
100
104
|
Applies the given inclusive and exclusive glob patterns to the given ``names`` and returns the filtered result.
|
|
101
105
|
|
|
@@ -121,8 +125,8 @@ class CopyFuncProtocol(Protocol):
|
|
|
121
125
|
def listfile(
|
|
122
126
|
path: str,
|
|
123
127
|
*,
|
|
124
|
-
include_patterns: list[str] = None,
|
|
125
|
-
exclude_patterns: list[str] = None,
|
|
128
|
+
include_patterns: list[str] | None = None,
|
|
129
|
+
exclude_patterns: list[str] | None = None,
|
|
126
130
|
depth: int = 0,
|
|
127
131
|
) -> list[str]:
|
|
128
132
|
"""
|
|
@@ -153,8 +157,8 @@ def copy(
|
|
|
153
157
|
src: str,
|
|
154
158
|
dst: str,
|
|
155
159
|
*,
|
|
156
|
-
include_patterns: list[str] = None,
|
|
157
|
-
exclude_patterns: list[str] = None,
|
|
160
|
+
include_patterns: list[str] | None = None,
|
|
161
|
+
exclude_patterns: list[str] | None = None,
|
|
158
162
|
depth: int = 0,
|
|
159
163
|
follow_symlinks: bool = False,
|
|
160
164
|
ignore_dangling_symlinks: bool = False,
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker_python_common.egg-info/PKG-INFO
RENAMED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: iker-python-common
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.59
|
|
4
4
|
Classifier: Programming Language :: Python :: 3
|
|
5
5
|
Classifier: Programming Language :: Python :: 3.12
|
|
6
6
|
Classifier: Programming Language :: Python :: 3.13
|
|
7
7
|
Classifier: Programming Language :: Python :: 3.14
|
|
8
8
|
Requires-Python: <3.15,>=3.12
|
|
9
|
-
Requires-Dist: boto3>=1.35
|
|
10
9
|
Requires-Dist: docker>=7.1
|
|
11
10
|
Requires-Dist: numpy>=2.3
|
|
12
11
|
Requires-Dist: psycopg>=3.2
|
|
@@ -16,7 +15,6 @@ Provides-Extra: all
|
|
|
16
15
|
Requires-Dist: iker-python-common; extra == "all"
|
|
17
16
|
Provides-Extra: test
|
|
18
17
|
Requires-Dist: ddt>=1.7; extra == "test"
|
|
19
|
-
Requires-Dist: moto[all,ec2,s3]>=5.0; extra == "test"
|
|
20
18
|
Requires-Dist: pytest-cov>=5.0; extra == "test"
|
|
21
19
|
Requires-Dist: pytest-mysql>=3.0; extra == "test"
|
|
22
20
|
Requires-Dist: pytest-order>=1.3; extra == "test"
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker_python_common.egg-info/SOURCES.txt
RENAMED
|
@@ -10,16 +10,6 @@ setup.py
|
|
|
10
10
|
resources/unittest/config/config.cfg
|
|
11
11
|
resources/unittest/csv/data.csv
|
|
12
12
|
resources/unittest/csv/data.tsv
|
|
13
|
-
resources/unittest/s3utils/dir.baz/file.bar.baz
|
|
14
|
-
resources/unittest/s3utils/dir.baz/file.foo.bar
|
|
15
|
-
resources/unittest/s3utils/dir.baz/file.foo.baz
|
|
16
|
-
resources/unittest/s3utils/dir.foo/file.bar
|
|
17
|
-
resources/unittest/s3utils/dir.foo/file.baz
|
|
18
|
-
resources/unittest/s3utils/dir.foo/file.foo
|
|
19
|
-
resources/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz
|
|
20
|
-
resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar
|
|
21
|
-
resources/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz
|
|
22
|
-
resources/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz
|
|
23
13
|
resources/unittest/shutils/dir.baz/file.bar.baz
|
|
24
14
|
resources/unittest/shutils/dir.baz/file.foo.bar
|
|
25
15
|
resources/unittest/shutils/dir.baz/file.foo.baz
|
|
@@ -44,7 +34,6 @@ src/iker/common/utils/logger.py
|
|
|
44
34
|
src/iker/common/utils/numutils.py
|
|
45
35
|
src/iker/common/utils/randutils.py
|
|
46
36
|
src/iker/common/utils/retry.py
|
|
47
|
-
src/iker/common/utils/s3utils.py
|
|
48
37
|
src/iker/common/utils/sequtils.py
|
|
49
38
|
src/iker/common/utils/shutils.py
|
|
50
39
|
src/iker/common/utils/span.py
|
|
@@ -72,7 +61,6 @@ test/iker_tests/common/utils/logger_test.py
|
|
|
72
61
|
test/iker_tests/common/utils/numutils_test.py
|
|
73
62
|
test/iker_tests/common/utils/randutils_test.py
|
|
74
63
|
test/iker_tests/common/utils/retry_test.py
|
|
75
|
-
test/iker_tests/common/utils/s3utils_test.py
|
|
76
64
|
test/iker_tests/common/utils/sequtils_test.py
|
|
77
65
|
test/iker_tests/common/utils/shutils_test.py
|
|
78
66
|
test/iker_tests/common/utils/span_test.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -1,270 +0,0 @@
|
|
|
1
|
-
import concurrent.futures
|
|
2
|
-
import contextlib
|
|
3
|
-
import dataclasses
|
|
4
|
-
import datetime
|
|
5
|
-
import mimetypes
|
|
6
|
-
import os
|
|
7
|
-
import tempfile
|
|
8
|
-
|
|
9
|
-
import boto3
|
|
10
|
-
from botocore.client import BaseClient
|
|
11
|
-
|
|
12
|
-
from iker.common.utils.shutils import glob_match, listfile, path_depth
|
|
13
|
-
from iker.common.utils.strutils import is_empty, trim_to_none
|
|
14
|
-
|
|
15
|
-
__all__ = [
|
|
16
|
-
"S3ObjectMeta",
|
|
17
|
-
"s3_make_client",
|
|
18
|
-
"s3_list_objects",
|
|
19
|
-
"s3_listfile",
|
|
20
|
-
"s3_cp_download",
|
|
21
|
-
"s3_cp_upload",
|
|
22
|
-
"s3_sync_download",
|
|
23
|
-
"s3_sync_upload",
|
|
24
|
-
"s3_pull_text",
|
|
25
|
-
"s3_push_text",
|
|
26
|
-
]
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
@dataclasses.dataclass
|
|
30
|
-
class S3ObjectMeta(object):
|
|
31
|
-
key: str
|
|
32
|
-
last_modified: datetime.datetime
|
|
33
|
-
size: int
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def s3_make_client(
|
|
37
|
-
access_key_id: str = None,
|
|
38
|
-
secret_access_key: str = None,
|
|
39
|
-
region_name: str = None,
|
|
40
|
-
endpoint_url: str = None,
|
|
41
|
-
) -> contextlib.AbstractContextManager[BaseClient]:
|
|
42
|
-
"""
|
|
43
|
-
Creates an AWS S3 client as a context manager for safe resource handling.
|
|
44
|
-
|
|
45
|
-
:param access_key_id: AWS access key ID.
|
|
46
|
-
:param secret_access_key: AWS secret access key.
|
|
47
|
-
:param region_name: AWS service region name.
|
|
48
|
-
:param endpoint_url: AWS service endpoint URL.
|
|
49
|
-
:return: A context manager yielding an S3 client instance.
|
|
50
|
-
"""
|
|
51
|
-
client = boto3.client("s3",
|
|
52
|
-
region_name=trim_to_none(region_name),
|
|
53
|
-
endpoint_url=trim_to_none(endpoint_url),
|
|
54
|
-
aws_access_key_id=trim_to_none(access_key_id),
|
|
55
|
-
aws_secret_access_key=trim_to_none(secret_access_key))
|
|
56
|
-
return contextlib.closing(client)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
def s3_list_objects(client: BaseClient, bucket: str, prefix: str, limit: int = None) -> list[S3ObjectMeta]:
|
|
60
|
-
"""
|
|
61
|
-
Lists all objects from the given S3 ``bucket`` and ``prefix``.
|
|
62
|
-
|
|
63
|
-
:param client: AWS S3 client instance.
|
|
64
|
-
:param bucket: Bucket name.
|
|
65
|
-
:param prefix: Object keys prefix.
|
|
66
|
-
:param limit: Maximum number of objects to return (``None`` for all).
|
|
67
|
-
:return: List of ``S3ObjectMeta`` items.
|
|
68
|
-
"""
|
|
69
|
-
entries = []
|
|
70
|
-
|
|
71
|
-
next_marker = None
|
|
72
|
-
while True:
|
|
73
|
-
if is_empty(next_marker):
|
|
74
|
-
response = client.list_objects(MaxKeys=1000, Bucket=bucket, Prefix=prefix)
|
|
75
|
-
else:
|
|
76
|
-
response = client.list_objects(MaxKeys=1000, Bucket=bucket, Prefix=prefix, Marker=next_marker)
|
|
77
|
-
|
|
78
|
-
entries.extend(response.get("Contents", []))
|
|
79
|
-
|
|
80
|
-
if limit is not None and len(entries) >= limit:
|
|
81
|
-
entries = entries[:limit]
|
|
82
|
-
|
|
83
|
-
if not response.get("IsTruncated"):
|
|
84
|
-
break
|
|
85
|
-
|
|
86
|
-
next_marker = response.get("NextMarker")
|
|
87
|
-
if is_empty(next_marker):
|
|
88
|
-
next_marker = entries[-1]["Key"]
|
|
89
|
-
|
|
90
|
-
return [S3ObjectMeta(key=e["Key"], last_modified=e["LastModified"], size=e["Size"]) for e in entries]
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
def s3_listfile(
|
|
94
|
-
client: BaseClient,
|
|
95
|
-
bucket: str,
|
|
96
|
-
prefix: str,
|
|
97
|
-
*,
|
|
98
|
-
include_patterns: list[str] = None,
|
|
99
|
-
exclude_patterns: list[str] = None,
|
|
100
|
-
depth: int = 0,
|
|
101
|
-
) -> list[S3ObjectMeta]:
|
|
102
|
-
"""
|
|
103
|
-
Lists all objects from the given S3 ``bucket`` and ``prefix``, filtered by patterns and directory depth.
|
|
104
|
-
|
|
105
|
-
:param client: AWS S3 client instance.
|
|
106
|
-
:param bucket: Bucket name.
|
|
107
|
-
:param prefix: Object keys prefix.
|
|
108
|
-
:param include_patterns: Inclusive glob patterns applied to filenames.
|
|
109
|
-
:param exclude_patterns: Exclusive glob patterns applied to filenames.
|
|
110
|
-
:param depth: Maximum depth of subdirectories to include in the scan.
|
|
111
|
-
:return: List of ``S3ObjectMeta`` items.
|
|
112
|
-
"""
|
|
113
|
-
|
|
114
|
-
# We add trailing slash "/" to the prefix if it is absent
|
|
115
|
-
if not prefix.endswith("/"):
|
|
116
|
-
prefix = prefix + "/"
|
|
117
|
-
|
|
118
|
-
objects = s3_list_objects(client, bucket, prefix)
|
|
119
|
-
|
|
120
|
-
def filter_object_meta(object_meta: S3ObjectMeta) -> bool:
|
|
121
|
-
if 0 < depth <= path_depth(prefix, os.path.dirname(object_meta.key)):
|
|
122
|
-
return False
|
|
123
|
-
if len(glob_match([os.path.basename(object_meta.key)], include_patterns, exclude_patterns)) == 0:
|
|
124
|
-
return False
|
|
125
|
-
return True
|
|
126
|
-
|
|
127
|
-
return list(filter(filter_object_meta, objects))
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
def s3_cp_download(client: BaseClient, bucket: str, key: str, file_path: str):
|
|
131
|
-
"""
|
|
132
|
-
Downloads an object from the given S3 ``bucket`` and ``key`` to a local file path.
|
|
133
|
-
|
|
134
|
-
:param client: AWS S3 client instance.
|
|
135
|
-
:param bucket: Bucket name.
|
|
136
|
-
:param key: Object key.
|
|
137
|
-
:param file_path: Local file path to save the object.
|
|
138
|
-
"""
|
|
139
|
-
client.download_file(bucket, key, file_path)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
def s3_cp_upload(client: BaseClient, file_path: str, bucket: str, key: str):
|
|
143
|
-
"""
|
|
144
|
-
Uploads a local file to the given S3 ``bucket`` and ``key``.
|
|
145
|
-
|
|
146
|
-
:param client: AWS S3 client instance.
|
|
147
|
-
:param file_path: Local file path to upload.
|
|
148
|
-
:param bucket: Bucket name.
|
|
149
|
-
:param key: Object key for the uploaded file.
|
|
150
|
-
"""
|
|
151
|
-
t, _ = mimetypes.MimeTypes().guess_type(file_path)
|
|
152
|
-
client.upload_file(file_path, bucket, key, ExtraArgs={"ContentType": "binary/octet-stream" if t is None else t})
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
def s3_sync_download(
|
|
156
|
-
client: BaseClient,
|
|
157
|
-
bucket: str,
|
|
158
|
-
prefix: str,
|
|
159
|
-
dir_path: str,
|
|
160
|
-
*,
|
|
161
|
-
max_workers: int = None,
|
|
162
|
-
include_patterns: list[str] = None,
|
|
163
|
-
exclude_patterns: list[str] = None,
|
|
164
|
-
depth: int = 0,
|
|
165
|
-
):
|
|
166
|
-
"""
|
|
167
|
-
Recursively downloads all objects from the given S3 ``bucket`` and ``prefix`` to a local directory path, using a thread pool.
|
|
168
|
-
|
|
169
|
-
:param client: AWS S3 client instance.
|
|
170
|
-
:param bucket: Bucket name.
|
|
171
|
-
:param prefix: Object keys prefix.
|
|
172
|
-
:param dir_path: Local directory path to save objects.
|
|
173
|
-
:param max_workers: Maximum number of worker threads.
|
|
174
|
-
:param include_patterns: Inclusive glob patterns applied to filenames.
|
|
175
|
-
:param exclude_patterns: Exclusive glob patterns applied to filenames.
|
|
176
|
-
:param depth: Maximum depth of subdirectories to include in the scan.
|
|
177
|
-
"""
|
|
178
|
-
|
|
179
|
-
# We add trailing slash "/" to the prefix if it is absent
|
|
180
|
-
if not prefix.endswith("/"):
|
|
181
|
-
prefix = prefix + "/"
|
|
182
|
-
|
|
183
|
-
objects = s3_listfile(client,
|
|
184
|
-
bucket,
|
|
185
|
-
prefix,
|
|
186
|
-
include_patterns=include_patterns,
|
|
187
|
-
exclude_patterns=exclude_patterns,
|
|
188
|
-
depth=depth)
|
|
189
|
-
|
|
190
|
-
def download_file(key: str):
|
|
191
|
-
file_path = os.path.join(dir_path, key[len(prefix):])
|
|
192
|
-
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|
193
|
-
s3_cp_download(client, bucket, key, file_path)
|
|
194
|
-
|
|
195
|
-
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
196
|
-
concurrent.futures.wait([executor.submit(download_file, obj.key) for obj in objects],
|
|
197
|
-
return_when=concurrent.futures.FIRST_EXCEPTION)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
def s3_sync_upload(
|
|
201
|
-
client: BaseClient,
|
|
202
|
-
dir_path: str,
|
|
203
|
-
bucket: str,
|
|
204
|
-
prefix: str,
|
|
205
|
-
*,
|
|
206
|
-
max_workers: int = None,
|
|
207
|
-
include_patterns: list[str] = None,
|
|
208
|
-
exclude_patterns: list[str] = None,
|
|
209
|
-
depth: int = 0,
|
|
210
|
-
):
|
|
211
|
-
"""
|
|
212
|
-
Recursively uploads all files from a local directory to the given S3 ``bucket`` and ``prefix``, using a thread pool.
|
|
213
|
-
|
|
214
|
-
:param client: AWS S3 client instance.
|
|
215
|
-
:param dir_path: Local directory path to upload from.
|
|
216
|
-
:param bucket: Bucket name.
|
|
217
|
-
:param prefix: Object keys prefix for uploaded files.
|
|
218
|
-
:param max_workers: Maximum number of worker threads.
|
|
219
|
-
:param include_patterns: Inclusive glob patterns applied to filenames.
|
|
220
|
-
:param exclude_patterns: Exclusive glob patterns applied to filenames.
|
|
221
|
-
:param depth: Maximum depth of subdirectories to include in the scan.
|
|
222
|
-
"""
|
|
223
|
-
|
|
224
|
-
# We add trailing slash "/" to the prefix if it is absent
|
|
225
|
-
if not prefix.endswith("/"):
|
|
226
|
-
prefix = prefix + "/"
|
|
227
|
-
|
|
228
|
-
file_paths = listfile(dir_path,
|
|
229
|
-
include_patterns=include_patterns,
|
|
230
|
-
exclude_patterns=exclude_patterns,
|
|
231
|
-
depth=depth)
|
|
232
|
-
|
|
233
|
-
def upload_file(file_path: str):
|
|
234
|
-
s3_cp_upload(client, file_path, bucket, prefix + os.path.relpath(file_path, dir_path))
|
|
235
|
-
|
|
236
|
-
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
|
|
237
|
-
concurrent.futures.wait([executor.submit(upload_file, file_path) for file_path in file_paths],
|
|
238
|
-
return_when=concurrent.futures.FIRST_EXCEPTION)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
def s3_pull_text(client: BaseClient, bucket: str, key: str, encoding: str = None) -> str:
|
|
242
|
-
"""
|
|
243
|
-
Downloads and decodes text content stored as an object in the given S3 ``bucket`` and ``key``.
|
|
244
|
-
|
|
245
|
-
:param client: AWS S3 client instance.
|
|
246
|
-
:param bucket: Bucket name.
|
|
247
|
-
:param key: Object key storing the text.
|
|
248
|
-
:param encoding: String encoding to use (defaults to UTF-8).
|
|
249
|
-
:return: The decoded text content.
|
|
250
|
-
"""
|
|
251
|
-
with tempfile.TemporaryFile() as fp:
|
|
252
|
-
client.download_fileobj(bucket, key, fp)
|
|
253
|
-
fp.seek(0)
|
|
254
|
-
return fp.read().decode(encoding or "utf-8")
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
def s3_push_text(client: BaseClient, text: str, bucket: str, key: str, encoding: str = None):
|
|
258
|
-
"""
|
|
259
|
-
Uploads the given text as an object to the specified S3 ``bucket`` and ``key``.
|
|
260
|
-
|
|
261
|
-
:param client: AWS S3 client instance.
|
|
262
|
-
:param text: Text content to upload.
|
|
263
|
-
:param bucket: Bucket name.
|
|
264
|
-
:param key: Object key to store the text.
|
|
265
|
-
:param encoding: String encoding to use (defaults to UTF-8).
|
|
266
|
-
"""
|
|
267
|
-
with tempfile.TemporaryFile() as fp:
|
|
268
|
-
fp.write(text.encode(encoding or "utf-8"))
|
|
269
|
-
fp.seek(0)
|
|
270
|
-
client.upload_fileobj(fp, bucket, key)
|
|
@@ -1,422 +0,0 @@
|
|
|
1
|
-
import tempfile
|
|
2
|
-
import unittest
|
|
3
|
-
|
|
4
|
-
import ddt
|
|
5
|
-
import moto
|
|
6
|
-
|
|
7
|
-
from iker.common.utils.randutils import randomizer
|
|
8
|
-
from iker.common.utils.s3utils import *
|
|
9
|
-
from iker.common.utils.shutils import listfile
|
|
10
|
-
from iker.common.utils.testutils import norm_path
|
|
11
|
-
from iker_tests import resources_directory
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
@ddt.ddt
|
|
15
|
-
class S3UtilsTest(unittest.TestCase):
|
|
16
|
-
|
|
17
|
-
def test_s3_list_object__random_text_files(self):
|
|
18
|
-
with moto.mock_aws(), s3_make_client(region_name="us-east-1") as client:
|
|
19
|
-
client.create_bucket(Bucket="dummy-bucket")
|
|
20
|
-
|
|
21
|
-
data = []
|
|
22
|
-
for i in range(0, 1000):
|
|
23
|
-
text = randomizer().random_alphanumeric(randomizer().next_int(1000, 2000))
|
|
24
|
-
key = "dummy_prefix/%03d" % i
|
|
25
|
-
data.append((key, text))
|
|
26
|
-
|
|
27
|
-
for key, text in data:
|
|
28
|
-
s3_push_text(client, text, "dummy-bucket", key)
|
|
29
|
-
|
|
30
|
-
result = s3_list_objects(client, "dummy-bucket", "dummy_prefix/")
|
|
31
|
-
|
|
32
|
-
for key, text in data:
|
|
33
|
-
self.assertTrue(any(o.key == key for o in result))
|
|
34
|
-
self.assertEqual(s3_pull_text(client, "dummy-bucket", key), text)
|
|
35
|
-
|
|
36
|
-
def test_s3_listfile__random_text_files(self):
|
|
37
|
-
with moto.mock_aws(), s3_make_client(region_name="us-east-1") as client:
|
|
38
|
-
client.create_bucket(Bucket="dummy-bucket")
|
|
39
|
-
|
|
40
|
-
data = []
|
|
41
|
-
for i in range(0, 1000):
|
|
42
|
-
text = randomizer().random_alphanumeric(randomizer().next_int(1000, 2000))
|
|
43
|
-
key = "dummy_prefix/%03d" % i
|
|
44
|
-
data.append((key, text))
|
|
45
|
-
|
|
46
|
-
for key, text in data:
|
|
47
|
-
s3_push_text(client, text, "dummy-bucket", key)
|
|
48
|
-
|
|
49
|
-
result = s3_listfile(client, "dummy-bucket", "dummy_prefix/")
|
|
50
|
-
|
|
51
|
-
for key, text in data:
|
|
52
|
-
self.assertTrue(any(o.key == key for o in result))
|
|
53
|
-
self.assertEqual(s3_pull_text(client, "dummy-bucket", key), text)
|
|
54
|
-
|
|
55
|
-
data_s3_listfile = [
|
|
56
|
-
(
|
|
57
|
-
"{res_dir}/unittest/s3utils/",
|
|
58
|
-
"dummy-bucket",
|
|
59
|
-
"unittest/s3utils/",
|
|
60
|
-
[],
|
|
61
|
-
[],
|
|
62
|
-
0,
|
|
63
|
-
[
|
|
64
|
-
"unittest/s3utils/dir.baz/file.foo.bar",
|
|
65
|
-
"unittest/s3utils/dir.baz/file.foo.baz",
|
|
66
|
-
"unittest/s3utils/dir.baz/file.bar.baz",
|
|
67
|
-
"unittest/s3utils/dir.foo/file.bar",
|
|
68
|
-
"unittest/s3utils/dir.foo/file.baz",
|
|
69
|
-
"unittest/s3utils/dir.foo/file.foo",
|
|
70
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar",
|
|
71
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz",
|
|
72
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz",
|
|
73
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz",
|
|
74
|
-
],
|
|
75
|
-
),
|
|
76
|
-
(
|
|
77
|
-
"{res_dir}/unittest/s3utils",
|
|
78
|
-
"dummy-bucket",
|
|
79
|
-
"unittest/s3utils/",
|
|
80
|
-
[],
|
|
81
|
-
[],
|
|
82
|
-
0,
|
|
83
|
-
[
|
|
84
|
-
"unittest/s3utils/dir.baz/file.foo.bar",
|
|
85
|
-
"unittest/s3utils/dir.baz/file.foo.baz",
|
|
86
|
-
"unittest/s3utils/dir.baz/file.bar.baz",
|
|
87
|
-
"unittest/s3utils/dir.foo/file.bar",
|
|
88
|
-
"unittest/s3utils/dir.foo/file.baz",
|
|
89
|
-
"unittest/s3utils/dir.foo/file.foo",
|
|
90
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar",
|
|
91
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz",
|
|
92
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz",
|
|
93
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz",
|
|
94
|
-
],
|
|
95
|
-
),
|
|
96
|
-
(
|
|
97
|
-
"{res_dir}/unittest/s3utils/dir.foo",
|
|
98
|
-
"dummy-bucket",
|
|
99
|
-
"unittest/s3utils/dir.foo",
|
|
100
|
-
[],
|
|
101
|
-
[],
|
|
102
|
-
0,
|
|
103
|
-
[
|
|
104
|
-
"unittest/s3utils/dir.foo/file.bar",
|
|
105
|
-
"unittest/s3utils/dir.foo/file.baz",
|
|
106
|
-
"unittest/s3utils/dir.foo/file.foo",
|
|
107
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar",
|
|
108
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz",
|
|
109
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz",
|
|
110
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz",
|
|
111
|
-
],
|
|
112
|
-
),
|
|
113
|
-
(
|
|
114
|
-
"{res_dir}/unittest/s3utils/dir.baz",
|
|
115
|
-
"dummy-bucket",
|
|
116
|
-
"unittest/s3utils/dir.baz",
|
|
117
|
-
[],
|
|
118
|
-
[],
|
|
119
|
-
0,
|
|
120
|
-
[
|
|
121
|
-
"unittest/s3utils/dir.baz/file.foo.bar",
|
|
122
|
-
"unittest/s3utils/dir.baz/file.foo.baz",
|
|
123
|
-
"unittest/s3utils/dir.baz/file.bar.baz",
|
|
124
|
-
],
|
|
125
|
-
),
|
|
126
|
-
(
|
|
127
|
-
"{res_dir}/unittest/s3utils",
|
|
128
|
-
"dummy-bucket",
|
|
129
|
-
"unittest/s3utils/",
|
|
130
|
-
["*.foo", "*.bar"],
|
|
131
|
-
["*.foo.bar"],
|
|
132
|
-
0,
|
|
133
|
-
[
|
|
134
|
-
"unittest/s3utils/dir.foo/file.bar",
|
|
135
|
-
"unittest/s3utils/dir.foo/file.foo",
|
|
136
|
-
],
|
|
137
|
-
),
|
|
138
|
-
(
|
|
139
|
-
"{res_dir}/unittest/s3utils",
|
|
140
|
-
"dummy-bucket",
|
|
141
|
-
"unittest/s3utils/",
|
|
142
|
-
["*.foo", "*.bar"],
|
|
143
|
-
[],
|
|
144
|
-
0,
|
|
145
|
-
[
|
|
146
|
-
"unittest/s3utils/dir.baz/file.foo.bar",
|
|
147
|
-
"unittest/s3utils/dir.foo/file.bar",
|
|
148
|
-
"unittest/s3utils/dir.foo/file.foo",
|
|
149
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar",
|
|
150
|
-
],
|
|
151
|
-
),
|
|
152
|
-
(
|
|
153
|
-
"{res_dir}/unittest/s3utils",
|
|
154
|
-
"dummy-bucket",
|
|
155
|
-
"unittest/s3utils/",
|
|
156
|
-
[],
|
|
157
|
-
["*.baz"],
|
|
158
|
-
0,
|
|
159
|
-
[
|
|
160
|
-
"unittest/s3utils/dir.baz/file.foo.bar",
|
|
161
|
-
"unittest/s3utils/dir.foo/file.bar",
|
|
162
|
-
"unittest/s3utils/dir.foo/file.foo",
|
|
163
|
-
"unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar",
|
|
164
|
-
],
|
|
165
|
-
),
|
|
166
|
-
(
|
|
167
|
-
"{res_dir}/unittest/s3utils",
|
|
168
|
-
"dummy-bucket",
|
|
169
|
-
"unittest/s3utils",
|
|
170
|
-
[],
|
|
171
|
-
[],
|
|
172
|
-
2,
|
|
173
|
-
[
|
|
174
|
-
"unittest/s3utils/dir.baz/file.foo.bar",
|
|
175
|
-
"unittest/s3utils/dir.baz/file.foo.baz",
|
|
176
|
-
"unittest/s3utils/dir.baz/file.bar.baz",
|
|
177
|
-
"unittest/s3utils/dir.foo/file.bar",
|
|
178
|
-
"unittest/s3utils/dir.foo/file.baz",
|
|
179
|
-
"unittest/s3utils/dir.foo/file.foo",
|
|
180
|
-
],
|
|
181
|
-
),
|
|
182
|
-
]
|
|
183
|
-
|
|
184
|
-
@ddt.idata(data_s3_listfile)
|
|
185
|
-
@ddt.unpack
|
|
186
|
-
def test_s3_listfile(self, src, bucket, prefix, include_patterns, exclude_patterns, depth, expect):
|
|
187
|
-
with moto.mock_aws(), s3_make_client(region_name="us-east-1") as client:
|
|
188
|
-
client.create_bucket(Bucket=bucket)
|
|
189
|
-
|
|
190
|
-
s3_sync_upload(client,
|
|
191
|
-
src.format(res_dir=resources_directory),
|
|
192
|
-
bucket,
|
|
193
|
-
prefix)
|
|
194
|
-
|
|
195
|
-
object_metas = s3_listfile(client,
|
|
196
|
-
bucket,
|
|
197
|
-
prefix,
|
|
198
|
-
include_patterns=include_patterns,
|
|
199
|
-
exclude_patterns=exclude_patterns,
|
|
200
|
-
depth=depth)
|
|
201
|
-
|
|
202
|
-
self.assertSetEqual(set(map(lambda x: norm_path(x.key), object_metas)),
|
|
203
|
-
set(map(lambda x: norm_path(x), expect)))
|
|
204
|
-
|
|
205
|
-
data_s3_sync = [
|
|
206
|
-
(
|
|
207
|
-
"{res_dir}/unittest/s3utils/",
|
|
208
|
-
"{tmp_dir}/unittest/s3utils/",
|
|
209
|
-
"dummy-bucket",
|
|
210
|
-
"unittest/s3utils/",
|
|
211
|
-
[],
|
|
212
|
-
[],
|
|
213
|
-
0,
|
|
214
|
-
[
|
|
215
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.foo.bar",
|
|
216
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.foo.baz",
|
|
217
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.bar.baz",
|
|
218
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.bar",
|
|
219
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.baz",
|
|
220
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.foo",
|
|
221
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar",
|
|
222
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz",
|
|
223
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz",
|
|
224
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz",
|
|
225
|
-
],
|
|
226
|
-
),
|
|
227
|
-
(
|
|
228
|
-
"{res_dir}/unittest/s3utils",
|
|
229
|
-
"{tmp_dir}/unittest/s3utils",
|
|
230
|
-
"dummy-bucket",
|
|
231
|
-
"unittest/s3utils/",
|
|
232
|
-
[],
|
|
233
|
-
[],
|
|
234
|
-
0,
|
|
235
|
-
[
|
|
236
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.foo.bar",
|
|
237
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.foo.baz",
|
|
238
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.bar.baz",
|
|
239
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.bar",
|
|
240
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.baz",
|
|
241
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.foo",
|
|
242
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar",
|
|
243
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz",
|
|
244
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz",
|
|
245
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz",
|
|
246
|
-
],
|
|
247
|
-
),
|
|
248
|
-
(
|
|
249
|
-
"{res_dir}/unittest/s3utils/dir.foo",
|
|
250
|
-
"{tmp_dir}/unittest/s3utils/dir.foo",
|
|
251
|
-
"dummy-bucket",
|
|
252
|
-
"unittest/s3utils/dir.foo",
|
|
253
|
-
[],
|
|
254
|
-
[],
|
|
255
|
-
0,
|
|
256
|
-
[
|
|
257
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.bar",
|
|
258
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.baz",
|
|
259
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.foo",
|
|
260
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar",
|
|
261
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.baz",
|
|
262
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.bar.baz",
|
|
263
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/dir.foo.bar.baz/file.foo.bar.baz",
|
|
264
|
-
],
|
|
265
|
-
),
|
|
266
|
-
(
|
|
267
|
-
"{res_dir}/unittest/s3utils/dir.baz",
|
|
268
|
-
"{tmp_dir}/unittest/s3utils/dir.baz",
|
|
269
|
-
"dummy-bucket",
|
|
270
|
-
"unittest/s3utils/dir.baz",
|
|
271
|
-
[],
|
|
272
|
-
[],
|
|
273
|
-
0,
|
|
274
|
-
[
|
|
275
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.foo.bar",
|
|
276
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.foo.baz",
|
|
277
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.bar.baz",
|
|
278
|
-
],
|
|
279
|
-
),
|
|
280
|
-
(
|
|
281
|
-
"{res_dir}/unittest/s3utils",
|
|
282
|
-
"{tmp_dir}/unittest/s3utils",
|
|
283
|
-
"dummy-bucket",
|
|
284
|
-
"unittest/s3utils/",
|
|
285
|
-
["*.foo", "*.bar"],
|
|
286
|
-
["*.foo.bar"],
|
|
287
|
-
0,
|
|
288
|
-
[
|
|
289
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.bar",
|
|
290
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.foo",
|
|
291
|
-
],
|
|
292
|
-
),
|
|
293
|
-
(
|
|
294
|
-
"{res_dir}/unittest/s3utils",
|
|
295
|
-
"{tmp_dir}/unittest/s3utils",
|
|
296
|
-
"dummy-bucket",
|
|
297
|
-
"unittest/s3utils/",
|
|
298
|
-
["*.foo", "*.bar"],
|
|
299
|
-
[],
|
|
300
|
-
0,
|
|
301
|
-
[
|
|
302
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.foo.bar",
|
|
303
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.bar",
|
|
304
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.foo",
|
|
305
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar",
|
|
306
|
-
],
|
|
307
|
-
),
|
|
308
|
-
(
|
|
309
|
-
"{res_dir}/unittest/s3utils",
|
|
310
|
-
"{tmp_dir}/unittest/s3utils",
|
|
311
|
-
"dummy-bucket",
|
|
312
|
-
"unittest/s3utils/",
|
|
313
|
-
[],
|
|
314
|
-
["*.baz"],
|
|
315
|
-
0,
|
|
316
|
-
[
|
|
317
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.foo.bar",
|
|
318
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.bar",
|
|
319
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.foo",
|
|
320
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/dir.foo.bar/file.foo.bar",
|
|
321
|
-
],
|
|
322
|
-
),
|
|
323
|
-
(
|
|
324
|
-
"{res_dir}/unittest/s3utils",
|
|
325
|
-
"{tmp_dir}/unittest/s3utils",
|
|
326
|
-
"dummy-bucket",
|
|
327
|
-
"unittest/s3utils",
|
|
328
|
-
[],
|
|
329
|
-
[],
|
|
330
|
-
2,
|
|
331
|
-
[
|
|
332
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.foo.bar",
|
|
333
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.foo.baz",
|
|
334
|
-
"{tmp_dir}/unittest/s3utils/dir.baz/file.bar.baz",
|
|
335
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.bar",
|
|
336
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.baz",
|
|
337
|
-
"{tmp_dir}/unittest/s3utils/dir.foo/file.foo",
|
|
338
|
-
],
|
|
339
|
-
),
|
|
340
|
-
]
|
|
341
|
-
|
|
342
|
-
@ddt.idata(data_s3_sync)
|
|
343
|
-
@ddt.unpack
|
|
344
|
-
def test_s3_sync(self, src, dst, bucket, prefix, include_patterns, exclude_patterns, depth, expect):
|
|
345
|
-
with moto.mock_aws(), s3_make_client(region_name="us-east-1") as client:
|
|
346
|
-
client.create_bucket(Bucket=bucket)
|
|
347
|
-
|
|
348
|
-
s3_sync_upload(client,
|
|
349
|
-
src.format(res_dir=resources_directory),
|
|
350
|
-
bucket,
|
|
351
|
-
prefix,
|
|
352
|
-
include_patterns=include_patterns,
|
|
353
|
-
exclude_patterns=exclude_patterns,
|
|
354
|
-
depth=depth)
|
|
355
|
-
|
|
356
|
-
with tempfile.TemporaryDirectory() as temp_directory:
|
|
357
|
-
s3_sync_download(client,
|
|
358
|
-
bucket,
|
|
359
|
-
prefix,
|
|
360
|
-
dst.format(tmp_dir=temp_directory))
|
|
361
|
-
|
|
362
|
-
self.assertSetEqual(set(map(lambda x: norm_path(x), listfile(dst.format(tmp_dir=temp_directory)))),
|
|
363
|
-
set(map(lambda x: norm_path(x.format(tmp_dir=temp_directory)), expect)))
|
|
364
|
-
|
|
365
|
-
with moto.mock_aws(), s3_make_client(region_name="us-east-1") as client:
|
|
366
|
-
client.create_bucket(Bucket=bucket)
|
|
367
|
-
|
|
368
|
-
s3_sync_upload(client,
|
|
369
|
-
src.format(res_dir=resources_directory),
|
|
370
|
-
bucket,
|
|
371
|
-
prefix)
|
|
372
|
-
|
|
373
|
-
with tempfile.TemporaryDirectory() as temp_directory:
|
|
374
|
-
s3_sync_download(client,
|
|
375
|
-
bucket,
|
|
376
|
-
prefix,
|
|
377
|
-
dst.format(tmp_dir=temp_directory),
|
|
378
|
-
include_patterns=include_patterns,
|
|
379
|
-
exclude_patterns=exclude_patterns,
|
|
380
|
-
depth=depth)
|
|
381
|
-
|
|
382
|
-
self.assertSetEqual(set(map(lambda x: norm_path(x), listfile(dst.format(tmp_dir=temp_directory)))),
|
|
383
|
-
set(map(lambda x: norm_path(x.format(tmp_dir=temp_directory)), expect)))
|
|
384
|
-
|
|
385
|
-
with moto.mock_aws(), s3_make_client(region_name="us-east-1") as client:
|
|
386
|
-
client.create_bucket(Bucket=bucket)
|
|
387
|
-
|
|
388
|
-
s3_sync_upload(client,
|
|
389
|
-
src.format(res_dir=resources_directory),
|
|
390
|
-
bucket,
|
|
391
|
-
prefix,
|
|
392
|
-
include_patterns=include_patterns,
|
|
393
|
-
depth=depth)
|
|
394
|
-
|
|
395
|
-
with tempfile.TemporaryDirectory() as temp_directory:
|
|
396
|
-
s3_sync_download(client,
|
|
397
|
-
bucket,
|
|
398
|
-
prefix,
|
|
399
|
-
dst.format(tmp_dir=temp_directory),
|
|
400
|
-
exclude_patterns=exclude_patterns,
|
|
401
|
-
depth=depth)
|
|
402
|
-
|
|
403
|
-
self.assertSetEqual(set(map(lambda x: norm_path(x), listfile(dst.format(tmp_dir=temp_directory)))),
|
|
404
|
-
set(map(lambda x: norm_path(x.format(tmp_dir=temp_directory)), expect)))
|
|
405
|
-
|
|
406
|
-
data_s3_text = [
|
|
407
|
-
("dummy-bucket", "dummy/key", "dummy content", None),
|
|
408
|
-
("dummy-bucket", "dummy/key.alpha", "Old MacDonald had a farm", None),
|
|
409
|
-
("dummy-bucket", "dummy/key.beta", "Ee-i-ee-i-o", None),
|
|
410
|
-
("dummy-bucket", "dummy/key", "dummy content", "ascii"),
|
|
411
|
-
("dummy-bucket", "dummy/key.alpha", "Old MacDonald had a farm", "ascii"),
|
|
412
|
-
("dummy-bucket", "dummy/key.beta", "Ee-i-ee-i-o", "ascii"),
|
|
413
|
-
]
|
|
414
|
-
|
|
415
|
-
@ddt.idata(data_s3_text)
|
|
416
|
-
@ddt.unpack
|
|
417
|
-
def test_s3_text(self, bucket, key, text, encoding):
|
|
418
|
-
with moto.mock_aws(), s3_make_client(region_name="us-east-1") as client:
|
|
419
|
-
client.create_bucket(Bucket=bucket)
|
|
420
|
-
|
|
421
|
-
s3_push_text(client, text, bucket, key, encoding=encoding)
|
|
422
|
-
self.assertEqual(s3_pull_text(client, bucket, key, encoding=encoding), text)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/resources/unittest/config/config.cfg
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker/common/utils/dockerutils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/src/iker_python_common.egg-info/not-zip-safe
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/config_test.py
RENAMED
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/csv_test.py
RENAMED
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/dbutils_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/dtutils_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/logger_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/retry_test.py
RENAMED
|
File without changes
|
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/shutils_test.py
RENAMED
|
File without changes
|
{iker_python_common-1.0.58 → iker_python_common-1.0.59}/test/iker_tests/common/utils/span_test.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|