data-sourcerer 0.9.0__tar.gz → 0.9.1__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.
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/PKG-INFO +14 -1
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/pyproject.toml +17 -2
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/__init__.py +1 -1
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/access_credentials/entities.py +1 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/file_system/services.py +1 -3
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/storage_provider/services.py +2 -3
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/access_credentials/registry.py +1 -3
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/access_credentials/repositories.py +5 -15
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/access_credentials/services.py +4 -12
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/db/models.py +1 -3
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/file_system/services.py +1 -3
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/package_meta/services.py +1 -5
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/settings/repositories.py +1 -3
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage/repositories.py +1 -3
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage_provider/services/azure.py +11 -27
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage_provider/services/gcp.py +9 -23
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage_provider/services/s3.py +7 -18
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/app.py +1 -3
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/di_container.py +4 -12
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/about/main.py +3 -9
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/file_system_finder/main.py +5 -18
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py +16 -50
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/main.py +22 -69
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/styles.tcss +2 -2
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/widgets/storage_content.py +60 -49
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py +60 -43
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/preview_content/main.py +16 -34
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/provider_creds_list/main.py +82 -22
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/provider_creds_registration/main.py +8 -27
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/settings/main.py +4 -12
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/shared/widgets/labeled_input.py +1 -3
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/shared/widgets/spinner.py +1 -3
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/storage_action_progress/main.py +12 -15
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/storages_list/main.py +71 -7
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/storages_registration/main.py +2 -6
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/settings.py +1 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/utils.py +5 -12
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/settings.py +1 -1
- data_sourcerer-0.9.0/sourcerer/presentation/screens/main/mixins/resize_containers_watcher_mixin.py +0 -145
- data_sourcerer-0.9.0/sourcerer/presentation/screens/main/widgets/resizing_rule.py +0 -69
- data_sourcerer-0.9.0/sourcerer/presentation/themes/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/.gitignore +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/LICENSE +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/README.md +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/access_credentials/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/access_credentials/exceptions.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/access_credentials/repositories.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/access_credentials/services.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/file_system/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/file_system/entities.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/file_system/exceptions.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/package_meta/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/package_meta/entities.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/package_meta/services.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/settings/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/settings/entities.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/settings/repositories.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/settings/services.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/shared/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/shared/entities.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/storage/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/storage/entities.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/storage/repositories.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/storage_provider/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/storage_provider/entities.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/domain/storage_provider/exceptions.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/access_credentials/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/access_credentials/exceptions.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/db/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/db/config.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/file_system/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/file_system/exceptions.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/package_meta/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/settings/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/settings/services.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage/services.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage_provider/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage_provider/exceptions.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage_provider/registry.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage_provider/services/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/utils.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/about/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/about/styles.tcss +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/critical_error/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/critical_error/main.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/critical_error/styles.tcss +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/file_system_finder/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/file_system_finder/styles.tcss +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/file_system_finder/widgets/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/messages/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/messages/delete_request.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/messages/download_request.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/messages/presign_url_request.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/messages/preview_request.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/messages/refresh_storages_list_request.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/messages/resizing_rule.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/messages/select_storage_item.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/messages/uncheck_files_request.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/messages/upload_request.py +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/main/mixins → data_sourcerer-0.9.1/sourcerer/presentation/screens/main/widgets}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/main/widgets/gradient.py +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/main/widgets → data_sourcerer-0.9.1/sourcerer/presentation/screens/preview_content}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/preview_content/styles.tcss +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/preview_content/text_area_style.py +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/preview_content → data_sourcerer-0.9.1/sourcerer/presentation/screens/provider_creds_list}/__init__.py +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/provider_creds_list → data_sourcerer-0.9.1/sourcerer/presentation/screens/provider_creds_list/messages}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/provider_creds_list/messages/reload_credentials_request.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/provider_creds_list/styles.tcss +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/provider_creds_list/messages → data_sourcerer-0.9.1/sourcerer/presentation/screens/provider_creds_registration}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/provider_creds_registration/styles.tcss +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/provider_creds_registration → data_sourcerer-0.9.1/sourcerer/presentation/screens/question}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/question/main.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/question/styles.tcss +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/question → data_sourcerer-0.9.1/sourcerer/presentation/screens/settings}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/settings/styles.tcss +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/settings → data_sourcerer-0.9.1/sourcerer/presentation/screens/shared}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/shared/containers.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/shared/modal_screens.py +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/shared → data_sourcerer-0.9.1/sourcerer/presentation/screens/shared/widgets}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/shared/widgets/button.py +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/shared/widgets → data_sourcerer-0.9.1/sourcerer/presentation/screens/storage_action_progress}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/storage_action_progress/styles.tcss +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/storage_action_progress → data_sourcerer-0.9.1/sourcerer/presentation/screens/storages_list}/__init__.py +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/storages_list → data_sourcerer-0.9.1/sourcerer/presentation/screens/storages_list/messages}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/storages_list/messages/reload_storages_request.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/storages_list/styles.tcss +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/storages_list/messages → data_sourcerer-0.9.1/sourcerer/presentation/screens/storages_registration}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/screens/storages_registration/styles.tcss +0 -0
- {data_sourcerer-0.9.0/sourcerer/presentation/screens/storages_registration → data_sourcerer-0.9.1/sourcerer/presentation/themes}/__init__.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/presentation/themes/github_dark.py +0 -0
- {data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/utils.py +0 -0
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: data-sourcerer
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.1
|
|
4
4
|
Summary: Sourcerer is a terminal cloud storage navigator.
|
|
5
5
|
Author-email: Bohdana Kuzmenko <bohdana.kuzmenko.dev@gmail.com>
|
|
6
6
|
License: MIT
|
|
7
7
|
License-File: LICENSE
|
|
8
8
|
Keywords: cli,cloud,gcp,s3,storage,terminal,textual,ui
|
|
9
9
|
Requires-Python: >=3.10
|
|
10
|
+
Requires-Dist: aiohttp>=3.13.3
|
|
11
|
+
Requires-Dist: azure-core>=1.38.0
|
|
10
12
|
Requires-Dist: azure-identity<2.0.0,>=1.22.0
|
|
11
13
|
Requires-Dist: azure-mgmt-storage<23.0.0,>=22.2.0
|
|
12
14
|
Requires-Dist: azure-storage-blob<13.0.0,>=12.25.1
|
|
@@ -14,17 +16,28 @@ Requires-Dist: boto3<2.0.0,>=1.26.0
|
|
|
14
16
|
Requires-Dist: cachetools>=5.5.2
|
|
15
17
|
Requires-Dist: cryptography<47,>=46.0.5
|
|
16
18
|
Requires-Dist: dependency-injector<5.0.0,>=4.43.0
|
|
19
|
+
Requires-Dist: filelock>=3.20.1
|
|
17
20
|
Requires-Dist: google-cloud-storage<4.0.0,>=3.1.0
|
|
18
21
|
Requires-Dist: humanize<5.0.0,>=4.12.1
|
|
22
|
+
Requires-Dist: markdown>=3.8.1
|
|
19
23
|
Requires-Dist: msgspec>=0.19.0
|
|
20
24
|
Requires-Dist: packaging>=25.0
|
|
25
|
+
Requires-Dist: protobuf>=6.31.1
|
|
26
|
+
Requires-Dist: pyasn1>=0.6.3
|
|
27
|
+
Requires-Dist: pyjwt>=2.12.0
|
|
28
|
+
Requires-Dist: pymdown-extensions>=10.16.1
|
|
21
29
|
Requires-Dist: pyopenssl>=22.1.0; sys_platform == 'linux'
|
|
30
|
+
Requires-Dist: requests>=2.32.4
|
|
22
31
|
Requires-Dist: sqlalchemy-utils<1.0.0,>=0.41.2
|
|
23
32
|
Requires-Dist: sqlalchemy<3.0.0,>=2.0.38
|
|
24
33
|
Requires-Dist: textual[syntax]<5.0.1,>=2.0.0
|
|
34
|
+
Requires-Dist: urllib3>=2.6.3
|
|
35
|
+
Requires-Dist: uv>=0.9.6
|
|
36
|
+
Requires-Dist: virtualenv>=20.36.1
|
|
25
37
|
Provides-Extra: dev
|
|
26
38
|
Requires-Dist: bandit>=1.8.3; extra == 'dev'
|
|
27
39
|
Requires-Dist: black>=25.1.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: black>=26.3.1; extra == 'dev'
|
|
28
41
|
Requires-Dist: coverage>=7.8.0; extra == 'dev'
|
|
29
42
|
Requires-Dist: hatch>=1.14.1; extra == 'dev'
|
|
30
43
|
Requires-Dist: mkdocs-material>=9.6.12; extra == 'dev'
|
|
@@ -30,6 +30,18 @@ dependencies = [
|
|
|
30
30
|
"msgspec>=0.19.0",
|
|
31
31
|
"packaging>=25.0",
|
|
32
32
|
"cachetools>=5.5.2",
|
|
33
|
+
"azure-core>=1.38.0",
|
|
34
|
+
"urllib3>=2.6.3",
|
|
35
|
+
"protobuf>=6.31.1",
|
|
36
|
+
"aiohttp>=3.13.3",
|
|
37
|
+
"uv>=0.9.6",
|
|
38
|
+
"filelock>=3.20.1",
|
|
39
|
+
"pyasn1>=0.6.3",
|
|
40
|
+
"pyjwt>=2.12.0",
|
|
41
|
+
"markdown>=3.8.1",
|
|
42
|
+
"requests>=2.32.4",
|
|
43
|
+
"virtualenv>=20.36.1",
|
|
44
|
+
"pymdown-extensions>=10.16.1",
|
|
33
45
|
]
|
|
34
46
|
|
|
35
47
|
[project.scripts]
|
|
@@ -42,7 +54,7 @@ build-backend = "hatchling.build"
|
|
|
42
54
|
[dependency-groups]
|
|
43
55
|
dev = [
|
|
44
56
|
"bandit>=1.8.3",
|
|
45
|
-
"black>=
|
|
57
|
+
"black>=26.3.1",
|
|
46
58
|
"coverage>=7.8.0",
|
|
47
59
|
"hatch>=1.14.1",
|
|
48
60
|
"mkdocs-material>=9.6.12",
|
|
@@ -58,7 +70,7 @@ dev = [
|
|
|
58
70
|
[project.optional-dependencies]
|
|
59
71
|
dev = [
|
|
60
72
|
"bandit>=1.8.3",
|
|
61
|
-
"black>=
|
|
73
|
+
"black>=26.3.1",
|
|
62
74
|
"coverage>=7.8.0",
|
|
63
75
|
"hatch>=1.14.1",
|
|
64
76
|
"mkdocs-material>=9.6.12",
|
|
@@ -115,3 +127,6 @@ path = "src/sourcerer/__init__.py"
|
|
|
115
127
|
[tool.ty.rules]
|
|
116
128
|
unresolved-import = "ignore"
|
|
117
129
|
invalid-assignment = "warn"
|
|
130
|
+
|
|
131
|
+
[tool.black]
|
|
132
|
+
line-length = 120
|
|
@@ -42,9 +42,7 @@ class BaseFileSystemService(metaclass=abc.ABCMeta):
|
|
|
42
42
|
raise NotImplementedError
|
|
43
43
|
|
|
44
44
|
@abc.abstractmethod
|
|
45
|
-
def list_dir(
|
|
46
|
-
self, path: Path, relative_paths: bool = False, recursively=False
|
|
47
|
-
) -> ListDirOutput:
|
|
45
|
+
def list_dir(self, path: Path, relative_paths: bool = False, recursively=False) -> ListDirOutput:
|
|
48
46
|
"""
|
|
49
47
|
List all files and directories within the specified directory.
|
|
50
48
|
|
|
@@ -4,6 +4,7 @@ Base storage provider service interface.
|
|
|
4
4
|
This module defines the abstract base class for storage provider services,
|
|
5
5
|
providing a common interface for cloud storage operations.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import threading
|
|
8
9
|
from abc import ABC, abstractmethod
|
|
9
10
|
from collections.abc import Callable
|
|
@@ -48,9 +49,7 @@ class BaseStorageProviderService(ABC):
|
|
|
48
49
|
"""
|
|
49
50
|
|
|
50
51
|
@abstractmethod
|
|
51
|
-
def list_storage_items(
|
|
52
|
-
self, storage: str, path: str, prefix: str
|
|
53
|
-
) -> StorageContent:
|
|
52
|
+
def list_storage_items(self, storage: str, path: str, prefix: str) -> StorageContent:
|
|
54
53
|
"""
|
|
55
54
|
List items in the specified storage path with the given prefix.
|
|
56
55
|
|
|
@@ -53,9 +53,7 @@ class AccessCredentialsRegistry(metaclass=Singleton):
|
|
|
53
53
|
"""
|
|
54
54
|
if access_credentials_method.provider not in self._items_:
|
|
55
55
|
self._items_[access_credentials_method.provider] = {}
|
|
56
|
-
self._items_[access_credentials_method.provider].update(
|
|
57
|
-
{access_credentials_method.name: cls}
|
|
58
|
-
)
|
|
56
|
+
self._items_[access_credentials_method.provider].update({access_credentials_method.name: cls})
|
|
59
57
|
|
|
60
58
|
def get(self):
|
|
61
59
|
"""
|
|
@@ -54,9 +54,7 @@ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
|
|
|
54
54
|
uuid (str): Unique identifier for the credentials to delete
|
|
55
55
|
"""
|
|
56
56
|
with self.db() as session:
|
|
57
|
-
credentials = (
|
|
58
|
-
session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
|
|
59
|
-
)
|
|
57
|
+
credentials = session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
|
|
60
58
|
if credentials is None:
|
|
61
59
|
# No matching credentials found; return early
|
|
62
60
|
return
|
|
@@ -74,9 +72,7 @@ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
|
|
|
74
72
|
DBCredentials: The credentials object from the database
|
|
75
73
|
"""
|
|
76
74
|
with self.db() as session:
|
|
77
|
-
return (
|
|
78
|
-
session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
|
|
79
|
-
)
|
|
75
|
+
return session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
|
|
80
76
|
|
|
81
77
|
def list(self, active_only: bool | None = None) -> list[Credentials]:
|
|
82
78
|
"""
|
|
@@ -92,9 +88,7 @@ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
|
|
|
92
88
|
with self.db() as session:
|
|
93
89
|
credentials_query = session.query(DBCredentials)
|
|
94
90
|
if active_only:
|
|
95
|
-
credentials_query = credentials_query.filter(
|
|
96
|
-
DBCredentials.active == True # noqa: E712
|
|
97
|
-
)
|
|
91
|
+
credentials_query = credentials_query.filter(DBCredentials.active == True) # noqa: E712
|
|
98
92
|
return [
|
|
99
93
|
Credentials(
|
|
100
94
|
uuid=credential.uuid,
|
|
@@ -116,9 +110,7 @@ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
|
|
|
116
110
|
uuid (str): Unique identifier for the credentials to activate
|
|
117
111
|
"""
|
|
118
112
|
with self.db() as session:
|
|
119
|
-
credentials = (
|
|
120
|
-
session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
|
|
121
|
-
)
|
|
113
|
+
credentials = session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
|
|
122
114
|
credentials.active = True
|
|
123
115
|
session.commit()
|
|
124
116
|
|
|
@@ -130,8 +122,6 @@ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
|
|
|
130
122
|
uuid (str): Unique identifier for the credentials to deactivate
|
|
131
123
|
"""
|
|
132
124
|
with self.db() as session:
|
|
133
|
-
credentials = (
|
|
134
|
-
session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
|
|
135
|
-
)
|
|
125
|
+
credentials = session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
|
|
136
126
|
credentials.active = False
|
|
137
127
|
session.commit()
|
|
@@ -316,9 +316,7 @@ class S3ProfileName(S3AccessCredentialsService):
|
|
|
316
316
|
]
|
|
317
317
|
|
|
318
318
|
|
|
319
|
-
@access_credentials_method(
|
|
320
|
-
AccessCredentialsMethod(StorageProvider.GoogleCloudStorage, "Service account")
|
|
321
|
-
)
|
|
319
|
+
@access_credentials_method(AccessCredentialsMethod(StorageProvider.GoogleCloudStorage, "Service account"))
|
|
322
320
|
class GCPCredentialsService(AccessCredentialsService):
|
|
323
321
|
"""
|
|
324
322
|
Google Cloud Platform json credentials service.
|
|
@@ -413,9 +411,7 @@ class GCPCredentialsService(AccessCredentialsService):
|
|
|
413
411
|
]
|
|
414
412
|
|
|
415
413
|
|
|
416
|
-
@access_credentials_method(
|
|
417
|
-
AccessCredentialsMethod(StorageProvider.AzureStorage, "Client Secret Credentials")
|
|
418
|
-
)
|
|
414
|
+
@access_credentials_method(AccessCredentialsMethod(StorageProvider.AzureStorage, "Client Secret Credentials"))
|
|
419
415
|
class AzureClientSecretCredentialsService(AccessCredentialsService):
|
|
420
416
|
def store(self, name, credentials: dict):
|
|
421
417
|
"""
|
|
@@ -453,9 +449,7 @@ class AzureClientSecretCredentialsService(AccessCredentialsService):
|
|
|
453
449
|
# Parse the outer JSON structure
|
|
454
450
|
parsed_credentials = json.loads(credentials)
|
|
455
451
|
subscription_id = parsed_credentials.get("subscription_id")
|
|
456
|
-
cloud_suffix = (
|
|
457
|
-
parsed_credentials.get("cloud_suffix") or "blob.core.windows.net"
|
|
458
|
-
)
|
|
452
|
+
cloud_suffix = parsed_credentials.get("cloud_suffix") or "blob.core.windows.net"
|
|
459
453
|
|
|
460
454
|
client_credentials = ClientSecretCredential(
|
|
461
455
|
tenant_id=parsed_credentials.get("tenant_id"),
|
|
@@ -487,7 +481,5 @@ class AzureClientSecretCredentialsService(AccessCredentialsService):
|
|
|
487
481
|
AuthField("tenant_id", "Tenant Id", True),
|
|
488
482
|
AuthField("client_id", "Client Id", True),
|
|
489
483
|
AuthField("client_secret", "Client Secret", True),
|
|
490
|
-
AuthField(
|
|
491
|
-
"cloud_suffix", "Cloud Suffix (default blob.core.windows.net)", False
|
|
492
|
-
),
|
|
484
|
+
AuthField("cloud_suffix", "Cloud Suffix (default blob.core.windows.net)", False),
|
|
493
485
|
]
|
|
@@ -66,9 +66,7 @@ class Storage(Base):
|
|
|
66
66
|
id = Column(Integer, primary_key=True)
|
|
67
67
|
uuid = Column(String, unique=True, nullable=False)
|
|
68
68
|
name = Column(String, nullable=False)
|
|
69
|
-
credentials_id = Column(
|
|
70
|
-
Integer, ForeignKey("credentials.id", ondelete="CASCADE"), nullable=False
|
|
71
|
-
)
|
|
69
|
+
credentials_id = Column(Integer, ForeignKey("credentials.id", ondelete="CASCADE"), nullable=False)
|
|
72
70
|
created_at = Column(DateTime, default=datetime.utcnow)
|
|
73
71
|
|
|
74
72
|
credentials = relationship(
|
{data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/file_system/services.py
RENAMED
|
@@ -112,9 +112,7 @@ class FileSystemService(BaseFileSystemService):
|
|
|
112
112
|
items = 0
|
|
113
113
|
for entry in entries:
|
|
114
114
|
if max_items and items > max_items:
|
|
115
|
-
raise ListDirError(
|
|
116
|
-
f"Too many items, max processable dir size: {max_items}"
|
|
117
|
-
)
|
|
115
|
+
raise ListDirError(f"Too many items, max processable dir size: {max_items}")
|
|
118
116
|
items += 1 # noqa SIM103
|
|
119
117
|
target = files if entry.is_file() else directories
|
|
120
118
|
target.append(entry.relative_to(path) if relative_paths else entry)
|
{data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/package_meta/services.py
RENAMED
|
@@ -11,11 +11,7 @@ from sourcerer.utils import get_last_package_version
|
|
|
11
11
|
class PackageMetaService(BasePackageMetaService):
|
|
12
12
|
def get_package_meta(self) -> PackageMeta:
|
|
13
13
|
latest_version = get_last_package_version(package_name)
|
|
14
|
-
has_available_update = (
|
|
15
|
-
version.parse(latest_version) > version.parse(__version__)
|
|
16
|
-
if latest_version
|
|
17
|
-
else False
|
|
18
|
-
)
|
|
14
|
+
has_available_update = version.parse(latest_version) > version.parse(__version__) if latest_version else False
|
|
19
15
|
|
|
20
16
|
return PackageMeta(
|
|
21
17
|
version=__version__,
|
{data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/settings/repositories.py
RENAMED
|
@@ -23,9 +23,7 @@ class SQLAlchemySettingsRepository(BaseSettingsRepository):
|
|
|
23
23
|
type_hints = get_type_hints(Settings)
|
|
24
24
|
return Settings(
|
|
25
25
|
**{
|
|
26
|
-
setting.key: self.parse_value(
|
|
27
|
-
setting.key, setting.value, type_hints.get(setting.key, str)
|
|
28
|
-
)
|
|
26
|
+
setting.key: self.parse_value(setting.key, setting.value, type_hints.get(setting.key, str))
|
|
29
27
|
for setting in settings
|
|
30
28
|
}
|
|
31
29
|
)
|
{data_sourcerer-0.9.0 → data_sourcerer-0.9.1}/sourcerer/infrastructure/storage/repositories.py
RENAMED
|
@@ -63,9 +63,7 @@ class SQLAlchemyStoragesRepository(BaseStoragesRepository):
|
|
|
63
63
|
uuid (str): The UUID of the storage entity to be deleted
|
|
64
64
|
"""
|
|
65
65
|
with self.db() as session:
|
|
66
|
-
storage = (
|
|
67
|
-
session.query(DBStorage).filter(DBStorage.uuid == uuid).one_or_none()
|
|
68
|
-
)
|
|
66
|
+
storage = session.query(DBStorage).filter(DBStorage.uuid == uuid).one_or_none()
|
|
69
67
|
if storage is None:
|
|
70
68
|
return
|
|
71
69
|
session.delete(storage)
|
|
@@ -4,6 +4,7 @@ Implementation of Azure storage provider services.
|
|
|
4
4
|
This module provides concrete implementations of the BaseStorageProviderService
|
|
5
5
|
interface for various cloud storage providers.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import asyncio
|
|
8
9
|
import base64
|
|
9
10
|
import os.path
|
|
@@ -79,9 +80,7 @@ class AzureStorageProviderService(BaseStorageProviderService):
|
|
|
79
80
|
|
|
80
81
|
self._storage_management_client: StorageManagementClient | None = None
|
|
81
82
|
self._blob_service_clients_lock = threading.Lock()
|
|
82
|
-
self._blob_service_clients: LRUCache[str, BlobServiceClient] = LRUCache(
|
|
83
|
-
maxsize=self.MAX_CACHE_SIZE
|
|
84
|
-
)
|
|
83
|
+
self._blob_service_clients: LRUCache[str, BlobServiceClient] = LRUCache(maxsize=self.MAX_CACHE_SIZE)
|
|
85
84
|
|
|
86
85
|
self.upload_chunk_size = upload_chunk_size * 1024 * 1024
|
|
87
86
|
self.download_chunk_size = download_chunk_size * 1024 * 1024
|
|
@@ -97,9 +96,7 @@ class AzureStorageProviderService(BaseStorageProviderService):
|
|
|
97
96
|
if self._storage_management_client:
|
|
98
97
|
return self._storage_management_client
|
|
99
98
|
|
|
100
|
-
self._storage_management_client = StorageManagementClient(
|
|
101
|
-
self.credentials, self.subscription_id
|
|
102
|
-
)
|
|
99
|
+
self._storage_management_client = StorageManagementClient(self.credentials, self.subscription_id)
|
|
103
100
|
return self._storage_management_client
|
|
104
101
|
|
|
105
102
|
def get_containers_client(self, storage: str):
|
|
@@ -150,9 +147,7 @@ class AzureStorageProviderService(BaseStorageProviderService):
|
|
|
150
147
|
def get_storage_permissions(self, storage: str) -> list[StoragePermissions]:
|
|
151
148
|
raise NotImplementedError("Not implemented")
|
|
152
149
|
|
|
153
|
-
def list_storage_items(
|
|
154
|
-
self, storage: str, path: str, prefix: str
|
|
155
|
-
) -> StorageContent:
|
|
150
|
+
def list_storage_items(self, storage: str, path: str, prefix: str) -> StorageContent:
|
|
156
151
|
"""
|
|
157
152
|
List items in the specified Azure container path with the given prefix.
|
|
158
153
|
|
|
@@ -190,12 +185,8 @@ class AzureStorageProviderService(BaseStorageProviderService):
|
|
|
190
185
|
)
|
|
191
186
|
parent_path = parent_path.rstrip("/") + "/"
|
|
192
187
|
|
|
193
|
-
for blob in blobs_client.walk_blobs(
|
|
194
|
-
|
|
195
|
-
):
|
|
196
|
-
remaining_path = blob.name[
|
|
197
|
-
len(base_path) + len(prefix_dirs) :
|
|
198
|
-
].lstrip("/")
|
|
188
|
+
for blob in blobs_client.walk_blobs(name_starts_with=base_path + prefix, delimiter="/"):
|
|
189
|
+
remaining_path = blob.name[len(base_path) + len(prefix_dirs) :].lstrip("/")
|
|
199
190
|
|
|
200
191
|
if "/" in remaining_path:
|
|
201
192
|
folder_name = remaining_path.split("/")[0]
|
|
@@ -279,9 +270,7 @@ class AzureStorageProviderService(BaseStorageProviderService):
|
|
|
279
270
|
"""
|
|
280
271
|
try:
|
|
281
272
|
if not storage_path:
|
|
282
|
-
raise AzureMissingContainerError(
|
|
283
|
-
"Container is required for Azure storage"
|
|
284
|
-
)
|
|
273
|
+
raise AzureMissingContainerError("Container is required for Azure storage")
|
|
285
274
|
|
|
286
275
|
containers_client = self.get_containers_client(storage)
|
|
287
276
|
|
|
@@ -295,9 +284,7 @@ class AzureStorageProviderService(BaseStorageProviderService):
|
|
|
295
284
|
if source_path.stat().st_size <= self.upload_chunk_size:
|
|
296
285
|
blob_client = containers_client.get_container_client(container)
|
|
297
286
|
with open(source_path, "rb") as file_handle:
|
|
298
|
-
blob_client.upload_blob(
|
|
299
|
-
blob_name or source_path.name, file_handle, overwrite=True
|
|
300
|
-
)
|
|
287
|
+
blob_client.upload_blob(blob_name or source_path.name, file_handle, overwrite=True)
|
|
301
288
|
if progress_callback:
|
|
302
289
|
progress_callback(source_path.stat().st_size)
|
|
303
290
|
else:
|
|
@@ -340,8 +327,7 @@ class AzureStorageProviderService(BaseStorageProviderService):
|
|
|
340
327
|
download_path = Path(user_downloads_dir()) / Path(key).name
|
|
341
328
|
suffix = Path(key).suffix
|
|
342
329
|
download_tmp_path = (
|
|
343
|
-
Path(user_downloads_dir())
|
|
344
|
-
/ f"{next(tempfile._get_candidate_names())}{suffix}" # type: ignore
|
|
330
|
+
Path(user_downloads_dir()) / f"{next(tempfile._get_candidate_names())}{suffix}" # type: ignore
|
|
345
331
|
)
|
|
346
332
|
|
|
347
333
|
containers_client = self.get_containers_client(storage)
|
|
@@ -424,8 +410,7 @@ class AzureStorageProviderService(BaseStorageProviderService):
|
|
|
424
410
|
|
|
425
411
|
user_delegation_key = containers_client.get_user_delegation_key(
|
|
426
412
|
key_start_time=datetime.utcnow(),
|
|
427
|
-
key_expiry_time=datetime.utcnow()
|
|
428
|
-
+ timedelta(seconds=self.presigned_url_expiration_period),
|
|
413
|
+
key_expiry_time=datetime.utcnow() + timedelta(seconds=self.presigned_url_expiration_period),
|
|
429
414
|
)
|
|
430
415
|
|
|
431
416
|
sas_token = generate_blob_sas(
|
|
@@ -433,8 +418,7 @@ class AzureStorageProviderService(BaseStorageProviderService):
|
|
|
433
418
|
container_name=container,
|
|
434
419
|
blob_name=blob_name,
|
|
435
420
|
permission=BlobSasPermissions(read=True),
|
|
436
|
-
expiry=datetime.utcnow()
|
|
437
|
-
+ timedelta(seconds=self.presigned_url_expiration_period),
|
|
421
|
+
expiry=datetime.utcnow() + timedelta(seconds=self.presigned_url_expiration_period),
|
|
438
422
|
user_delegation_key=user_delegation_key,
|
|
439
423
|
)
|
|
440
424
|
url = f"https://{account_name}.blob.core.windows.net/{container}/{blob_name}?{sas_token}"
|
|
@@ -4,6 +4,7 @@ Implementation of GCP storage provider services.
|
|
|
4
4
|
This module provides concrete implementations of the BaseStorageProviderService
|
|
5
5
|
interface for various cloud storage providers.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import datetime
|
|
8
9
|
import shutil
|
|
9
10
|
import tempfile
|
|
@@ -85,8 +86,7 @@ class GCPStorageProviderService(BaseStorageProviderService):
|
|
|
85
86
|
"""
|
|
86
87
|
try:
|
|
87
88
|
return [
|
|
88
|
-
Storage(StorageProvider.GoogleCloudStorage, i.name, i.time_created)
|
|
89
|
-
for i in self.client.list_buckets()
|
|
89
|
+
Storage(StorageProvider.GoogleCloudStorage, i.name, i.time_created) for i in self.client.list_buckets()
|
|
90
90
|
]
|
|
91
91
|
except Exception as ex:
|
|
92
92
|
raise ListStoragesError(str(ex)) from ex
|
|
@@ -115,15 +115,11 @@ class GCPStorageProviderService(BaseStorageProviderService):
|
|
|
115
115
|
if member not in result:
|
|
116
116
|
result[member] = set()
|
|
117
117
|
result[member].add(role)
|
|
118
|
-
return [
|
|
119
|
-
StoragePermissions(member, roles) for member, roles in result.items()
|
|
120
|
-
]
|
|
118
|
+
return [StoragePermissions(member, roles) for member, roles in result.items()]
|
|
121
119
|
except Exception as ex:
|
|
122
120
|
raise StoragePermissionError(str(ex)) from ex
|
|
123
121
|
|
|
124
|
-
def list_storage_items(
|
|
125
|
-
self, storage: str, path: str = "", prefix: str = ""
|
|
126
|
-
) -> StorageContent:
|
|
122
|
+
def list_storage_items(self, storage: str, path: str = "", prefix: str = "") -> StorageContent:
|
|
127
123
|
"""
|
|
128
124
|
List items in the specified GCP bucket path with the given prefix.
|
|
129
125
|
|
|
@@ -163,18 +159,13 @@ class GCPStorageProviderService(BaseStorageProviderService):
|
|
|
163
159
|
]
|
|
164
160
|
|
|
165
161
|
folders = [
|
|
166
|
-
Folder(
|
|
167
|
-
key=folder[prefix_folders_len:].strip("/"), parent_path=parent_path
|
|
168
|
-
)
|
|
169
|
-
for folder in blobs.prefixes
|
|
162
|
+
Folder(key=folder[prefix_folders_len:].strip("/"), parent_path=parent_path) for folder in blobs.prefixes
|
|
170
163
|
]
|
|
171
164
|
|
|
172
165
|
return StorageContent(files=files, folders=folders)
|
|
173
166
|
|
|
174
167
|
except Exception as ex:
|
|
175
|
-
raise ListStorageItemsError(
|
|
176
|
-
f"Failed to list items in {storage}: {ex}"
|
|
177
|
-
) from ex
|
|
168
|
+
raise ListStorageItemsError(f"Failed to list items in {storage}: {ex}") from ex
|
|
178
169
|
|
|
179
170
|
def read_storage_item(self, storage: str, key: str) -> str:
|
|
180
171
|
"""
|
|
@@ -245,9 +236,7 @@ class GCPStorageProviderService(BaseStorageProviderService):
|
|
|
245
236
|
"""
|
|
246
237
|
try:
|
|
247
238
|
bucket = self.client.bucket(storage)
|
|
248
|
-
storage_path = str(
|
|
249
|
-
Path(storage_path or "") / (dest_path or source_path.name)
|
|
250
|
-
)
|
|
239
|
+
storage_path = str(Path(storage_path or "") / (dest_path or source_path.name))
|
|
251
240
|
blob = bucket.blob(storage_path)
|
|
252
241
|
if source_path.stat().st_size <= self.upload_chunk_size:
|
|
253
242
|
blob.upload_from_filename(source_path)
|
|
@@ -290,8 +279,7 @@ class GCPStorageProviderService(BaseStorageProviderService):
|
|
|
290
279
|
|
|
291
280
|
suffix = Path(key).suffix
|
|
292
281
|
download_tmp_path = (
|
|
293
|
-
Path(user_downloads_dir())
|
|
294
|
-
/ f"{next(tempfile._get_candidate_names())}{suffix}" # type: ignore
|
|
282
|
+
Path(user_downloads_dir()) / f"{next(tempfile._get_candidate_names())}{suffix}" # type: ignore
|
|
295
283
|
)
|
|
296
284
|
|
|
297
285
|
downloaded = 0
|
|
@@ -363,9 +351,7 @@ class GCPStorageProviderService(BaseStorageProviderService):
|
|
|
363
351
|
|
|
364
352
|
response = blob.generate_signed_url(
|
|
365
353
|
version="v4",
|
|
366
|
-
expiration=datetime.timedelta(
|
|
367
|
-
seconds=self.presigned_url_expiration_period
|
|
368
|
-
),
|
|
354
|
+
expiration=datetime.timedelta(seconds=self.presigned_url_expiration_period),
|
|
369
355
|
method="GET",
|
|
370
356
|
)
|
|
371
357
|
except Exception as ex:
|
|
@@ -4,6 +4,7 @@ Implementation of S3 compatible storage provider services.
|
|
|
4
4
|
This module provides concrete implementations of the BaseStorageProviderService
|
|
5
5
|
interface for various cloud storage providers.
|
|
6
6
|
"""
|
|
7
|
+
|
|
7
8
|
import shutil
|
|
8
9
|
import tempfile
|
|
9
10
|
import threading
|
|
@@ -124,10 +125,7 @@ class S3ProviderService(BaseStorageProviderService):
|
|
|
124
125
|
response = self.client.list_buckets()
|
|
125
126
|
except Exception as ex:
|
|
126
127
|
raise ListStoragesError(str(ex)) from ex
|
|
127
|
-
return [
|
|
128
|
-
Storage(StorageProvider.S3, i.get("Name"), i.get("CreationDate"))
|
|
129
|
-
for i in response.get("Buckets")
|
|
130
|
-
]
|
|
128
|
+
return [Storage(StorageProvider.S3, i.get("Name"), i.get("CreationDate")) for i in response.get("Buckets")]
|
|
131
129
|
|
|
132
130
|
def get_storage_permissions(self, storage: str) -> list[StoragePermissions]:
|
|
133
131
|
"""
|
|
@@ -154,9 +152,7 @@ class S3ProviderService(BaseStorageProviderService):
|
|
|
154
152
|
)
|
|
155
153
|
]
|
|
156
154
|
|
|
157
|
-
def list_storage_items(
|
|
158
|
-
self, storage: str, path: str = "", prefix: str = ""
|
|
159
|
-
) -> StorageContent:
|
|
155
|
+
def list_storage_items(self, storage: str, path: str = "", prefix: str = "") -> StorageContent:
|
|
160
156
|
"""
|
|
161
157
|
List items in the specified S3 bucket path with the given prefix.
|
|
162
158
|
|
|
@@ -314,13 +310,10 @@ class S3ProviderService(BaseStorageProviderService):
|
|
|
314
310
|
download_path = Path(user_downloads_dir()) / Path(key).name
|
|
315
311
|
suffix = Path(key).suffix
|
|
316
312
|
download_tmp_path = (
|
|
317
|
-
Path(user_downloads_dir())
|
|
318
|
-
/ f"{next(tempfile._get_candidate_names())}{suffix}" # type: ignore
|
|
313
|
+
Path(user_downloads_dir()) / f"{next(tempfile._get_candidate_names())}{suffix}" # type: ignore
|
|
319
314
|
)
|
|
320
315
|
|
|
321
|
-
self.client.download_file(
|
|
322
|
-
storage, key, download_tmp_path, Callback=callback
|
|
323
|
-
)
|
|
316
|
+
self.client.download_file(storage, key, download_tmp_path, Callback=callback)
|
|
324
317
|
shutil.move(download_tmp_path, download_path)
|
|
325
318
|
return str(download_path)
|
|
326
319
|
except Exception as ex:
|
|
@@ -384,9 +377,7 @@ class S3ProviderService(BaseStorageProviderService):
|
|
|
384
377
|
|
|
385
378
|
with open(source_path, "rb") as file_handle:
|
|
386
379
|
# Initiate multipart upload
|
|
387
|
-
response = self.client.create_multipart_upload(
|
|
388
|
-
Bucket=storage, Key=dest_path
|
|
389
|
-
)
|
|
380
|
+
response = self.client.create_multipart_upload(Bucket=storage, Key=dest_path)
|
|
390
381
|
upload_id = response["UploadId"]
|
|
391
382
|
|
|
392
383
|
part_number = 1
|
|
@@ -429,7 +420,5 @@ class S3ProviderService(BaseStorageProviderService):
|
|
|
429
420
|
except Exception:
|
|
430
421
|
# Abort multipart if error or cancel
|
|
431
422
|
if upload_id:
|
|
432
|
-
self.client.abort_multipart_upload(
|
|
433
|
-
Bucket=storage, Key=dest_path, UploadId=upload_id
|
|
434
|
-
)
|
|
423
|
+
self.client.abort_multipart_upload(Bucket=storage, Key=dest_path, UploadId=upload_id)
|
|
435
424
|
raise
|
|
@@ -21,9 +21,7 @@ def main():
|
|
|
21
21
|
4. Creates and runs the main application window
|
|
22
22
|
"""
|
|
23
23
|
di_container = DiContainer()
|
|
24
|
-
di_container.config.access_credential_method_registry.from_value(
|
|
25
|
-
access_credential_method_registry
|
|
26
|
-
)
|
|
24
|
+
di_container.config.access_credential_method_registry.from_value(access_credential_method_registry)
|
|
27
25
|
di_container.wire(packages=["sourcerer"])
|
|
28
26
|
|
|
29
27
|
DiContainer.db().prepare_db()
|
|
@@ -45,21 +45,13 @@ class DiContainer(containers.DeclarativeContainer):
|
|
|
45
45
|
db = providers.Singleton(Database, db_url=DB_URL)
|
|
46
46
|
session_factory = providers.Factory(Database.session_factory, db=db)
|
|
47
47
|
|
|
48
|
-
credentials_repository = providers.Factory(
|
|
49
|
-
SQLAlchemyCredentialsRepository, session_factory
|
|
50
|
-
)
|
|
48
|
+
credentials_repository = providers.Factory(SQLAlchemyCredentialsRepository, session_factory)
|
|
51
49
|
|
|
52
|
-
storages_repository = providers.Factory(
|
|
53
|
-
SQLAlchemyStoragesRepository, session_factory
|
|
54
|
-
)
|
|
50
|
+
storages_repository = providers.Factory(SQLAlchemyStoragesRepository, session_factory)
|
|
55
51
|
|
|
56
|
-
settings_repository = providers.Factory(
|
|
57
|
-
SQLAlchemySettingsRepository, session_factory
|
|
58
|
-
)
|
|
52
|
+
settings_repository = providers.Factory(SQLAlchemySettingsRepository, session_factory)
|
|
59
53
|
|
|
60
|
-
credentials_service = providers.Factory(
|
|
61
|
-
CredentialsService, repository=credentials_repository
|
|
62
|
-
)
|
|
54
|
+
credentials_service = providers.Factory(CredentialsService, repository=credentials_repository)
|
|
63
55
|
storages_service = providers.Factory(
|
|
64
56
|
StoragesService,
|
|
65
57
|
repository=storages_repository,
|
|
@@ -18,9 +18,7 @@ class AboutScreen(ExitBoundModalScreen):
|
|
|
18
18
|
|
|
19
19
|
def __init__(
|
|
20
20
|
self,
|
|
21
|
-
package_meta_service: BasePackageMetaService = Provide[
|
|
22
|
-
DiContainer.package_meta_service
|
|
23
|
-
],
|
|
21
|
+
package_meta_service: BasePackageMetaService = Provide[DiContainer.package_meta_service],
|
|
24
22
|
) -> None:
|
|
25
23
|
super().__init__()
|
|
26
24
|
self.package_meta_service = package_meta_service
|
|
@@ -29,7 +27,7 @@ class AboutScreen(ExitBoundModalScreen):
|
|
|
29
27
|
package_meta = self.package_meta_service.get_package_meta()
|
|
30
28
|
|
|
31
29
|
with Container():
|
|
32
|
-
yield Static(Text("Sourcerer", style="bold
|
|
30
|
+
yield Static(Text("Sourcerer", style="bold", justify="center"))
|
|
33
31
|
yield Static(
|
|
34
32
|
Text(
|
|
35
33
|
f"Version: {package_meta.version}"
|
|
@@ -38,11 +36,7 @@ class AboutScreen(ExitBoundModalScreen):
|
|
|
38
36
|
justify="center",
|
|
39
37
|
)
|
|
40
38
|
)
|
|
41
|
-
yield Static(
|
|
42
|
-
Text(
|
|
43
|
-
f"Platform: {package_meta.platform}", style="dim", justify="center"
|
|
44
|
-
)
|
|
45
|
-
)
|
|
39
|
+
yield Static(Text(f"Platform: {package_meta.platform}", style="dim", justify="center"))
|
|
46
40
|
yield Static(
|
|
47
41
|
Text(
|
|
48
42
|
f"System Version: {package_meta.system_version}",
|