data-sourcerer 0.2.0__py3-none-any.whl → 0.2.2__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.
Files changed (40) hide show
  1. {data_sourcerer-0.2.0.dist-info → data_sourcerer-0.2.2.dist-info}/METADATA +23 -21
  2. {data_sourcerer-0.2.0.dist-info → data_sourcerer-0.2.2.dist-info}/RECORD +39 -36
  3. {data_sourcerer-0.2.0.dist-info → data_sourcerer-0.2.2.dist-info}/WHEEL +1 -2
  4. sourcerer/__init__.py +1 -1
  5. sourcerer/domain/access_credentials/entities.py +4 -7
  6. sourcerer/domain/access_credentials/repositories.py +12 -0
  7. sourcerer/domain/access_credentials/services.py +2 -1
  8. sourcerer/domain/file_system/entities.py +5 -7
  9. sourcerer/domain/storage_provider/entities.py +7 -11
  10. sourcerer/infrastructure/access_credentials/registry.py +1 -1
  11. sourcerer/infrastructure/access_credentials/repositories.py +17 -0
  12. sourcerer/infrastructure/access_credentials/services.py +30 -14
  13. sourcerer/infrastructure/db/config.py +1 -1
  14. sourcerer/infrastructure/storage_provider/services/azure.py +5 -3
  15. sourcerer/infrastructure/utils.py +115 -1
  16. sourcerer/presentation/screens/critical_error/main.py +4 -4
  17. sourcerer/presentation/screens/file_system_finder/main.py +7 -3
  18. sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py +1 -1
  19. sourcerer/presentation/screens/main/main.py +37 -6
  20. sourcerer/presentation/screens/main/messages/refresh_storages_list_request.py +8 -0
  21. sourcerer/presentation/screens/main/widgets/gradient.py +3 -3
  22. sourcerer/presentation/screens/main/widgets/resizing_rule.py +3 -1
  23. sourcerer/presentation/screens/main/widgets/storage_content.py +47 -18
  24. sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py +38 -6
  25. sourcerer/presentation/screens/preview_content/main.py +5 -5
  26. sourcerer/presentation/screens/provider_creds_list/main.py +44 -0
  27. sourcerer/presentation/screens/provider_creds_list/messages/__init__.py +0 -0
  28. sourcerer/presentation/screens/provider_creds_list/messages/reload_credentials_request.py +8 -0
  29. sourcerer/presentation/screens/provider_creds_list/styles.tcss +5 -5
  30. sourcerer/presentation/screens/provider_creds_registration/main.py +6 -2
  31. sourcerer/presentation/screens/question/main.py +4 -3
  32. sourcerer/presentation/screens/question/styles.tcss +2 -8
  33. sourcerer/presentation/screens/shared/widgets/button.py +1 -1
  34. sourcerer/presentation/screens/shared/widgets/labeled_input.py +6 -2
  35. sourcerer/presentation/screens/shared/widgets/loader.py +31 -0
  36. sourcerer/presentation/screens/storage_action_progress/main.py +28 -26
  37. sourcerer/utils.py +1 -1
  38. data_sourcerer-0.2.0.dist-info/top_level.txt +0 -1
  39. {data_sourcerer-0.2.0.dist-info → data_sourcerer-0.2.2.dist-info}/entry_points.txt +0 -0
  40. {data_sourcerer-0.2.0.dist-info → data_sourcerer-0.2.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,42 +1,44 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: data-sourcerer
3
- Version: 0.2.0
3
+ Version: 0.2.2
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
- Keywords: cloud,s3,gcp,cli,terminal,storage,textual,ui
8
- Requires-Python: >=3.9
9
- Description-Content-Type: text/markdown
10
7
  License-File: LICENSE
8
+ Keywords: cli,cloud,gcp,s3,storage,terminal,textual,ui
9
+ Requires-Python: >=3.9
10
+ Requires-Dist: azure-identity<2.0.0,>=1.22.0
11
+ Requires-Dist: azure-mgmt-storage<23.0.0,>=22.2.0
12
+ Requires-Dist: azure-storage-blob<13.0.0,>=12.25.1
11
13
  Requires-Dist: boto3<2.0.0,>=1.26.0
12
14
  Requires-Dist: cryptography<45.0.0,>=44.0.2
13
15
  Requires-Dist: dependency-injector<5.0.0,>=4.43.0
14
16
  Requires-Dist: google-cloud-storage<4.0.0,>=3.1.0
15
17
  Requires-Dist: humanize<5.0.0,>=4.12.1
16
- Requires-Dist: sqlalchemy<3.0.0,>=2.0.38
18
+ Requires-Dist: msgspec>=0.19.0
19
+ Requires-Dist: pyopenssl>=22.1.0; sys_platform == 'linux'
17
20
  Requires-Dist: sqlalchemy-utils<1.0.0,>=0.41.2
21
+ Requires-Dist: sqlalchemy<3.0.0,>=2.0.38
18
22
  Requires-Dist: textual[syntax]<4.0.0,>=2.0.0
19
- Requires-Dist: pyOpenSSL>=22.1.0; sys_platform == "linux"
20
- Requires-Dist: azure-storage-blob<13.0.0,>=12.25.1
21
- Requires-Dist: azure-identity<2.0.0,>=1.22.0
22
- Requires-Dist: azure-mgmt-storage<23.0.0,>=22.2.0
23
23
  Provides-Extra: dev
24
- Requires-Dist: bandit>=1.8.3; extra == "dev"
25
- Requires-Dist: black>=25.1.0; extra == "dev"
26
- Requires-Dist: coverage>=7.8.0; extra == "dev"
27
- Requires-Dist: mkdocs-material>=9.6.12; extra == "dev"
28
- Requires-Dist: pre-commit>=4.2.0; extra == "dev"
29
- Requires-Dist: pylint>=3.3.6; extra == "dev"
30
- Requires-Dist: pyright>=1.1.400; extra == "dev"
31
- Requires-Dist: ruff>=0.11.7; extra == "dev"
32
- Requires-Dist: textual-dev>=1.7.0; extra == "dev"
33
- Dynamic: license-file
24
+ Requires-Dist: bandit>=1.8.3; extra == 'dev'
25
+ Requires-Dist: black>=25.1.0; extra == 'dev'
26
+ Requires-Dist: coverage>=7.8.0; extra == 'dev'
27
+ Requires-Dist: hatch>=1.14.1; extra == 'dev'
28
+ Requires-Dist: mkdocs-material>=9.6.12; extra == 'dev'
29
+ Requires-Dist: pre-commit>=4.2.0; extra == 'dev'
30
+ Requires-Dist: pylint>=3.3.6; extra == 'dev'
31
+ Requires-Dist: pyright>=1.1.400; extra == 'dev'
32
+ Requires-Dist: ruff>=0.11.7; extra == 'dev'
33
+ Requires-Dist: textual-dev>=1.7.0; extra == 'dev'
34
+ Requires-Dist: ty>=0.0.1a6; extra == 'dev'
35
+ Description-Content-Type: text/markdown
34
36
 
35
37
  # 🧙‍♂️ Sourcerer
36
38
 
37
39
  **Sourcerer** is a CLI-based cloud storage explorer that provides a unified interface for developers and DevOps
38
40
  engineers to view and manage files across multiple cloud providers like
39
- **GCP**, **AWS S3**, and **S3-compatible services**.
41
+ **GCP Storage**, **Azure Storage**, **AWS S3**, and **S3-compatible services**.
40
42
 
41
43
  > Your terminal. Your storages. Your control.
42
44
 
@@ -44,7 +46,7 @@ engineers to view and manage files across multiple cloud providers like
44
46
 
45
47
  ## ✨ Features
46
48
 
47
- - 🔍 Unified file browser for GCP, AWS S3, and S3-compatible services
49
+ - 🔍 Unified file browser for GCP Storage, Azure Storage, AWS S3, and S3-compatible services
48
50
  - 🧭 Terminal UI (TUI) built with [Textual](https://github.com/Textualize/textual)
49
51
  - 🗂️ Explore buckets and objects seamlessly
50
52
  - 🔄 Upload, download, and delete files
@@ -1,32 +1,31 @@
1
- data_sourcerer-0.2.0.dist-info/licenses/LICENSE,sha256=HjZ7RAG3i6izxvitGfY4feHfvW5F8DPj5eF0YBSf2rI,1073
2
- sourcerer/__init__.py,sha256=EjDDEplny6MYdZdi-SpLg0b_I4GZ0Q12MTHkE_4f2ag,585
1
+ sourcerer/__init__.py,sha256=f2b6aEvKKCf2QDu8Xfc-8stC78nN3qQFeO-Pj7r1ITM,585
3
2
  sourcerer/settings.py,sha256=dwY2GoaWD1CsAoVtWzaAhP7_e3KUugmBr2E624JSedc,1388
4
- sourcerer/utils.py,sha256=1VzKResV28-BlNlvEQ694WcxOZCK-NBR9uTbopl_slE,872
3
+ sourcerer/utils.py,sha256=4jAlcofepAQMcD1cYDsC1ryGwBLxE9m7ckPS6CzDsCI,879
5
4
  sourcerer/domain/__init__.py,sha256=rV21d-dD-e0q4EQ2LfWDSDLlrUOjnHnWBtWPujoue0o,556
6
5
  sourcerer/domain/access_credentials/__init__.py,sha256=pFAwnr74uy09e7kubYsuaqzkVPkTA66dwjKzpIGQkAY,217
7
- sourcerer/domain/access_credentials/entities.py,sha256=UVjNbxTuXyaywG7RxxTADe67wRB8xlo3GO0bnij1Srs,2030
6
+ sourcerer/domain/access_credentials/entities.py,sha256=u_pZMTncYorVYFNZOnJHn8qnsTWpbFyl7rEOaVrFjxQ,2020
8
7
  sourcerer/domain/access_credentials/exceptions.py,sha256=jo3vhGpIaEsDl68uV8JLDqPvfVZMi7H6MA0qsRL0QXQ,546
9
- sourcerer/domain/access_credentials/repositories.py,sha256=KVD9P_-wYelt2_40Vyh-G6uyrNjtbDyKmD9gO8EiStY,2408
10
- sourcerer/domain/access_credentials/services.py,sha256=MHTcz2OajQbQypbL082gXA7kqs4klCBUdKlguhWpLgQ,2791
8
+ sourcerer/domain/access_credentials/repositories.py,sha256=fTSCBUqSwgZnY0NVxCIwDLjyvylOBk3xSUBJ5Sr8FKA,2720
9
+ sourcerer/domain/access_credentials/services.py,sha256=HtTOBrDyh8Wz-dxYtcohPYu0qWxgnvzafGiXOXRu6Ww,2821
11
10
  sourcerer/domain/file_system/__init__.py,sha256=5diScp5Q8Hw8e_4vqacVocQBw0KA7fPs_YERoNwSEzM,184
12
- sourcerer/domain/file_system/entities.py,sha256=5W2_I1lng8J2foSJN-FqNZPR6n151VntiD_vkssAqgQ,2069
11
+ sourcerer/domain/file_system/entities.py,sha256=IeTu5VYxmBQMH7AcKfW1Muk4wUmgZ769eWwNyqeWRpw,2060
13
12
  sourcerer/domain/file_system/exceptions.py,sha256=TairaMaLkSHgbiq3pImkmVZAACoVHy-1vQMl7Ox24cQ,509
14
13
  sourcerer/domain/file_system/services.py,sha256=kQeEM1Lt28UBVT9uG4M2iFDSxSvQdaJw4QzM9giUdjY,2208
15
14
  sourcerer/domain/shared/__init__.py,sha256=pkCn6PfBLIlYT5q4xWq3cNtOfbUrrePiH06TduLq6_o,148
16
15
  sourcerer/domain/shared/entities.py,sha256=jJR1PhJBWrSeJyEFvauEYJ1UXG7BcT6pi2oFpmglu4I,497
17
16
  sourcerer/domain/storage_provider/__init__.py,sha256=P3RUH9LFkWez3ehCczgVbnbp0tZZepPeOQf9spsC8FQ,192
18
- sourcerer/domain/storage_provider/entities.py,sha256=08ueb1KXHfU_nyeY6GnQJ0-JxJEEW-WxKlIMWYY0T4A,1946
17
+ sourcerer/domain/storage_provider/entities.py,sha256=EgHkVFizMzzpzN161DlmWKPV9QhoRo8X7iiLtcN3_Wk,1931
19
18
  sourcerer/domain/storage_provider/exceptions.py,sha256=6xK5r62Bhedx3vV0_i7Eu5ZG5IExxeiuaGHG5sX17i4,508
20
19
  sourcerer/domain/storage_provider/services.py,sha256=Zm6nrKqQJW-9ZaqTp9wQaQuwMeH6hkLJZCkhQ_sTRF0,3997
21
20
  sourcerer/infrastructure/__init__.py,sha256=HQoqA8S9Vx2dr1Eua86wu_YxwXyY6jqa4IfEoZJcXcQ,616
22
- sourcerer/infrastructure/utils.py,sha256=ZN8X2raaz_0mwYxz5gE9TgnuI8haSfYkuO_DadsAKgg,3000
21
+ sourcerer/infrastructure/utils.py,sha256=5ITzUIsraIVGRJOt9C5znDSu9TUYPBS9YTx9OsiOVzM,5135
23
22
  sourcerer/infrastructure/access_credentials/__init__.py,sha256=7BSXnI9n59_PuGxHjOra6PG82R_6JlrU4S1tsJx4WGM,249
24
23
  sourcerer/infrastructure/access_credentials/exceptions.py,sha256=usad48RTA7ub8AfnUs2EzbD-fiUwpmnRGjJluBjd3m4,1101
25
- sourcerer/infrastructure/access_credentials/registry.py,sha256=KNhjocRCb5yQ0BzETPGauBoqUx3xnpBdRfTHFW-QD4A,3432
26
- sourcerer/infrastructure/access_credentials/repositories.py,sha256=og5kAgUlNNGbCQYCMTJ7DE1GotmqLc7owpnXIfOSnng,3839
27
- sourcerer/infrastructure/access_credentials/services.py,sha256=Hbzubm1oN5-sVunzcRb11F31GpWGiiCyFNvMSy2fzEk,15628
24
+ sourcerer/infrastructure/access_credentials/registry.py,sha256=YEjkbh5639j8LkAocozC8O_7t1pPcrJwbL1LCJhiGkY,3416
25
+ sourcerer/infrastructure/access_credentials/repositories.py,sha256=1Yf2ByKed8Z6WXcjbnHjC9dyw-PV0KE62JVO5SDaOMU,4393
26
+ sourcerer/infrastructure/access_credentials/services.py,sha256=YUbltxfreMMJRr-ERnbsRqdABrx8zb5bSRUEI8vdk60,16086
28
27
  sourcerer/infrastructure/db/__init__.py,sha256=sjx2F0aDnxej7-FAjhFJYIQQ5d2apmItkquKbvGYIBc,175
29
- sourcerer/infrastructure/db/config.py,sha256=VUh4S4bEh9GSx3ZDfQTI-ZGdkWNs_KdO9zDjRCGDjPQ,1808
28
+ sourcerer/infrastructure/db/config.py,sha256=c3ubAxBWt-zDUwTe3pAgJ86-rw-LZZAZppuBRo93Xn8,1792
30
29
  sourcerer/infrastructure/db/models.py,sha256=U7Ocdup4KHyCRGvTTxHY2kF1FES3oaU2-hT7vU8pFIw,1743
31
30
  sourcerer/infrastructure/file_system/__init__.py,sha256=Swx8arwXeZ4E40ViDSpQglmUrIlpuEvZY6crcWpGC2g,219
32
31
  sourcerer/infrastructure/file_system/exceptions.py,sha256=obx0NxVuhVzLgL5K2MA5d4rNImlRHJ4Gr-2RrIuKJqk,2944
@@ -35,7 +34,7 @@ sourcerer/infrastructure/storage_provider/__init__.py,sha256=GONjDCsTmd6f_fF3lzx
35
34
  sourcerer/infrastructure/storage_provider/exceptions.py,sha256=acx3IIXD2yWlzLvD2asJBEpKEa6eJW31uKkzzr8MrR4,3336
36
35
  sourcerer/infrastructure/storage_provider/registry.py,sha256=8dbRLOx1jLK_i18uuh_JnKvId9NJBECKg4nG9F_dFH4,2249
37
36
  sourcerer/infrastructure/storage_provider/services/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
38
- sourcerer/infrastructure/storage_provider/services/azure.py,sha256=u5yr1xFZwhqSCXcaQMygpOVhuNSabqLBZ_MpB8tmWV4,9785
37
+ sourcerer/infrastructure/storage_provider/services/azure.py,sha256=A7k8Zs6rK5nBsUr5ZNBzkDQWRxpU0qnfWAcrz3eZzAk,9796
39
38
  sourcerer/infrastructure/storage_provider/services/gcp.py,sha256=_iVNf8OESVynGHKt68ZmudQtS6qU-UWZMhFa3v0Sm7Y,9102
40
39
  sourcerer/infrastructure/storage_provider/services/s3.py,sha256=lSpf5SPyTZGl19ChgYBtf3IR6uUWULuAvLBEdD-oarM,9277
41
40
  sourcerer/presentation/__init__.py,sha256=kzOeaTpy9hm61MLl_nybdooRrawFUd1uEX4f3Y-84ZU,472
@@ -45,19 +44,20 @@ sourcerer/presentation/settings.py,sha256=OcNrvwqHwAq3ZqWOfEmZ0PqyvQpAY1fmBpMc9l
45
44
  sourcerer/presentation/utils.py,sha256=aM5eCNEmIzCyfg8Egb2rFfOlXQ5pFTXzbRVwQGSOdjY,2638
46
45
  sourcerer/presentation/screens/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
47
46
  sourcerer/presentation/screens/critical_error/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
- sourcerer/presentation/screens/critical_error/main.py,sha256=DEYFNBqm-KE-TB09aJHMGBA0SVeFaOy4Zd9q3rcBpb4,2224
47
+ sourcerer/presentation/screens/critical_error/main.py,sha256=10Ip1InBzktwwM2ijKXBOkhvBXGorw1X8EGxdh75WZE,2208
49
48
  sourcerer/presentation/screens/critical_error/styles.tcss,sha256=mURvbf0_npkRtzVBs2bVBybbyNK9cO_6Ar2Muk1Mpv8,604
50
- sourcerer/presentation/screens/file_system_finder/main.py,sha256=DnzAz--JcfRxeBzNLk0qA9EuTkSK26IbIkMErV2t1nE,10121
49
+ sourcerer/presentation/screens/file_system_finder/main.py,sha256=Zxn0bLlHyFNAqkYDrFwrIH9XABY2xKsraGAYgmkYFPc,10241
51
50
  sourcerer/presentation/screens/file_system_finder/styles.tcss,sha256=fZkdwXFsDkjXkaIskLxoQ_YHsLWKjgrn6hYseugg_68,718
52
51
  sourcerer/presentation/screens/file_system_finder/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
- sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py,sha256=Le_76mA12dN8UhWddJexnb3Qqm-f4kqQdAaiyvIfxYQ,30878
52
+ sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py,sha256=EHPsVWyq0Lmkv1Jt3m4OgpJvI1nsye2Os1XA0XAZz8M,30884
54
53
  sourcerer/presentation/screens/main/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
55
- sourcerer/presentation/screens/main/main.py,sha256=OOczA6lem6JSdJCq-Nd2TtXmFA1R-xeVdqbM7I5QHTM,20440
54
+ sourcerer/presentation/screens/main/main.py,sha256=FhG0_uev8W5bfrP-F5pBVst_ZnSyim6aM7G4nL9yYfQ,21354
56
55
  sourcerer/presentation/screens/main/styles.tcss,sha256=Ruv2vBKzM8njH7OS2TCpZqCmRVEp7XQLeBN4XhVB5AU,381
57
56
  sourcerer/presentation/screens/main/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
58
57
  sourcerer/presentation/screens/main/messages/delete_request.py,sha256=puaU1UtbDErfYi8ViPEawhSbycnUpwdE81zZfzlslNE,203
59
58
  sourcerer/presentation/screens/main/messages/download_request.py,sha256=3urSTrvNbod1FrXfu-C1UDZqOu5D0OC-NJsKJhhprXE,205
60
59
  sourcerer/presentation/screens/main/messages/preview_request.py,sha256=px8N3E2VEexKmpZESb9nYDQvhXUThPxM0dU41B533tM,184
60
+ sourcerer/presentation/screens/main/messages/refresh_storages_list_request.py,sha256=NxOBcUf5oKF1cMCcHZny8qG2Jv6zTdPmYeFV9qORHh8,136
61
61
  sourcerer/presentation/screens/main/messages/resizing_rule.py,sha256=ws7lzS08h6qqeihF66XV5FsX26YkjQOje_4vgCw2mqI,332
62
62
  sourcerer/presentation/screens/main/messages/select_storage_item.py,sha256=xBu0UH5A6iyZPJECt_f_vfWVaCmE0bJo5hq2FJXMHQo,237
63
63
  sourcerer/presentation/screens/main/messages/uncheck_files_request.py,sha256=CMpYVwos1JHknqDcqru1hG8RJy5f1Lwjsxtrse1ZDGw,140
@@ -65,34 +65,37 @@ sourcerer/presentation/screens/main/messages/upload_request.py,sha256=KXPTliqdvR
65
65
  sourcerer/presentation/screens/main/mixins/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  sourcerer/presentation/screens/main/mixins/resize_containers_watcher_mixin.py,sha256=wZnTbJHjHDJbKFkfbyT0CR3GWlVupyiSotgnumBiEoI,5647
67
67
  sourcerer/presentation/screens/main/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- sourcerer/presentation/screens/main/widgets/gradient.py,sha256=LThG7XSIUhJeXnONgArWuabosv9UiGHoHd95jKrT6rk,1226
69
- sourcerer/presentation/screens/main/widgets/resizing_rule.py,sha256=-SIqnXtQNM80t73nsyUx02bz8I6dAHJiSxWL0Aki2Bo,2040
70
- sourcerer/presentation/screens/main/widgets/storage_content.py,sha256=fXHBfrZ5db7rzF4MfDwUDO8cQSeyVa73smJFw-qzaj0,21863
71
- sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py,sha256=CFzNpnhEJ0TZHOVxaVGl2AsvYcRF3VvNhKAbD0KGuCg,4670
68
+ sourcerer/presentation/screens/main/widgets/gradient.py,sha256=Ow6oaX0tsFNbUKRh_e9ITph20_tKoQgqzM7rujwKmxs,1263
69
+ sourcerer/presentation/screens/main/widgets/resizing_rule.py,sha256=W4tAbSZlmAIytP1BNlSvBeiMGA7cD6l13IpxG2JYzxk,2088
70
+ sourcerer/presentation/screens/main/widgets/storage_content.py,sha256=1bhIhHH8KMgsOIf2bX4F6AzSEWvLu1ccOigmvSagwa8,22516
71
+ sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py,sha256=dz1Qdznc2hNt_MBB4j6kszx7cCpiaM9kM9_7LDwyPDc,5619
72
72
  sourcerer/presentation/screens/preview_content/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
- sourcerer/presentation/screens/preview_content/main.py,sha256=hvJpiHZD3fuT6qPauSgPIMj7uaUUVSUKp1KnmaSQr5E,2546
73
+ sourcerer/presentation/screens/preview_content/main.py,sha256=c7WEM3dCRHh0gnB2AXgl_upi8lfNwRfH1425736mya8,2498
74
74
  sourcerer/presentation/screens/preview_content/styles.tcss,sha256=Qk0nZtUfp-mCFaUXtkjwimAnshXnhEgh719aT4_lDPQ,374
75
75
  sourcerer/presentation/screens/provider_creds_list/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
76
- sourcerer/presentation/screens/provider_creds_list/main.py,sha256=gs35uG4mC0vWD_-TcQB3Wr6XnLyDFvtkPItj-qq_B9E,6203
77
- sourcerer/presentation/screens/provider_creds_list/styles.tcss,sha256=PmO_JKNR7NhYhT9CXLSZqh_q3rxFJ1HkSzVxOjJs_P8,904
76
+ sourcerer/presentation/screens/provider_creds_list/main.py,sha256=s3t9UaaOVHBiSQ5L-tduzxaJWdDgWqbJtIol1IlAv5s,7870
77
+ sourcerer/presentation/screens/provider_creds_list/styles.tcss,sha256=_BXTWQw_LjPjbAG-V4YxxOeHn4GFShVjc4K1by-uVR0,956
78
+ sourcerer/presentation/screens/provider_creds_list/messages/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
+ sourcerer/presentation/screens/provider_creds_list/messages/reload_credentials_request.py,sha256=zkyLFkXZHQMj5OsDU_IiInUnezHNWyvYn8yZLoJmJn0,134
78
80
  sourcerer/presentation/screens/provider_creds_registration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
79
- sourcerer/presentation/screens/provider_creds_registration/main.py,sha256=TUPw2E54-ALfEk2YSU7DpzuyJ24oDj3jHEfQQsH6n_g,11079
81
+ sourcerer/presentation/screens/provider_creds_registration/main.py,sha256=fBAi3xnH-QoRwq6dttuS_lqBMCe66RZND2M228IhngI,11182
80
82
  sourcerer/presentation/screens/provider_creds_registration/styles.tcss,sha256=gd1SNeRoHTYwNzdGxK-2aDqNPeY5b2wFWajtoNn5--Y,612
81
83
  sourcerer/presentation/screens/question/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- sourcerer/presentation/screens/question/main.py,sha256=XftOcA6gDpK1Tc9WqE_jK5q0CLNvZuVuW88hp4X_kZM,901
83
- sourcerer/presentation/screens/question/styles.tcss,sha256=fJl0Votob2sfRQP4s8Oqd5P2OQ0WiGMdoLpTsMgISfw,418
84
+ sourcerer/presentation/screens/question/main.py,sha256=7ogFbKrqP9deBYfgq7Bs6NkiSdy3whEu51mW_--TCIY,980
85
+ sourcerer/presentation/screens/question/styles.tcss,sha256=NT8Ty4opqYLG1-sal3m1us4M4LNhtTcQywlU-Al-v7o,396
84
86
  sourcerer/presentation/screens/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
85
87
  sourcerer/presentation/screens/shared/containers.py,sha256=9Tkl5SbPNgycZlfp5Pq50pHnJqbP0EckmxayXPPuhFs,378
86
88
  sourcerer/presentation/screens/shared/widgets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
- sourcerer/presentation/screens/shared/widgets/button.py,sha256=MpzxKZ7KGe5g4aNkNnFN6novnXv1au3WdgsVN-ITOns,1558
88
- sourcerer/presentation/screens/shared/widgets/labeled_input.py,sha256=H_v62jpcZD0iuaKlTtKvOy_0GKCugibR7n6weGK-Upk,2750
89
+ sourcerer/presentation/screens/shared/widgets/button.py,sha256=aGsJTwK04nTXarafkl8TgdeB9EGfRwn4gffoPvFFwiU,1580
90
+ sourcerer/presentation/screens/shared/widgets/labeled_input.py,sha256=5sFsuZRd6E9kfG2zjSH9oE_VgXA7sp5XJxg73jPdwGw,2801
91
+ sourcerer/presentation/screens/shared/widgets/loader.py,sha256=_sRFM9I_KhiqPyUCN_hX7IP1AlxtrUNn5QBXi5hmdtU,737
89
92
  sourcerer/presentation/screens/storage_action_progress/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
- sourcerer/presentation/screens/storage_action_progress/main.py,sha256=F33lL4NEqrw8B_xORSoQWVdUCldFTPPdqUsn2_YgEKM,17973
93
+ sourcerer/presentation/screens/storage_action_progress/main.py,sha256=d2p6YYU3N1FBuKy0oNqqbkUTiFhoH260-jDt2Rqzlng,17998
91
94
  sourcerer/presentation/screens/storage_action_progress/styles.tcss,sha256=ffvDxRWhckE5tjEG4jwlhQNqeQsYpdF71104StWCGWU,818
92
95
  sourcerer/presentation/themes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
93
96
  sourcerer/presentation/themes/github_dark.py,sha256=9E1mEOr701nU-ZDSKBccMl3GYchroCEsxEVelm5oI-E,497
94
- data_sourcerer-0.2.0.dist-info/METADATA,sha256=ZbbpumnqYrw9JDSlgRQN8fYY5Yn55rlPO4QtEB1gRBU,2388
95
- data_sourcerer-0.2.0.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
96
- data_sourcerer-0.2.0.dist-info/entry_points.txt,sha256=CyD02GehPW6QuhR5oDY5tLLRHQ9qbPXe0v3aT1pK3N8,62
97
- data_sourcerer-0.2.0.dist-info/top_level.txt,sha256=_9Nul_xiROuGIUDltaPqy-HyRzvv80MF_uquhggP9So,10
98
- data_sourcerer-0.2.0.dist-info/RECORD,,
97
+ data_sourcerer-0.2.2.dist-info/METADATA,sha256=FX2OTYOD6iPhiFmYJGhDP0oI1X3YKK8xWszaJEC-QU8,2535
98
+ data_sourcerer-0.2.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
99
+ data_sourcerer-0.2.2.dist-info/entry_points.txt,sha256=CyD02GehPW6QuhR5oDY5tLLRHQ9qbPXe0v3aT1pK3N8,62
100
+ data_sourcerer-0.2.2.dist-info/licenses/LICENSE,sha256=HjZ7RAG3i6izxvitGfY4feHfvW5F8DPj5eF0YBSf2rI,1073
101
+ data_sourcerer-0.2.2.dist-info/RECORD,,
@@ -1,5 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.8.0)
2
+ Generator: hatchling 1.27.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
-
sourcerer/__init__.py CHANGED
@@ -12,4 +12,4 @@ The application is structured using a clean architecture approach with:
12
12
  - Presentation layer: User interface components
13
13
  """
14
14
 
15
- __version__ = "0.2.0"
15
+ __version__ = "0.2.2"
@@ -5,15 +5,14 @@ This module defines data classes representing access credentials
5
5
  used for authentication with various cloud providers.
6
6
  """
7
7
 
8
- from dataclasses import dataclass
9
8
  from datetime import datetime
10
9
 
11
10
  import boto3
12
11
  from azure.identity import ClientSecretCredential
12
+ from msgspec._core import Struct
13
13
 
14
14
 
15
- @dataclass
16
- class Credentials:
15
+ class Credentials(Struct):
17
16
  """
18
17
  Represents access credentials for a provider.
19
18
 
@@ -38,8 +37,7 @@ class Credentials:
38
37
  updated_at: datetime | None = None
39
38
 
40
39
 
41
- @dataclass
42
- class Boto3Credentials:
40
+ class Boto3Credentials(Struct):
43
41
  """
44
42
  Represents AWS credentials using boto3 session.
45
43
 
@@ -54,8 +52,7 @@ class Boto3Credentials:
54
52
  signature_version: str | None = None
55
53
 
56
54
 
57
- @dataclass
58
- class AzureCredentials:
55
+ class AzureCredentials(Struct):
59
56
  """
60
57
  Represents Azure credentials.
61
58
 
@@ -28,6 +28,18 @@ class BaseCredentialsRepository(metaclass=ABCMeta):
28
28
  """
29
29
  raise NotImplementedError
30
30
 
31
+ @abstractmethod
32
+ def delete(self, uuid):
33
+ """Delete credentials by UUID.
34
+
35
+ Args:
36
+ uuid: Unique identifier for the credentials to delete
37
+
38
+ Raises:
39
+ NotImplementedError: Method must be implemented by concrete classes
40
+ """
41
+ raise NotImplementedError
42
+
31
43
  @abstractmethod
32
44
  def get(self, uuid):
33
45
  """Retrieve credentials by UUID.
@@ -8,6 +8,7 @@ authentication methods.
8
8
 
9
9
  from abc import abstractmethod
10
10
  from dataclasses import dataclass
11
+ from typing import Any
11
12
 
12
13
  from sourcerer.domain.access_credentials.repositories import BaseCredentialsRepository
13
14
 
@@ -71,7 +72,7 @@ class BaseAccessCredentialsService:
71
72
  """
72
73
 
73
74
  @abstractmethod
74
- def authenticate(self, credentials: str):
75
+ def authenticate(self, credentials: str) -> Any:
75
76
  """
76
77
  Authenticate using stored credentials.
77
78
 
@@ -5,12 +5,12 @@ This module defines data classes representing file system entities and
5
5
  operation results used throughout the application.
6
6
  """
7
7
 
8
- from dataclasses import dataclass
9
8
  from pathlib import Path
10
9
 
10
+ from msgspec._core import Struct
11
11
 
12
- @dataclass
13
- class SearchResult:
12
+
13
+ class SearchResult(Struct):
14
14
  """
15
15
  Represents the result of a search operation.
16
16
 
@@ -30,8 +30,7 @@ class SearchResult:
30
30
  line: int
31
31
 
32
32
 
33
- @dataclass
34
- class SearchResultOutput:
33
+ class SearchResultOutput(Struct):
35
34
  """
36
35
  Represents the output of a search operation.
37
36
 
@@ -51,8 +50,7 @@ class SearchResultOutput:
51
50
  total: int
52
51
 
53
52
 
54
- @dataclass
55
- class ListDirOutput:
53
+ class ListDirOutput(Struct):
56
54
  """
57
55
  Represents the output of a list directory operation.
58
56
 
@@ -5,12 +5,12 @@ This module defines data classes representing cloud storage entities
5
5
  such as storage containers, files, folders, and permissions.
6
6
  """
7
7
 
8
- from dataclasses import dataclass
9
8
  from datetime import datetime
10
9
 
10
+ from msgspec._core import Struct
11
11
 
12
- @dataclass
13
- class Storage:
12
+
13
+ class Storage(Struct):
14
14
  """
15
15
  Represents a cloud storage container (bucket/container).
16
16
 
@@ -25,8 +25,7 @@ class Storage:
25
25
  date_created: datetime
26
26
 
27
27
 
28
- @dataclass
29
- class StoragePermissions:
28
+ class StoragePermissions(Struct):
30
29
  """
31
30
  Represents permissions for a user on a storage resource.
32
31
 
@@ -39,8 +38,7 @@ class StoragePermissions:
39
38
  permissions: list[str]
40
39
 
41
40
 
42
- @dataclass
43
- class Folder:
41
+ class Folder(Struct):
44
42
  """
45
43
  Represents a folder/directory within a storage container.
46
44
 
@@ -51,8 +49,7 @@ class Folder:
51
49
  key: str
52
50
 
53
51
 
54
- @dataclass
55
- class File:
52
+ class File(Struct):
56
53
  """
57
54
  Represents a file within a storage container.
58
55
 
@@ -71,8 +68,7 @@ class File:
71
68
  date_modified: datetime | None = None
72
69
 
73
70
 
74
- @dataclass
75
- class StorageContent:
71
+ class StorageContent(Struct):
76
72
  """
77
73
  Represents the contents of a storage location, including files and folders.
78
74
 
@@ -37,7 +37,7 @@ class AccessCredentialsRegistry(metaclass=Singleton):
37
37
  def __init__(self, *args, **kwargs):
38
38
  """Initialize the registry with an empty dictionary."""
39
39
  super().__init__(*args, **kwargs)
40
- self._items_: dict[str, dict[str, type]] = {} # type: ignore
40
+ self._items_: dict[str, dict[str, type]] = {}
41
41
 
42
42
  def register(
43
43
  self,
@@ -46,6 +46,23 @@ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
46
46
  session.add(credentials)
47
47
  session.commit()
48
48
 
49
+ def delete(self, uuid: str):
50
+ """
51
+ Delete credentials from the database by UUID.
52
+
53
+ Args:
54
+ uuid (str): Unique identifier for the credentials to delete
55
+ """
56
+ with self.db() as session:
57
+ credentials = (
58
+ session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
59
+ )
60
+ if credentials is None:
61
+ # No matching credentials found; return early
62
+ return
63
+ session.delete(credentials)
64
+ session.commit()
65
+
49
66
  def get(self, uuid: str):
50
67
  """
51
68
  Retrieve credentials by UUID.
@@ -71,6 +71,15 @@ class CredentialsService:
71
71
  """
72
72
  return self.credentials_repo.list(active_only)
73
73
 
74
+ def delete(self, uuid):
75
+ """
76
+ Delete credentials by UUID.
77
+
78
+ Args:
79
+ uuid (str): Unique identifier for the credentials to delete
80
+ """
81
+ return self.credentials_repo.delete(uuid)
82
+
74
83
  def get(self, uuid):
75
84
  """
76
85
  Get credentials by UUID.
@@ -190,7 +199,7 @@ class S3AccessKeySecretKeyPair(S3AccessCredentialsService):
190
199
  """
191
200
  return self.credentials_repo.get(uuid)
192
201
 
193
- def authenticate(self, credentials: str): # type: ignore
202
+ def authenticate(self, credentials: str):
194
203
  """
195
204
  Authenticate using stored credentials.
196
205
 
@@ -201,22 +210,27 @@ class S3AccessKeySecretKeyPair(S3AccessCredentialsService):
201
210
  boto3.Session: Authenticated boto3 session
202
211
  """
203
212
  try:
204
- credentials: dict = json.loads(credentials)
213
+ credentials_dict: dict = json.loads(credentials)
214
+
215
+ access_key_id = credentials_dict.get("aws_access_key_id")
216
+ secret_access_key = credentials_dict.get("aws_secret_access_key")
217
+ endpoint_url = credentials_dict.get("endpoint_url")
218
+ signature_version = credentials_dict.get("signature_version")
205
219
 
206
220
  session_args = {
207
- "aws_access_key_id": credentials.get("aws_access_key_id"),
208
- "aws_secret_access_key": credentials.get("aws_secret_access_key"),
221
+ "aws_access_key_id": access_key_id,
222
+ "aws_secret_access_key": secret_access_key,
209
223
  }
210
224
 
211
- if region := credentials.get("region"):
225
+ if region := credentials_dict.get("region"):
212
226
  session_args["region_name"] = region
213
227
 
214
228
  session = boto3.Session(**session_args)
215
229
 
216
230
  return Boto3Credentials(
217
231
  session=session,
218
- endpoint_url=credentials.get("endpoint_url", None),
219
- signature_version=credentials.get("signature_version", None),
232
+ endpoint_url=endpoint_url,
233
+ signature_version=signature_version,
220
234
  )
221
235
  except Exception as e:
222
236
  raise CredentialsAuthError("Failed to authenticate") from e
@@ -277,7 +291,7 @@ class S3ProfileName(S3AccessCredentialsService):
277
291
  """
278
292
  return self.credentials_repo.get(uuid)
279
293
 
280
- def authenticate(self, credentials: str): # type: ignore
294
+ def authenticate(self, credentials: str):
281
295
  """
282
296
  Authenticate using stored profile name.
283
297
 
@@ -288,11 +302,14 @@ class S3ProfileName(S3AccessCredentialsService):
288
302
  boto3.Session: Authenticated boto3 session
289
303
  """
290
304
  try:
291
- credentials: dict = json.loads(credentials)
292
- session = boto3.Session(profile_name=credentials.get("profile_name"))
305
+ credentials_dict: dict = json.loads(credentials)
306
+ profile_name = credentials_dict.get("profile_name")
307
+ endpoint_url = credentials_dict.get("endpoint_url")
308
+
309
+ session = boto3.Session(profile_name=profile_name)
293
310
  return Boto3Credentials(
294
311
  session=session,
295
- endpoint_url=credentials.get("endpoint_url"),
312
+ endpoint_url=endpoint_url,
296
313
  )
297
314
  except Exception as e:
298
315
  raise CredentialsAuthError("Failed to authenticate") from e
@@ -353,7 +370,7 @@ class GCPCredentialsService(AccessCredentialsService):
353
370
  """
354
371
  return self.credentials_repo.get(uuid)
355
372
 
356
- def authenticate(self, credentials: str): # type: ignore
373
+ def authenticate(self, credentials: str):
357
374
  """
358
375
  Authenticate with Google Cloud Platform using service account credentials.
359
376
 
@@ -414,7 +431,6 @@ class GCPCredentialsService(AccessCredentialsService):
414
431
  AccessCredentialsMethod(StorageProvider.AzureStorage, "Client Secret Credentials")
415
432
  )
