data-sourcerer 0.1.0__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 (95) hide show
  1. data_sourcerer-0.1.0.dist-info/METADATA +52 -0
  2. data_sourcerer-0.1.0.dist-info/RECORD +95 -0
  3. data_sourcerer-0.1.0.dist-info/WHEEL +5 -0
  4. data_sourcerer-0.1.0.dist-info/entry_points.txt +2 -0
  5. data_sourcerer-0.1.0.dist-info/licenses/LICENSE +21 -0
  6. data_sourcerer-0.1.0.dist-info/top_level.txt +1 -0
  7. sourcerer/__init__.py +15 -0
  8. sourcerer/domain/__init__.py +13 -0
  9. sourcerer/domain/access_credentials/__init__.py +7 -0
  10. sourcerer/domain/access_credentials/entities.py +53 -0
  11. sourcerer/domain/access_credentials/exceptions.py +17 -0
  12. sourcerer/domain/access_credentials/repositories.py +84 -0
  13. sourcerer/domain/access_credentials/services.py +91 -0
  14. sourcerer/domain/file_system/__init__.py +7 -0
  15. sourcerer/domain/file_system/entities.py +70 -0
  16. sourcerer/domain/file_system/exceptions.py +17 -0
  17. sourcerer/domain/file_system/services.py +64 -0
  18. sourcerer/domain/shared/__init__.py +6 -0
  19. sourcerer/domain/shared/entities.py +18 -0
  20. sourcerer/domain/storage_provider/__init__.py +7 -0
  21. sourcerer/domain/storage_provider/entities.py +86 -0
  22. sourcerer/domain/storage_provider/exceptions.py +17 -0
  23. sourcerer/domain/storage_provider/services.py +130 -0
  24. sourcerer/infrastructure/__init__.py +13 -0
  25. sourcerer/infrastructure/access_credentials/__init__.py +7 -0
  26. sourcerer/infrastructure/access_credentials/exceptions.py +16 -0
  27. sourcerer/infrastructure/access_credentials/registry.py +120 -0
  28. sourcerer/infrastructure/access_credentials/repositories.py +119 -0
  29. sourcerer/infrastructure/access_credentials/services.py +396 -0
  30. sourcerer/infrastructure/db/__init__.py +6 -0
  31. sourcerer/infrastructure/db/config.py +73 -0
  32. sourcerer/infrastructure/db/models.py +47 -0
  33. sourcerer/infrastructure/file_system/__init__.py +7 -0
  34. sourcerer/infrastructure/file_system/exceptions.py +89 -0
  35. sourcerer/infrastructure/file_system/services.py +147 -0
  36. sourcerer/infrastructure/storage_provider/__init__.py +7 -0
  37. sourcerer/infrastructure/storage_provider/exceptions.py +78 -0
  38. sourcerer/infrastructure/storage_provider/registry.py +84 -0
  39. sourcerer/infrastructure/storage_provider/services.py +509 -0
  40. sourcerer/infrastructure/utils.py +106 -0
  41. sourcerer/presentation/__init__.py +12 -0
  42. sourcerer/presentation/app.py +36 -0
  43. sourcerer/presentation/di_container.py +46 -0
  44. sourcerer/presentation/screens/__init__.py +0 -0
  45. sourcerer/presentation/screens/critical_error/__init__.py +0 -0
  46. sourcerer/presentation/screens/critical_error/main.py +78 -0
  47. sourcerer/presentation/screens/critical_error/styles.tcss +41 -0
  48. sourcerer/presentation/screens/file_system_finder/main.py +248 -0
  49. sourcerer/presentation/screens/file_system_finder/styles.tcss +44 -0
  50. sourcerer/presentation/screens/file_system_finder/widgets/__init__.py +0 -0
  51. sourcerer/presentation/screens/file_system_finder/widgets/file_system_navigator.py +810 -0
  52. sourcerer/presentation/screens/main/__init__.py +0 -0
  53. sourcerer/presentation/screens/main/main.py +469 -0
  54. sourcerer/presentation/screens/main/messages/__init__.py +0 -0
  55. sourcerer/presentation/screens/main/messages/delete_request.py +12 -0
  56. sourcerer/presentation/screens/main/messages/download_request.py +12 -0
  57. sourcerer/presentation/screens/main/messages/preview_request.py +10 -0
  58. sourcerer/presentation/screens/main/messages/resizing_rule.py +21 -0
  59. sourcerer/presentation/screens/main/messages/select_storage_item.py +11 -0
  60. sourcerer/presentation/screens/main/messages/uncheck_files_request.py +8 -0
  61. sourcerer/presentation/screens/main/messages/upload_request.py +10 -0
  62. sourcerer/presentation/screens/main/mixins/__init__.py +0 -0
  63. sourcerer/presentation/screens/main/mixins/resize_containers_watcher_mixin.py +144 -0
  64. sourcerer/presentation/screens/main/styles.tcss +32 -0
  65. sourcerer/presentation/screens/main/widgets/__init__.py +0 -0
  66. sourcerer/presentation/screens/main/widgets/gradient.py +45 -0
  67. sourcerer/presentation/screens/main/widgets/resizing_rule.py +67 -0
  68. sourcerer/presentation/screens/main/widgets/storage_content.py +691 -0
  69. sourcerer/presentation/screens/main/widgets/storage_list_sidebar.py +143 -0
  70. sourcerer/presentation/screens/preview_content/__init__.py +0 -0
  71. sourcerer/presentation/screens/preview_content/main.py +59 -0
  72. sourcerer/presentation/screens/preview_content/styles.tcss +26 -0
  73. sourcerer/presentation/screens/provider_creds_list/__init__.py +0 -0
  74. sourcerer/presentation/screens/provider_creds_list/main.py +164 -0
  75. sourcerer/presentation/screens/provider_creds_list/styles.tcss +65 -0
  76. sourcerer/presentation/screens/provider_creds_registration/__init__.py +0 -0
  77. sourcerer/presentation/screens/provider_creds_registration/main.py +264 -0
  78. sourcerer/presentation/screens/provider_creds_registration/styles.tcss +42 -0
  79. sourcerer/presentation/screens/question/__init__.py +0 -0
  80. sourcerer/presentation/screens/question/main.py +31 -0
  81. sourcerer/presentation/screens/question/styles.tcss +33 -0
  82. sourcerer/presentation/screens/shared/__init__.py +0 -0
  83. sourcerer/presentation/screens/shared/containers.py +13 -0
  84. sourcerer/presentation/screens/shared/widgets/__init__.py +0 -0
  85. sourcerer/presentation/screens/shared/widgets/button.py +54 -0
  86. sourcerer/presentation/screens/shared/widgets/labeled_input.py +80 -0
  87. sourcerer/presentation/screens/storage_action_progress/__init__.py +0 -0
  88. sourcerer/presentation/screens/storage_action_progress/main.py +476 -0
  89. sourcerer/presentation/screens/storage_action_progress/styles.tcss +43 -0
  90. sourcerer/presentation/settings.py +31 -0
  91. sourcerer/presentation/themes/__init__.py +0 -0
  92. sourcerer/presentation/themes/github_dark.py +21 -0
  93. sourcerer/presentation/utils.py +69 -0
  94. sourcerer/settings.py +72 -0
  95. sourcerer/utils.py +32 -0
