synapse-sdk 1.0.0b13__py3-none-any.whl → 1.0.0b14__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.
Potentially problematic release.
This version of synapse-sdk might be problematic. Click here for more details.
- locale/ko/LC_MESSAGES/messages.mo +0 -0
- synapse_sdk/clients/agent/ray.py +9 -11
- synapse_sdk/clients/backend/annotation.py +1 -1
- synapse_sdk/clients/backend/core.py +31 -4
- synapse_sdk/clients/backend/data_collection.py +78 -5
- synapse_sdk/clients/backend/hitl.py +1 -1
- synapse_sdk/clients/backend/ml.py +1 -1
- synapse_sdk/clients/base.py +23 -16
- synapse_sdk/devtools/docs/docs/api/clients/agent.md +43 -0
- synapse_sdk/devtools/docs/docs/api/clients/backend.md +53 -0
- synapse_sdk/devtools/docs/docs/api/clients/base.md +35 -0
- synapse_sdk/devtools/docs/docs/api/clients/ray.md +321 -0
- synapse_sdk/devtools/docs/docs/api/index.md +52 -0
- synapse_sdk/devtools/docs/docs/api/plugins/categories.md +43 -0
- synapse_sdk/devtools/docs/docs/api/plugins/models.md +59 -0
- synapse_sdk/devtools/docs/docs/api/plugins/utils.md +328 -0
- synapse_sdk/devtools/docs/docs/api/utils/file.md +195 -0
- synapse_sdk/devtools/docs/docs/api/utils/network.md +378 -0
- synapse_sdk/devtools/docs/docs/api/utils/storage.md +57 -0
- synapse_sdk/devtools/docs/docs/api/utils/types.md +51 -0
- synapse_sdk/devtools/docs/docs/categories.md +0 -0
- synapse_sdk/devtools/docs/docs/cli-usage.md +280 -0
- synapse_sdk/devtools/docs/docs/concepts/index.md +38 -0
- synapse_sdk/devtools/docs/docs/configuration.md +83 -0
- synapse_sdk/devtools/docs/docs/contributing.md +306 -0
- synapse_sdk/devtools/docs/docs/examples/index.md +29 -0
- synapse_sdk/devtools/docs/docs/faq.md +179 -0
- synapse_sdk/devtools/docs/docs/features/converters/index.md +455 -0
- synapse_sdk/devtools/docs/docs/features/index.md +24 -0
- synapse_sdk/devtools/docs/docs/features/plugins/index.md +509 -0
- synapse_sdk/devtools/docs/docs/installation.md +94 -0
- synapse_sdk/devtools/docs/docs/introduction.md +47 -0
- synapse_sdk/devtools/docs/docs/quickstart.md +78 -0
- synapse_sdk/devtools/docs/docs/troubleshooting.md +519 -0
- synapse_sdk/devtools/docs/docs/tutorial-basics/_category_.json +8 -0
- synapse_sdk/devtools/docs/docs/tutorial-basics/congratulations.md +23 -0
- synapse_sdk/devtools/docs/docs/tutorial-basics/create-a-blog-post.md +34 -0
- synapse_sdk/devtools/docs/docs/tutorial-basics/create-a-document.md +57 -0
- synapse_sdk/devtools/docs/docs/tutorial-basics/create-a-page.md +43 -0
- synapse_sdk/devtools/docs/docs/tutorial-basics/deploy-your-site.md +31 -0
- synapse_sdk/devtools/docs/docs/tutorial-basics/markdown-features.mdx +152 -0
- synapse_sdk/devtools/docs/docs/tutorial-extras/_category_.json +7 -0
- synapse_sdk/devtools/docs/docs/tutorial-extras/img/docsVersionDropdown.png +0 -0
- synapse_sdk/devtools/docs/docs/tutorial-extras/img/localeDropdown.png +0 -0
- synapse_sdk/devtools/docs/docs/tutorial-extras/manage-docs-versions.md +55 -0
- synapse_sdk/devtools/docs/docs/tutorial-extras/translate-your-site.md +88 -0
- synapse_sdk/devtools/docs/docusaurus.config.ts +5 -3
- synapse_sdk/devtools/docs/i18n/ko/code.json +325 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/agent.md +43 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/backend.md +53 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/base.md +35 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/ray.md +321 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/index.md +52 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/utils/file.md +195 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/utils/network.md +378 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/utils/storage.md +60 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/utils/types.md +51 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/categories.md +0 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/cli-usage.md +280 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/concepts/index.md +38 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/configuration.md +83 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/contributing.md +306 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/examples/index.md +29 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/faq.md +179 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/converters/index.md +30 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/index.md +24 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/plugins/index.md +30 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/installation.md +94 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/introduction.md +47 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/quickstart.md +78 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/troubleshooting.md +519 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current.json +22 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-theme-classic/footer.json +42 -0
- synapse_sdk/devtools/docs/i18n/ko/docusaurus-theme-classic/navbar.json +18 -0
- synapse_sdk/devtools/docs/node_modules/shell-quote/print.py +3 -0
- synapse_sdk/devtools/docs/package.json +1 -1
- synapse_sdk/plugins/categories/export/actions/export.py +3 -0
- synapse_sdk/plugins/categories/upload/actions/upload.py +9 -4
- synapse_sdk/utils/file.py +77 -0
- {synapse_sdk-1.0.0b13.dist-info → synapse_sdk-1.0.0b14.dist-info}/METADATA +1 -1
- {synapse_sdk-1.0.0b13.dist-info → synapse_sdk-1.0.0b14.dist-info}/RECORD +85 -19
- {synapse_sdk-1.0.0b13.dist-info → synapse_sdk-1.0.0b14.dist-info}/WHEEL +0 -0
- {synapse_sdk-1.0.0b13.dist-info → synapse_sdk-1.0.0b14.dist-info}/entry_points.txt +0 -0
- {synapse_sdk-1.0.0b13.dist-info → synapse_sdk-1.0.0b14.dist-info}/licenses/LICENSE +0 -0
- {synapse_sdk-1.0.0b13.dist-info → synapse_sdk-1.0.0b14.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: utils
|
|
3
|
+
title: Plugin Utilities
|
|
4
|
+
sidebar_position: 3
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Plugin Utilities
|
|
8
|
+
|
|
9
|
+
Comprehensive utility functions for plugin development, configuration management, and action handling.
|
|
10
|
+
|
|
11
|
+
## Overview
|
|
12
|
+
|
|
13
|
+
The plugin utilities module (`synapse_sdk.plugins.utils`) provides a collection of functions for working with plugin configurations, managing actions, and handling plugin metadata. The utilities are organized into focused modules for better maintainability.
|
|
14
|
+
|
|
15
|
+
## Configuration Utilities
|
|
16
|
+
|
|
17
|
+
### read_plugin_config()
|
|
18
|
+
|
|
19
|
+
Read and parse plugin configuration from config.yaml file with enhanced error handling.
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from synapse_sdk.plugins.utils import read_plugin_config
|
|
23
|
+
|
|
24
|
+
# Read from specific plugin directory
|
|
25
|
+
config = read_plugin_config(plugin_path="./my-plugin")
|
|
26
|
+
|
|
27
|
+
# Read from current directory
|
|
28
|
+
config = read_plugin_config()
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Parameters:**
|
|
32
|
+
|
|
33
|
+
- `plugin_path` (optional): Path to plugin directory containing config.yaml
|
|
34
|
+
|
|
35
|
+
**Returns:** Dictionary containing parsed plugin configuration
|
|
36
|
+
|
|
37
|
+
**Raises:**
|
|
38
|
+
|
|
39
|
+
- `FileNotFoundError`: If config.yaml is not found
|
|
40
|
+
- `ValueError`: If config.yaml contains invalid YAML
|
|
41
|
+
|
|
42
|
+
### get_plugin_actions()
|
|
43
|
+
|
|
44
|
+
Get list of action names defined in a plugin configuration.
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from synapse_sdk.plugins.utils import get_plugin_actions
|
|
48
|
+
|
|
49
|
+
# From config dictionary
|
|
50
|
+
config = {'actions': {'train': {...}, 'inference': {...}}}
|
|
51
|
+
actions = get_plugin_actions(config=config)
|
|
52
|
+
# Returns: ['train', 'inference']
|
|
53
|
+
|
|
54
|
+
# From plugin path
|
|
55
|
+
actions = get_plugin_actions(plugin_path="./my-plugin")
|
|
56
|
+
|
|
57
|
+
# From current directory
|
|
58
|
+
actions = get_plugin_actions()
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
**Parameters:**
|
|
62
|
+
|
|
63
|
+
- `config` (optional): Plugin configuration dictionary
|
|
64
|
+
- `plugin_path` (optional): Path to plugin directory
|
|
65
|
+
|
|
66
|
+
**Returns:** List of action names
|
|
67
|
+
|
|
68
|
+
### get_action_config()
|
|
69
|
+
|
|
70
|
+
Retrieve configuration for a specific action within a plugin.
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from synapse_sdk.plugins.utils import get_action_config
|
|
74
|
+
|
|
75
|
+
# Get specific action configuration
|
|
76
|
+
action_config = get_action_config('train', plugin_path="./my-plugin")
|
|
77
|
+
# Returns: {'entrypoint': 'plugin.train.TrainAction', 'method': 'job'}
|
|
78
|
+
|
|
79
|
+
# With config dictionary
|
|
80
|
+
config = {'actions': {'train': {'entrypoint': 'plugin.train.TrainAction'}}}
|
|
81
|
+
action_config = get_action_config('train', config=config)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Parameters:**
|
|
85
|
+
|
|
86
|
+
- `action_name`: Name of the action to retrieve
|
|
87
|
+
- `config` (optional): Plugin configuration dictionary
|
|
88
|
+
- `plugin_path` (optional): Path to plugin directory
|
|
89
|
+
|
|
90
|
+
**Returns:** Dictionary containing action configuration
|
|
91
|
+
|
|
92
|
+
### validate_plugin_config()
|
|
93
|
+
|
|
94
|
+
Validate plugin configuration structure and required fields.
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from synapse_sdk.plugins.utils import validate_plugin_config
|
|
98
|
+
|
|
99
|
+
config = {
|
|
100
|
+
'name': 'My Plugin',
|
|
101
|
+
'code': 'my-plugin',
|
|
102
|
+
'version': '1.0.0',
|
|
103
|
+
'category': 'neural_net',
|
|
104
|
+
'actions': {'train': {'entrypoint': 'plugin.train.TrainAction'}}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
is_valid = validate_plugin_config(config) # Returns: True
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
**Validation Checks:**
|
|
111
|
+
|
|
112
|
+
- Required fields: `name`, `code`, `version`, `category`, `actions`
|
|
113
|
+
- Valid plugin category
|
|
114
|
+
- Proper actions structure
|
|
115
|
+
- Required entrypoints (except for REST API actions)
|
|
116
|
+
|
|
117
|
+
### get_plugin_metadata()
|
|
118
|
+
|
|
119
|
+
Extract metadata (name, version, description, etc.) from plugin configuration.
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from synapse_sdk.plugins.utils import get_plugin_metadata
|
|
123
|
+
|
|
124
|
+
metadata = get_plugin_metadata(plugin_path="./my-plugin")
|
|
125
|
+
# Returns: {
|
|
126
|
+
# 'name': 'My Plugin',
|
|
127
|
+
# 'code': 'my-plugin',
|
|
128
|
+
# 'version': '1.0.0',
|
|
129
|
+
# 'category': 'neural_net',
|
|
130
|
+
# 'description': 'A custom ML plugin'
|
|
131
|
+
# }
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Action Utilities
|
|
135
|
+
|
|
136
|
+
### get_action_class()
|
|
137
|
+
|
|
138
|
+
Retrieve action class by category and action name from the registry.
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from synapse_sdk.plugins.utils import get_action_class
|
|
142
|
+
|
|
143
|
+
# Get action class for instantiation
|
|
144
|
+
TrainAction = get_action_class('neural_net', 'train')
|
|
145
|
+
action_instance = TrainAction(params, config)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### get_available_actions()
|
|
149
|
+
|
|
150
|
+
List all available actions for a specific plugin category.
|
|
151
|
+
|
|
152
|
+
```python
|
|
153
|
+
from synapse_sdk.plugins.utils import get_available_actions
|
|
154
|
+
|
|
155
|
+
actions = get_available_actions('neural_net')
|
|
156
|
+
# Returns: ['train', 'inference', 'test', 'deployment', 'gradio', 'tune']
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### is_action_available()
|
|
160
|
+
|
|
161
|
+
Check if a specific action is available in a category.
|
|
162
|
+
|
|
163
|
+
```python
|
|
164
|
+
from synapse_sdk.plugins.utils import is_action_available
|
|
165
|
+
|
|
166
|
+
if is_action_available('neural_net', 'train'):
|
|
167
|
+
print("Training action is available")
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### get_action()
|
|
171
|
+
|
|
172
|
+
Create and configure a plugin action instance with parameters.
|
|
173
|
+
|
|
174
|
+
```python
|
|
175
|
+
from synapse_sdk.plugins.utils import get_action
|
|
176
|
+
|
|
177
|
+
# With dictionary parameters
|
|
178
|
+
params = {'dataset_path': '/data', 'epochs': 10}
|
|
179
|
+
action = get_action('train', params, plugin_path="./my-plugin")
|
|
180
|
+
|
|
181
|
+
# With JSON string parameters
|
|
182
|
+
params_json = '{"dataset_path": "/data", "epochs": 10}'
|
|
183
|
+
action = get_action('train', params_json, config=config)
|
|
184
|
+
|
|
185
|
+
# With file parameters
|
|
186
|
+
action = get_action('train', '/path/to/params.yaml')
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Registry Utilities
|
|
190
|
+
|
|
191
|
+
### get_plugin_categories()
|
|
192
|
+
|
|
193
|
+
Get list of all available plugin categories.
|
|
194
|
+
|
|
195
|
+
```python
|
|
196
|
+
from synapse_sdk.plugins.utils import get_plugin_categories
|
|
197
|
+
|
|
198
|
+
categories = get_plugin_categories()
|
|
199
|
+
# Returns: ['neural_net', 'export', 'upload', 'smart_tool',
|
|
200
|
+
# 'post_annotation', 'pre_annotation', 'data_validation']
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### is_valid_category()
|
|
204
|
+
|
|
205
|
+
Validate if a category name is valid.
|
|
206
|
+
|
|
207
|
+
```python
|
|
208
|
+
from synapse_sdk.plugins.utils import is_valid_category
|
|
209
|
+
|
|
210
|
+
if is_valid_category('neural_net'):
|
|
211
|
+
print("Valid category")
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### get_category_display_name()
|
|
215
|
+
|
|
216
|
+
Get human-readable display name for a category.
|
|
217
|
+
|
|
218
|
+
```python
|
|
219
|
+
from synapse_sdk.plugins.utils import get_category_display_name
|
|
220
|
+
|
|
221
|
+
display_name = get_category_display_name('neural_net')
|
|
222
|
+
# Returns: "Neural Net"
|
|
223
|
+
|
|
224
|
+
display_name = get_category_display_name('data_validation')
|
|
225
|
+
# Returns: "Data Validation"
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
## Error Handling
|
|
229
|
+
|
|
230
|
+
All utility functions include comprehensive error handling with descriptive error messages:
|
|
231
|
+
|
|
232
|
+
```python
|
|
233
|
+
from synapse_sdk.plugins.utils import get_plugin_actions
|
|
234
|
+
|
|
235
|
+
try:
|
|
236
|
+
actions = get_plugin_actions(plugin_path="./nonexistent")
|
|
237
|
+
except FileNotFoundError as e:
|
|
238
|
+
print(f"Plugin config not found: {e}")
|
|
239
|
+
except ValueError as e:
|
|
240
|
+
print(f"Invalid plugin config: {e}")
|
|
241
|
+
except KeyError as e:
|
|
242
|
+
print(f"Missing required field: {e}")
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
## Usage Examples
|
|
246
|
+
|
|
247
|
+
### Complete Plugin Workflow
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
from synapse_sdk.plugins.utils import (
|
|
251
|
+
read_plugin_config,
|
|
252
|
+
get_plugin_actions,
|
|
253
|
+
get_action_config,
|
|
254
|
+
validate_plugin_config,
|
|
255
|
+
get_action_class
|
|
256
|
+
)
|
|
257
|
+
|
|
258
|
+
# 1. Read plugin configuration
|
|
259
|
+
config = read_plugin_config("./my-neural-net-plugin")
|
|
260
|
+
|
|
261
|
+
# 2. Validate configuration
|
|
262
|
+
if validate_plugin_config(config):
|
|
263
|
+
print("✅ Plugin configuration is valid")
|
|
264
|
+
|
|
265
|
+
# 3. List available actions
|
|
266
|
+
actions = get_plugin_actions(config=config)
|
|
267
|
+
print(f"Available actions: {actions}")
|
|
268
|
+
|
|
269
|
+
# 4. Get specific action configuration
|
|
270
|
+
train_config = get_action_config('train', config=config)
|
|
271
|
+
print(f"Train entrypoint: {train_config['entrypoint']}")
|
|
272
|
+
|
|
273
|
+
# 5. Create action instance
|
|
274
|
+
TrainAction = get_action_class(config['category'], 'train')
|
|
275
|
+
action = TrainAction(
|
|
276
|
+
params={'dataset_path': '/data', 'epochs': 10},
|
|
277
|
+
plugin_config=config
|
|
278
|
+
)
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Plugin Development Helper
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
from synapse_sdk.plugins.utils import (
|
|
285
|
+
get_plugin_categories,
|
|
286
|
+
get_available_actions,
|
|
287
|
+
is_action_available
|
|
288
|
+
)
|
|
289
|
+
|
|
290
|
+
# Check available categories
|
|
291
|
+
categories = get_plugin_categories()
|
|
292
|
+
print("Available plugin categories:")
|
|
293
|
+
for category in categories:
|
|
294
|
+
print(f" - {category}")
|
|
295
|
+
|
|
296
|
+
# List actions for each category
|
|
297
|
+
actions = get_available_actions(category)
|
|
298
|
+
for action in actions:
|
|
299
|
+
print(f" - {action}")
|
|
300
|
+
|
|
301
|
+
# Verify action availability
|
|
302
|
+
if is_action_available('neural_net', 'train'):
|
|
303
|
+
print("✅ Train action is available for neural_net plugins")
|
|
304
|
+
```
|
|
305
|
+
|
|
306
|
+
## Migration from Legacy API
|
|
307
|
+
|
|
308
|
+
The new utilities maintain backward compatibility while providing enhanced functionality:
|
|
309
|
+
|
|
310
|
+
```python
|
|
311
|
+
# Legacy (still supported)
|
|
312
|
+
from synapse_sdk.plugins.utils import read_plugin_config
|
|
313
|
+
|
|
314
|
+
# New enhanced API (recommended)
|
|
315
|
+
from synapse_sdk.plugins.utils import (
|
|
316
|
+
read_plugin_config,
|
|
317
|
+
get_plugin_actions,
|
|
318
|
+
validate_plugin_config
|
|
319
|
+
)
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## Best Practices
|
|
323
|
+
|
|
324
|
+
1. **Error Handling**: Always wrap utility calls in try-catch blocks
|
|
325
|
+
2. **Configuration Validation**: Validate configs before using them
|
|
326
|
+
3. **Path Handling**: Use absolute paths when possible
|
|
327
|
+
4. **Action Verification**: Check action availability before instantiation
|
|
328
|
+
5. **Type Safety**: Use the provided type hints for better IDE support
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: file
|
|
3
|
+
title: File Utilities
|
|
4
|
+
sidebar_position: 1
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# File Utilities
|
|
8
|
+
|
|
9
|
+
File operations and handling utilities.
|
|
10
|
+
|
|
11
|
+
## File Operations
|
|
12
|
+
|
|
13
|
+
### Archive Functions
|
|
14
|
+
|
|
15
|
+
Functions for creating and extracting plugin archives.
|
|
16
|
+
|
|
17
|
+
### Download Functions
|
|
18
|
+
|
|
19
|
+
Utilities for downloading files from URLs.
|
|
20
|
+
|
|
21
|
+
```python
|
|
22
|
+
from synapse_sdk.utils.file import download_file
|
|
23
|
+
|
|
24
|
+
local_path = download_file(url, destination)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Upload Functions
|
|
28
|
+
|
|
29
|
+
File upload utilities with chunked upload support.
|
|
30
|
+
|
|
31
|
+
## Chunked File Operations
|
|
32
|
+
|
|
33
|
+
### read_file_in_chunks
|
|
34
|
+
|
|
35
|
+
Read files in chunks for efficient memory usage, particularly useful for large files or when processing files in chunks for uploading or hashing.
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
from synapse_sdk.utils.file import read_file_in_chunks
|
|
39
|
+
|
|
40
|
+
# Read a file in default 50MB chunks
|
|
41
|
+
for chunk in read_file_in_chunks('/path/to/large_file.bin'):
|
|
42
|
+
process_chunk(chunk)
|
|
43
|
+
|
|
44
|
+
# Read with custom chunk size (10MB)
|
|
45
|
+
for chunk in read_file_in_chunks('/path/to/file.bin', chunk_size=1024*1024*10):
|
|
46
|
+
upload_chunk(chunk)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Parameters:**
|
|
50
|
+
|
|
51
|
+
- `file_path` (str | Path): Path to the file to read
|
|
52
|
+
- `chunk_size` (int, optional): Size of each chunk in bytes. Defaults to 50MB (52,428,800 bytes)
|
|
53
|
+
|
|
54
|
+
**Returns:**
|
|
55
|
+
|
|
56
|
+
- Generator yielding file content chunks as bytes
|
|
57
|
+
|
|
58
|
+
**Raises:**
|
|
59
|
+
|
|
60
|
+
- `FileNotFoundError`: If the file doesn't exist
|
|
61
|
+
- `PermissionError`: If the file can't be read due to permissions
|
|
62
|
+
- `OSError`: If there's an OS-level error reading the file
|
|
63
|
+
|
|
64
|
+
### Use Cases
|
|
65
|
+
|
|
66
|
+
**Large File Processing**: Efficiently process files that are too large to fit in memory:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
import hashlib
|
|
70
|
+
|
|
71
|
+
def calculate_hash_for_large_file(file_path):
|
|
72
|
+
hash_md5 = hashlib.md5()
|
|
73
|
+
for chunk in read_file_in_chunks(file_path):
|
|
74
|
+
hash_md5.update(chunk)
|
|
75
|
+
return hash_md5.hexdigest()
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Chunked Upload Integration**: The function integrates seamlessly with the `CoreClientMixin.create_chunked_upload` method:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
from synapse_sdk.clients.backend.core import CoreClientMixin
|
|
82
|
+
|
|
83
|
+
client = CoreClientMixin(base_url='https://api.example.com')
|
|
84
|
+
result = client.create_chunked_upload('/path/to/large_file.zip')
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Best Practices:**
|
|
88
|
+
|
|
89
|
+
- Use default chunk size (50MB) for optimal upload performance
|
|
90
|
+
- Adjust chunk size based on available memory and network conditions
|
|
91
|
+
- For very large files (>1GB), consider using smaller chunks for better progress tracking
|
|
92
|
+
- Always handle exceptions when working with file operations
|
|
93
|
+
|
|
94
|
+
## Checksum Functions
|
|
95
|
+
|
|
96
|
+
### get_checksum_from_file
|
|
97
|
+
|
|
98
|
+
Calculate checksum for file-like objects without requiring Django dependencies. This function works with any file-like object that has a `read()` method, making it compatible with Django's File objects, BytesIO, StringIO, and regular file objects.
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
import hashlib
|
|
102
|
+
from io import BytesIO
|
|
103
|
+
from synapse_sdk.utils.file import get_checksum_from_file
|
|
104
|
+
|
|
105
|
+
# Basic usage with BytesIO (defaults to SHA1)
|
|
106
|
+
data = BytesIO(b'Hello, world!')
|
|
107
|
+
checksum = get_checksum_from_file(data)
|
|
108
|
+
print(checksum) # SHA1 hash as hexadecimal string
|
|
109
|
+
|
|
110
|
+
# Using different hash algorithms
|
|
111
|
+
checksum_md5 = get_checksum_from_file(data, digest_mod=hashlib.md5)
|
|
112
|
+
checksum_sha256 = get_checksum_from_file(data, digest_mod=hashlib.sha256)
|
|
113
|
+
|
|
114
|
+
# With real file objects
|
|
115
|
+
with open('/path/to/file.txt', 'rb') as f:
|
|
116
|
+
checksum = get_checksum_from_file(f)
|
|
117
|
+
|
|
118
|
+
# With StringIO (text files)
|
|
119
|
+
from io import StringIO
|
|
120
|
+
text_data = StringIO('Hello, world!')
|
|
121
|
+
checksum = get_checksum_from_file(text_data) # Automatically UTF-8 encoded
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Parameters:**
|
|
125
|
+
|
|
126
|
+
- `file` (IO[Any]): File-like object with read() method that supports reading in chunks
|
|
127
|
+
- `digest_mod` (Callable[[], Any], optional): Hash algorithm from hashlib. Defaults to `hashlib.sha1`
|
|
128
|
+
|
|
129
|
+
**Returns:**
|
|
130
|
+
|
|
131
|
+
- `str`: Hexadecimal digest of the file contents
|
|
132
|
+
|
|
133
|
+
**Key Features:**
|
|
134
|
+
|
|
135
|
+
- **Memory Efficient**: Reads files in 4KB chunks to handle large files
|
|
136
|
+
- **Automatic File Pointer Reset**: Resets to beginning if the file object supports seeking
|
|
137
|
+
- **Text/Binary Agnostic**: Handles both text (StringIO) and binary (BytesIO) file objects
|
|
138
|
+
- **No Django Dependency**: Works without Django while being compatible with Django File objects
|
|
139
|
+
- **Flexible Hash Algorithms**: Supports any hashlib algorithm (SHA1, SHA256, MD5, etc.)
|
|
140
|
+
|
|
141
|
+
**Use Cases:**
|
|
142
|
+
|
|
143
|
+
**Django File Object Compatibility**: Works with Django's File objects without requiring Django:
|
|
144
|
+
|
|
145
|
+
```python
|
|
146
|
+
# Simulating Django File-like behavior
|
|
147
|
+
class FileWrapper:
|
|
148
|
+
def __init__(self, data):
|
|
149
|
+
self._data = data
|
|
150
|
+
self._pos = 0
|
|
151
|
+
|
|
152
|
+
def read(self, size=None):
|
|
153
|
+
if size is None:
|
|
154
|
+
result = self._data[self._pos:]
|
|
155
|
+
self._pos = len(self._data)
|
|
156
|
+
else:
|
|
157
|
+
result = self._data[self._pos:self._pos + size]
|
|
158
|
+
self._pos += len(result)
|
|
159
|
+
return result
|
|
160
|
+
|
|
161
|
+
file_obj = FileWrapper(b'File content')
|
|
162
|
+
checksum = get_checksum_from_file(file_obj)
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Large File Processing**: Efficiently calculate checksums for large files:
|
|
166
|
+
|
|
167
|
+
```python
|
|
168
|
+
# Large file processing with memory efficiency
|
|
169
|
+
with open('/path/to/large_file.bin', 'rb') as large_file:
|
|
170
|
+
checksum = get_checksum_from_file(large_file, digest_mod=hashlib.sha256)
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
**Multiple Hash Algorithms**: Calculate different checksums for the same file:
|
|
174
|
+
|
|
175
|
+
```python
|
|
176
|
+
algorithms = [
|
|
177
|
+
('MD5', hashlib.md5),
|
|
178
|
+
('SHA1', hashlib.sha1),
|
|
179
|
+
('SHA256', hashlib.sha256),
|
|
180
|
+
]
|
|
181
|
+
|
|
182
|
+
with open('/path/to/file.bin', 'rb') as f:
|
|
183
|
+
checksums = {}
|
|
184
|
+
for name, algo in algorithms:
|
|
185
|
+
f.seek(0) # Reset file pointer
|
|
186
|
+
checksums[name] = get_checksum_from_file(f, digest_mod=algo)
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Path Utilities
|
|
190
|
+
|
|
191
|
+
Functions for path manipulation and validation.
|
|
192
|
+
|
|
193
|
+
## Temporary Files
|
|
194
|
+
|
|
195
|
+
Utilities for managing temporary files and cleanup.
|