416
433
  class AzureClientSecretCredentialsService(AccessCredentialsService):
417
-
418
434
  def store(self, name, credentials: dict):
419
435
  """
420
436
  Store Azure client_id and secret_key_pair credentials.
@@ -446,7 +462,7 @@ class AzureClientSecretCredentialsService(AccessCredentialsService):
446
462
  """
447
463
  return self.credentials_repo.get(uuid)
448
464
 
449
- def authenticate(self, credentials: str): # type: ignore
465
+ def authenticate(self, credentials: str):
450
466
  try:
451
467
  # Parse the outer JSON structure
452
468
  parsed_credentials = json.loads(credentials)
@@ -30,7 +30,7 @@ class Database:
30
30
  """
31
31
  self.db_url = db_url
32
32
  self.engine = sqlalchemy.create_engine(db_url)
33
- self.scoped_session = scoped_session(sessionmaker(bind=self.engine)) # type: ignore
33
+ self.scoped_session = scoped_session(sessionmaker(bind=self.engine))
34
34
 
35
35
  def prepare_db(self):
36
36
  """
@@ -91,7 +91,7 @@ class AzureStorageProviderService(BaseStorageProviderService):
91
91
  try:
92
92
  accounts_client = self.get_accounts_client()
93
93
  return [
94
- Storage(StorageProvider.AzureStorage, i.name, i.creation_time) # type: ignore
94
+ Storage(StorageProvider.AzureStorage, i.name, i.creation_time)
95
95
  for i in accounts_client.storage_accounts.list()
96
96
  ]
97
97
  except Exception as ex:
@@ -198,9 +198,11 @@ class AzureStorageProviderService(BaseStorageProviderService):
198
198
  """
199
199
  try:
200
200
  if not storage_path:
201
- raise AzureMissingContainerError("Container is required for Azure storage")
201
+ raise AzureMissingContainerError(
202
+ "Container is required for Azure storage"
203
+ )
202
204
 
203
- containers_client = self.get_containers_client(storage)
205
+ containers_client = self.get_containers_client(storage)
204
206
 
205
207
  storage_path_parts = storage_path.split("/", 1)
206
208