@@ -0,0 +1,7 @@
1
+ """
2
+ Storage provider domain module.
3
+
4
+ This package defines the domain model for cloud storage providers,
5
+ including entities, services, and exceptions related to cloud storage
6
+ interactions.
7
+ """
@@ -0,0 +1,86 @@
1
+ """
2
+ Storage provider entity classes.
3
+
4
+ This module defines data classes representing cloud storage entities
5
+ such as storage containers, files, folders, and permissions.
6
+ """
7
+
8
+ from dataclasses import dataclass
9
+ from datetime import datetime
10
+ from typing import List
11
+
12
+
13
+ @dataclass
14
+ class Storage:
15
+ """
16
+ Represents a cloud storage container (bucket/container).
17
+
18
+ Attributes:
19
+ provider (str): The cloud provider identifier (e.g., 's3', 'gcp')
20
+ storage (str): The storage name/identifier (e.g., bucket name)
21
+ date_created (datetime): When the storage was created
22
+ """
23
+
24
+ provider: str
25
+ storage: str
26
+ date_created: datetime
27
+
28
+
29
+ @dataclass
30
+ class StoragePermissions:
31
+ """
32
+ Represents permissions for a user on a storage resource.
33
+
34
+ Attributes:
35
+ user (str): The user identifier or name
36
+ permissions (List[str]): List of permission strings granted to the user
37
+ """
38
+
39
+ user: str
40
+ permissions: List[str]
41
+
42
+
43
+ @dataclass
44
+ class Folder:
45
+ """
46
+ Represents a folder/directory within a storage container.
47
+
48
+ Attributes:
49
+ key (str): The path/key identifier for the folder
50
+ """
51
+
52
+ key: str
53
+
54
+
55
+ @dataclass
56
+ class File:
57
+ """
58
+ Represents a file within a storage container.
59
+
60
+ Attributes:
61
+ uuid (str): Unique identifier for the file
62
+ key (str): The path/key identifier for the file
63
+ size (str): Human-readable file size
64
+ is_text (bool): Whether the file is textual
65
+ date_modified (datetime | None): When the file was last modified, if available
66
+ """
67
+
68
+ uuid: str
69
+ key: str
70
+ size: str
71
+ is_text: bool
72
+ date_modified: datetime | None = None
73
+
74
+
75
+ @dataclass
76
+ class StorageContent:
77
+ """
78
+ Represents the contents of a storage location, including files and folders.
79
+
80
+ Attributes:
81
+ files (List[File]): List of files in the location
82
+ folders (List[Folder]): List of folders in the location
83
+ """
84
+
85
+ files: List[File]
86
+ folders: List[Folder]
@@ -0,0 +1,17 @@
1
+ """
2
+ Storage provider exception base class.
3
+
4
+ This module defines the base exception class for errors related to
5
+ cloud storage provider operations.
6
+ """
7
+
8
+
9
+ class BaseStorageProviderException(Exception):
10
+ """
11
+ Base exception class for cloud storage provider-related errors.
12
+
13
+ This class serves as the base for all exceptions that may occur
14
+ when interacting with cloud storage services. Specific exception
15
+ types should inherit from this class to maintain a consistent
16
+ exception hierarchy.
17
+ """
@@ -0,0 +1,130 @@
1
+ """
2
+ Base storage provider service interface.
3
+
4
+ This module defines the abstract base class for storage provider services,
5
+ providing a common interface for cloud storage operations.
6
+ """
7
+
8
+ from abc import ABC, abstractmethod
9
+ from pathlib import Path
10
+ from typing import List, Callable
11
+
12
+ from sourcerer.domain.storage_provider.entities import (
13
+ StoragePermissions,
14
+ StorageContent,
15
+ Storage,
16
+ )
17
+
18
+
19
+ class BaseStorageProviderService(ABC):
20
+ """
21
+ Abstract base class defining the interface for storage provider services.
22
+
23
+ This class defines the contract that all storage provider implementations
24
+ must follow to provide consistent access to different cloud storage systems.
25
+ It specifies methods for listing, reading, creating, and deleting storage
26
+ items across various cloud providers.
27
+ """
28
+
29
+ @abstractmethod
30
+ def list_storages(self) -> List[Storage]:
31
+ """
32
+ Return a list of available storages.
33
+
34
+ Returns:
35
+ List[Storage]: A list of Storage objects representing available storage containers
36
+ """
37
+
38
+ @abstractmethod
39
+ def get_storage_permissions(self, storage: str) -> List[StoragePermissions]:
40
+ """
41
+ Return the permissions for the specified storage.
42
+
43
+ Args:
44
+ storage (str): The storage identifier
45
+
46
+ Returns:
47
+ List[StoragePermissions]: A list of permission objects for the storage
48
+ """
49
+
50
+ @abstractmethod
51
+ def list_storage_items(
52
+ self, storage: str, path: str, prefix: str
53
+ ) -> StorageContent:
54
+ """
55
+ List items in the specified storage path with the given prefix.
56
+
57
+ Args:
58
+ storage (str): The storage identifier
59
+ path (str): The path within the storage to list
60
+ prefix (str): Filter items by this prefix
61
+
62
+ Returns:
63
+ StorageContent: Object containing files and folders at the specified location
64
+ """
65
+
66
+ @abstractmethod
67
+ def read_storage_item(self, storage: str, key: str) -> str:
68
+ """
69
+ Read and return the content of the specified storage item.
70
+
71
+ Args:
72
+ storage (str): The storage identifier
73
+ key (str): The key/path of the item to read
74
+
75
+ Returns:
76
+ bytes: The content of the storage item
77
+ """
78
+ pass
79
+
80
+ @abstractmethod
81
+ def delete_storage_item(self, storage: str, key: str) -> None:
82
+ """
83
+ Delete the specified storage item.
84
+
85
+ Args:
86
+ storage (str): The storage identifier
87
+ key (str): The key/path of the item to delete
88
+ """
89
+
90
+ @abstractmethod
91
+ def upload_storage_item(
92
+ self, storage: str, source_path: Path, dest_path: str | None = None
93
+ ) -> None:
94
+ """
95
+ Upload a file to the specified storage path.
96
+
97
+ Args:
98
+ storage (str): The storage identifier
99
+ source_path (Path): Local file path to upload
100
+ dest_path (str, optional): Destination path in storage. Defaults to None.
101
+ """
102
+
103
+ @abstractmethod
104
+ def download_storage_item(
105
+ self, storage: str, key: str, progress_callback: Callable | None = None
106
+ ) -> str:
107
+ """
108
+ Download a file from storage to local filesystem.
109
+
110
+ Args:
111
+ storage (str): The storage identifier
112
+ key (str): The key/path of the item to download
113
+ progress_callback (callable, optional): Callback function for progress updates. Defaults to None.
114
+
115
+ Returns:
116
+ str: Path to the downloaded file
117
+ """
118
+
119
+ @abstractmethod
120
+ def get_file_size(self, storage: str, key: str) -> dict:
121
+ """
122
+ Get metadata for a storage item without downloading content.
123
+
124
+ Args:
125
+ storage (str): The storage identifier
126
+ key (str): The key/path of the item
127
+
128
+ Returns:
129
+ dict: Metadata for the specified item
130
+ """
@@ -0,0 +1,13 @@
1
+ """
2
+ Infrastructure layer for the Sourcerer application.
3
+
4
+ This package contains implementations of the interfaces defined in the domain layer,
5
+ providing concrete implementations for services, repositories, and other components.
6
+ It handles interactions with external systems, databases, and frameworks.
7
+
8
+ The infrastructure layer is organized into several subpackages:
9
+ - file_system: File system service implementations
10
+ - storage_provider: Cloud storage provider service implementations
11
+ - access_credentials: Authentication and credential service implementations
12
+ - db: Database models, configuration, and utilities
13
+ """
@@ -0,0 +1,7 @@
1
+ """
2
+ Access credentials infrastructure module.
3
+
4
+ This package provides concrete implementations of the access credentials
5
+ service and repository interfaces defined in the domain layer, along with
6
+ infrastructure-specific controllers and utilities.
7
+ """
@@ -0,0 +1,16 @@
1
+ from sourcerer.domain.access_credentials.exceptions import (
2
+ BaseAccessCredentialsException,
3
+ )
4
+
5
+
6
+ class CredentialsAuthError(BaseAccessCredentialsException):
7
+ """
8
+ Exception raised when there is an error parsing access credentials.
9
+
10
+ This exception is raised when the access credentials cannot be
11
+ authenticated or parsed correctly. It indicates that the provided
12
+ credentials are invalid or not in the expected format.
13
+ This can occur during operations such as login, token validation,
14
+ or any other authentication process that relies on the provided
15
+ credentials.
16
+ """
@@ -0,0 +1,120 @@
1
+ """
2
+ Registry for access credential service implementations.
3
+
4
+ This module provides a registry system for managing different types of
5
+ access credential services for various cloud providers.
6
+ """
7
+
8
+ import functools
9
+ from dataclasses import dataclass
10
+ from typing import Type, Dict
11
+
12
+ from sourcerer.domain.access_credentials.services import BaseAccessCredentialsService
13
+ from sourcerer.infrastructure.utils import Singleton
14
+
15
+
16
+ @dataclass
17
+ class AccessCredentialsMethod:
18
+ """
19
+ Data class representing an access credentials method.
20
+
21
+ Attributes:
22
+ provider (str): The cloud provider identifier
23
+ name (str): The name of the credentials method
24
+ """
25
+
26
+ provider: str
27
+ name: str
28
+
29
+
30
+ class AccessCredentialsRegistry(metaclass=Singleton):
31
+ """
32
+ Registry for access credential service implementations.
33
+
34
+ This singleton class maintains a registry of credential service implementations
35
+ organized by provider and credential method name.
36
+ """
37
+
38
+ def __init__(self, *args, **kwargs):
39
+ """Initialize the registry with an empty dictionary."""
40
+ super().__init__(*args, **kwargs)
41
+ self._items_: Dict[str, Dict[str, type]] = {} # type: ignore
42
+
43
+ def register(
44
+ self,
45
+ access_credentials_method: AccessCredentialsMethod,
46
+ cls: Type[BaseAccessCredentialsService],
47
+ ):
48
+ """
49
+ Register a credential service implementation.
50
+
51
+ Args:
52
+ access_credentials_method (AccessCredentialsMethod): The method descriptor
53
+ cls (Type[BaseAccessCredentialsService]): The service class to register
54
+ """
55
+ if access_credentials_method.provider not in self._items_:
56
+ self._items_[access_credentials_method.provider] = {}
57
+ self._items_[access_credentials_method.provider].update(
58
+ {access_credentials_method.name: cls}
59
+ )
60
+
61
+ def get(self):
62
+ """
63
+ Get all registered credential services.
64
+
65
+ Returns:
66
+ dict: Dictionary of all registered credential services
67
+ """
68
+ return self._items_
69
+
70
+ def get_by_provider(self, provider):
71
+ """
72
+ Get credential services for a specific provider.
73
+
74
+ Args:
75
+ provider (str): The provider identifier
76
+
77
+ Returns:
78
+ dict: Dictionary of credential services for the provider
79
+ """
80
+ return self._items_.get(provider)
81
+
82
+ def get_by_provider_and_name(self, provider: str, name: str):
83
+ """
84
+ Get a specific credential service by provider and method name.
85
+
86
+ Args:
87
+ provider (str): The provider identifier
88
+ name (str): The method name
89
+
90
+ Returns:
91
+ Type[BaseAccessCredentialsService]: The credential service class
92
+ """
93
+ return self._items_.get(provider, {}).get(name)
94
+
95
+
96
+ def access_credentials_method(access_credentials_method: AccessCredentialsMethod):
97
+ """
98
+ Decorator for registering credential service implementations.
99
+
100
+ Args:
101
+ access_credentials_method (AccessCredentialsMethod): The method descriptor
102
+
103
+ Returns:
104
+ callable: Decorator function
105
+ """
106
+
107
+ def wrapper(cls):
108
+ access_credential_method_registry.register(access_credentials_method, cls)
109
+
110
+ @functools.wraps(cls)
111
+ def wrapped(*args, **kwargs):
112
+ return cls(*args, **kwargs)
113
+
114
+ return wrapped
115
+
116
+ return wrapper
117
+
118
+
119
+ # Singleton registry instance
120
+ access_credential_method_registry = AccessCredentialsRegistry()
@@ -0,0 +1,119 @@
1
+ """
2
+ SQLAlchemy implementation of the credentials repository.
3
+
4
+ This module provides a concrete implementation of the BaseCredentialsRepository
5
+ interface using SQLAlchemy for database access.
6
+ """
7
+
8
+ from sourcerer.domain.access_credentials.entities import Credentials
9
+ from sourcerer.domain.access_credentials.repositories import BaseCredentialsRepository
10
+ from sourcerer.infrastructure.db.models import Credentials as DBCredentials
11
+
12
+
13
+ class SQLAlchemyCredentialsRepository(BaseCredentialsRepository):
14
+ """
15
+ SQLAlchemy implementation of the credentials repository.
16
+
17
+ This class provides methods for storing and retrieving credentials
18
+ using SQLAlchemy as the database access layer.
19
+ """
20
+
21
+ def __init__(self, db):
22
+ """
23
+ Initialize the repository with a database session factory.
24
+
25
+ Args:
26
+ db: Database session factory
27
+ """
28
+ self.db = db
29
+
30
+ def create(self, credentials: Credentials):
31
+ """
32
+ Create new credentials in the database.
33
+
34
+ Args:
35
+ credentials (Credentials): The credentials object to store
36
+ """
37
+ credentials = DBCredentials(
38
+ uuid=credentials.uuid,
39
+ name=credentials.name,
40
+ provider=credentials.provider,
41
+ credentials_type=credentials.credentials_type,
42
+ credentials=credentials.credentials,
43
+ active=credentials.active,
44
+ )
45
+ with self.db() as session:
46
+ session.add(credentials)
47
+ session.commit()
48
+
49
+ def get(self, uuid: str):
50
+ """
51
+ Retrieve credentials by UUID.
52
+
53
+ Args:
54
+ uuid (str): Unique identifier for the credentials
55
+
56
+ Returns:
57
+ DBCredentials: The credentials object from the database
58
+ """
59
+ with self.db() as session:
60
+ return (
61
+ session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
62
+ )
63
+
64
+ def list(self, active_only: bool | None = None):
65
+ """
66
+ List all credentials in the repository.
67
+
68
+ Args:
69
+ active_only (bool|None, optional): If True, return only active credentials.
70
+ If False, return all credentials. Defaults to None.
71
+
72
+ Returns:
73
+ List[Credentials]: List of credentials objects
74
+ """
75
+ with self.db() as session:
76
+ credentials_query = session.query(DBCredentials)
77
+ if active_only:
78
+ credentials_query = credentials_query.filter(
79
+ DBCredentials.active == True # noqa: E712
80
+ )
81
+ return [
82
+ Credentials(
83
+ uuid=credential.uuid,
84
+ name=credential.name,
85
+ provider=credential.provider,
86
+ credentials_type=credential.credentials_type,
87
+ credentials=credential.credentials,
88
+ active=credential.active,
89
+ )
90
+ for credential in credentials_query.all()
91
+ ]
92
+
93
+ def activate(self, uuid):
94
+ """
95
+ Activate credentials by UUID.
96
+
97
+ Args:
98
+ uuid (str): Unique identifier for the credentials to activate
99
+ """
100
+ with self.db() as session:
101
+ credentials = (
102
+ session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
103
+ )
104
+ credentials.active = True
105
+ session.commit()
106
+
107
+ def deactivate(self, uuid):
108
+ """
109
+ Deactivate credentials by UUID.
110
+
111
+ Args:
112
+ uuid (str): Unique identifier for the credentials to deactivate
113
+ """
114
+ with self.db() as session:
115
+ credentials = (
116
+ session.query(DBCredentials).filter(DBCredentials.uuid == uuid).first()
117
+ )
118
+ credentials.active = False
119
+ session.commit()