digitalkin 0.2.14__py3-none-any.whl → 0.2.16__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.
- digitalkin/__version__.py +1 -1
- digitalkin/services/filesystem/default_filesystem.py +337 -130
- digitalkin/services/filesystem/filesystem_strategy.py +202 -34
- digitalkin/services/filesystem/grpc_filesystem.py +235 -118
- digitalkin/services/setup/grpc_setup.py +1 -0
- {digitalkin-0.2.14.dist-info → digitalkin-0.2.16.dist-info}/METADATA +1 -1
- {digitalkin-0.2.14.dist-info → digitalkin-0.2.16.dist-info}/RECORD +14 -13
- {digitalkin-0.2.14.dist-info → digitalkin-0.2.16.dist-info}/top_level.txt +1 -0
- modules/cpu_intensive_module.py +0 -1
- modules/text_transform_module.py +0 -1
- services/filesystem_module.py +198 -0
- {modules → services}/storage_module.py +20 -7
- {digitalkin-0.2.14.dist-info → digitalkin-0.2.16.dist-info}/WHEEL +0 -0
- {digitalkin-0.2.14.dist-info → digitalkin-0.2.16.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"""This module contains the abstract base class for filesystem strategies."""
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
-
from
|
|
4
|
+
from datetime import datetime
|
|
5
|
+
from typing import Any, Literal
|
|
5
6
|
|
|
6
7
|
from pydantic import BaseModel, Field
|
|
7
8
|
|
|
@@ -9,63 +10,230 @@ from digitalkin.services.base_strategy import BaseStrategy
|
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class FilesystemServiceError(Exception):
|
|
12
|
-
"""Base exception for
|
|
13
|
+
"""Base exception for Filesystem service errors."""
|
|
13
14
|
|
|
14
15
|
|
|
15
|
-
class
|
|
16
|
-
"""Enum defining the types of data that can be stored."""
|
|
17
|
-
|
|
18
|
-
DOCUMENT = auto()
|
|
19
|
-
IMAGE = auto()
|
|
20
|
-
VIDEO = auto()
|
|
21
|
-
AUDIO = auto()
|
|
22
|
-
ARCHIVE = auto()
|
|
23
|
-
OTHER = auto()
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class FilesystemData(BaseModel):
|
|
16
|
+
class FilesystemRecord(BaseModel):
|
|
27
17
|
"""Data model for filesystem operations."""
|
|
28
18
|
|
|
29
|
-
|
|
19
|
+
id: str = Field(description="Unique identifier for the file (UUID)")
|
|
20
|
+
context: str = Field(description="The context of the file in the filesystem")
|
|
30
21
|
name: str = Field(description="The name of the file")
|
|
31
|
-
file_type:
|
|
32
|
-
|
|
22
|
+
file_type: str = Field(default="UNSPECIFIED", description="The type of data stored")
|
|
23
|
+
content_type: str = Field(default="application/octet-stream", description="The MIME type of the file")
|
|
24
|
+
size_bytes: int = Field(default=0, description="Size of the file in bytes")
|
|
25
|
+
checksum: str = Field(default="", description="SHA-256 checksum of the file content")
|
|
26
|
+
metadata: dict[str, Any] | None = Field(default=None, description="Additional metadata for the file")
|
|
27
|
+
storage_url: str = Field(description="Internal URL for accessing the file content")
|
|
28
|
+
status: str = Field(default="UNSPECIFIED", description="Current status of the file")
|
|
29
|
+
content: bytes | None = Field(default=None, description="The content of the file")
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class FileFilter(BaseModel):
|
|
33
|
+
"""Filter criteria for querying files."""
|
|
34
|
+
|
|
35
|
+
names: list[str] | None = Field(default=None, description="Filter by file names (exact matches)")
|
|
36
|
+
file_ids: list[str] | None = Field(default=None, description="Filter by file IDs")
|
|
37
|
+
file_types: (
|
|
38
|
+
list[
|
|
39
|
+
Literal[
|
|
40
|
+
"UNSPECIFIED",
|
|
41
|
+
"DOCUMENT",
|
|
42
|
+
"IMAGE",
|
|
43
|
+
"AUDIO",
|
|
44
|
+
"VIDEO",
|
|
45
|
+
"ARCHIVE",
|
|
46
|
+
"CODE",
|
|
47
|
+
"OTHER",
|
|
48
|
+
]
|
|
49
|
+
]
|
|
50
|
+
| None
|
|
51
|
+
) = Field(default=None, description="Filter by file types")
|
|
52
|
+
created_after: datetime | None = Field(default=None, description="Filter files created after this timestamp")
|
|
53
|
+
created_before: datetime | None = Field(default=None, description="Filter files created before this timestamp")
|
|
54
|
+
updated_after: datetime | None = Field(default=None, description="Filter files updated after this timestamp")
|
|
55
|
+
updated_before: datetime | None = Field(default=None, description="Filter files updated before this timestamp")
|
|
56
|
+
status: str | None = Field(default=None, description="Filter by file status")
|
|
57
|
+
content_type_prefix: str | None = Field(default=None, description="Filter by content type prefix (e.g., 'image/')")
|
|
58
|
+
min_size_bytes: int | None = Field(default=None, description="Filter files with minimum size")
|
|
59
|
+
max_size_bytes: int | None = Field(default=None, description="Filter files with maximum size")
|
|
60
|
+
prefix: str | None = Field(default=None, description="Filter by path prefix (e.g., 'folder1/')")
|
|
61
|
+
content_type: str | None = Field(default=None, description="Filter by content type")
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class UploadFileData(BaseModel):
|
|
65
|
+
"""Data model for uploading a file."""
|
|
66
|
+
|
|
67
|
+
content: bytes = Field(description="The content of the file")
|
|
68
|
+
name: str = Field(description="The name of the file")
|
|
69
|
+
file_type: Literal[
|
|
70
|
+
"UNSPECIFIED",
|
|
71
|
+
"DOCUMENT",
|
|
72
|
+
"IMAGE",
|
|
73
|
+
"AUDIO",
|
|
74
|
+
"VIDEO",
|
|
75
|
+
"ARCHIVE",
|
|
76
|
+
"CODE",
|
|
77
|
+
"OTHER",
|
|
78
|
+
] = Field(description="The type of the file")
|
|
79
|
+
content_type: str | None = Field(default=None, description="The content type of the file")
|
|
80
|
+
metadata: dict[str, Any] | None = Field(default=None, description="The metadata of the file")
|
|
81
|
+
replace_if_exists: bool = Field(default=False, description="Whether to replace the file if it already exists")
|
|
33
82
|
|
|
34
83
|
|
|
35
84
|
class FilesystemStrategy(BaseStrategy, ABC):
|
|
36
|
-
"""Abstract base class for filesystem strategies.
|
|
85
|
+
"""Abstract base class for filesystem strategies.
|
|
86
|
+
|
|
87
|
+
This strategy provides comprehensive file management capabilities including
|
|
88
|
+
upload, retrieval, update, and deletion operations with rich metadata support,
|
|
89
|
+
filtering, and pagination.
|
|
90
|
+
"""
|
|
37
91
|
|
|
38
|
-
def __init__(self, mission_id: str, setup_version_id: str, config: dict[str,
|
|
92
|
+
def __init__(self, mission_id: str, setup_version_id: str, config: dict[str, Any] | None = None) -> None:
|
|
39
93
|
"""Initialize the strategy.
|
|
40
94
|
|
|
41
95
|
Args:
|
|
42
96
|
mission_id: The ID of the mission this strategy is associated with
|
|
43
97
|
setup_version_id: The ID of the setup version this strategy is associated with
|
|
44
|
-
config:
|
|
98
|
+
config: Configuration for the filesystem strategy
|
|
45
99
|
"""
|
|
46
100
|
super().__init__(mission_id, setup_version_id)
|
|
47
|
-
self.config
|
|
101
|
+
self.config = config
|
|
48
102
|
|
|
49
103
|
@abstractmethod
|
|
50
|
-
def
|
|
51
|
-
|
|
104
|
+
def upload_files(
|
|
105
|
+
self,
|
|
106
|
+
files: list[UploadFileData],
|
|
107
|
+
) -> tuple[list[FilesystemRecord], int, int]:
|
|
108
|
+
"""Upload multiple files to the system.
|
|
52
109
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
110
|
+
This method allows batch uploading of files with validation and
|
|
111
|
+
error handling for each individual file. Files are processed
|
|
112
|
+
atomically - if one fails, others may still succeed.
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
files: List of tuples containing (content, name, file_type, content_type, metadata, replace_if_exists)
|
|
116
|
+
|
|
117
|
+
Returns:
|
|
118
|
+
tuple[list[FilesystemRecord], int, int]: List of uploaded files, total uploaded count, total failed count
|
|
119
|
+
"""
|
|
56
120
|
|
|
57
121
|
@abstractmethod
|
|
58
|
-
def
|
|
59
|
-
|
|
122
|
+
def get_file(
|
|
123
|
+
self,
|
|
124
|
+
file_id: str,
|
|
125
|
+
*,
|
|
126
|
+
include_content: bool = False,
|
|
127
|
+
) -> tuple[FilesystemRecord, bytes | None]:
|
|
128
|
+
"""Get a specific file by ID or name.
|
|
129
|
+
|
|
130
|
+
This method fetches detailed information about a single file,
|
|
131
|
+
with optional content inclusion. Supports lookup by either
|
|
132
|
+
unique ID or name within a context.
|
|
133
|
+
|
|
134
|
+
Args:
|
|
135
|
+
file_id: The ID of the file to be retrieved
|
|
136
|
+
include_content: Whether to include file content in response
|
|
137
|
+
|
|
138
|
+
Returns:
|
|
139
|
+
tuple[FilesystemRecord, bytes | None]: Metadata about the retrieved file and optional content
|
|
140
|
+
"""
|
|
60
141
|
|
|
61
142
|
@abstractmethod
|
|
62
|
-
def
|
|
63
|
-
|
|
143
|
+
def get_files(
|
|
144
|
+
self,
|
|
145
|
+
filters: FileFilter,
|
|
146
|
+
*,
|
|
147
|
+
list_size: int = 100,
|
|
148
|
+
offset: int = 0,
|
|
149
|
+
order: str | None = None,
|
|
150
|
+
include_content: bool = False,
|
|
151
|
+
) -> tuple[list[FilesystemRecord], int]:
|
|
152
|
+
"""Get multiple files by various criteria.
|
|
153
|
+
|
|
154
|
+
This method provides efficient retrieval of multiple files using:
|
|
155
|
+
- File IDs
|
|
156
|
+
- File names
|
|
157
|
+
- Path prefix
|
|
158
|
+
With support for:
|
|
159
|
+
- Pagination for large result sets
|
|
160
|
+
- Optional content inclusion
|
|
161
|
+
- Total count of matching files
|
|
162
|
+
|
|
163
|
+
Args:
|
|
164
|
+
filters: Filter criteria for the files
|
|
165
|
+
list_size: Number of files to return per page
|
|
166
|
+
offset: Offset to start listing files from
|
|
167
|
+
order: Field to order results by
|
|
168
|
+
include_content: Whether to include file content in response
|
|
169
|
+
|
|
170
|
+
Returns:
|
|
171
|
+
tuple[list[FilesystemRecord], int]: List of files and total count
|
|
172
|
+
"""
|
|
64
173
|
|
|
65
174
|
@abstractmethod
|
|
66
|
-
def
|
|
67
|
-
|
|
175
|
+
def update_file(
|
|
176
|
+
self,
|
|
177
|
+
file_id: str,
|
|
178
|
+
content: bytes | None = None,
|
|
179
|
+
file_type: Literal[
|
|
180
|
+
"UNSPECIFIED",
|
|
181
|
+
"DOCUMENT",
|
|
182
|
+
"IMAGE",
|
|
183
|
+
"VIDEO",
|
|
184
|
+
"AUDIO",
|
|
185
|
+
"ARCHIVE",
|
|
186
|
+
"CODE",
|
|
187
|
+
"OTHER",
|
|
188
|
+
]
|
|
189
|
+
| None = None,
|
|
190
|
+
content_type: str | None = None,
|
|
191
|
+
metadata: dict[str, Any] | None = None,
|
|
192
|
+
new_name: str | None = None,
|
|
193
|
+
status: str | None = None,
|
|
194
|
+
) -> FilesystemRecord:
|
|
195
|
+
"""Update file metadata, content, or both.
|
|
196
|
+
|
|
197
|
+
This method allows updating various aspects of a file:
|
|
198
|
+
- Rename files
|
|
199
|
+
- Update content and content type
|
|
200
|
+
- Modify metadata
|
|
201
|
+
- Create new versions
|
|
202
|
+
|
|
203
|
+
Args:
|
|
204
|
+
file_id: The ID of the file to be updated
|
|
205
|
+
content: Optional new content of the file
|
|
206
|
+
file_type: Optional new type of data
|
|
207
|
+
content_type: Optional new MIME type
|
|
208
|
+
metadata: Optional new metadata (will merge with existing)
|
|
209
|
+
new_name: Optional new name for the file
|
|
210
|
+
status: Optional new status for the file
|
|
211
|
+
|
|
212
|
+
Returns:
|
|
213
|
+
FilesystemRecord: Metadata about the updated file
|
|
214
|
+
"""
|
|
68
215
|
|
|
69
216
|
@abstractmethod
|
|
70
|
-
def
|
|
71
|
-
|
|
217
|
+
def delete_files(
|
|
218
|
+
self,
|
|
219
|
+
filters: FileFilter,
|
|
220
|
+
*,
|
|
221
|
+
permanent: bool = False,
|
|
222
|
+
force: bool = False,
|
|
223
|
+
) -> tuple[dict[str, bool], int, int]:
|
|
224
|
+
"""Delete multiple files.
|
|
225
|
+
|
|
226
|
+
This method supports batch deletion of files with options for:
|
|
227
|
+
- Soft deletion (marking as deleted)
|
|
228
|
+
- Permanent deletion
|
|
229
|
+
- Force deletion of files in use
|
|
230
|
+
- Individual error reporting per file
|
|
231
|
+
|
|
232
|
+
Args:
|
|
233
|
+
filters: Filter criteria for the files
|
|
234
|
+
permanent: Whether to permanently delete the files
|
|
235
|
+
force: Whether to force delete even if files are in use
|
|
236
|
+
|
|
237
|
+
Returns:
|
|
238
|
+
tuple[dict[str, bool], int, int]: Results per file, total deleted count, total failed count
|
|
239
|
+
"""
|