synapse-sdk 1.0.0b23__py3-none-any.whl → 2025.9.1__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.

Files changed (37) hide show
  1. synapse_sdk/clients/agent/ray.py +50 -0
  2. synapse_sdk/devtools/docs/docs/api/clients/ray.md +24 -3
  3. synapse_sdk/devtools/docs/docs/api/index.md +5 -5
  4. synapse_sdk/devtools/docs/docs/features/utils/file.md +415 -0
  5. synapse_sdk/devtools/docs/docs/{api → features}/utils/network.md +1 -1
  6. synapse_sdk/devtools/docs/docs/plugins/export-plugins.md +140 -0
  7. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/clients/ray.md +24 -3
  8. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/index.md +5 -5
  9. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/index.md +5 -5
  10. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/features/utils/file.md +415 -0
  11. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/{api → features}/utils/network.md +1 -1
  12. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/export-plugins.md +138 -0
  13. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/plugins/plugins.md +48 -2
  14. synapse_sdk/devtools/docs/sidebars.ts +10 -10
  15. synapse_sdk/plugins/categories/export/templates/plugin/__init__.py +17 -2
  16. synapse_sdk/utils/file/__init__.py +39 -0
  17. synapse_sdk/utils/file/archive.py +32 -0
  18. synapse_sdk/utils/file/checksum.py +56 -0
  19. synapse_sdk/utils/file/chunking.py +31 -0
  20. synapse_sdk/utils/file/download.py +124 -0
  21. synapse_sdk/utils/file/encoding.py +40 -0
  22. synapse_sdk/utils/file/io.py +22 -0
  23. synapse_sdk/utils/file/video/__init__.py +29 -0
  24. synapse_sdk/utils/file/video/transcode.py +307 -0
  25. {synapse_sdk-1.0.0b23.dist-info → synapse_sdk-2025.9.1.dist-info}/METADATA +3 -2
  26. {synapse_sdk-1.0.0b23.dist-info → synapse_sdk-2025.9.1.dist-info}/RECORD +35 -26
  27. synapse_sdk/devtools/docs/docs/api/utils/file.md +0 -195
  28. synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/api/utils/file.md +0 -195
  29. /synapse_sdk/devtools/docs/docs/{api → features}/utils/storage.md +0 -0
  30. /synapse_sdk/devtools/docs/docs/{api → features}/utils/types.md +0 -0
  31. /synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/{api → features}/utils/storage.md +0 -0
  32. /synapse_sdk/devtools/docs/i18n/ko/docusaurus-plugin-content-docs/current/{api → features}/utils/types.md +0 -0
  33. /synapse_sdk/utils/{file.py → file.py.backup} +0 -0
  34. {synapse_sdk-1.0.0b23.dist-info → synapse_sdk-2025.9.1.dist-info}/WHEEL +0 -0
  35. {synapse_sdk-1.0.0b23.dist-info → synapse_sdk-2025.9.1.dist-info}/entry_points.txt +0 -0
  36. {synapse_sdk-1.0.0b23.dist-info → synapse_sdk-2025.9.1.dist-info}/licenses/LICENSE +0 -0
  37. {synapse_sdk-1.0.0b23.dist-info → synapse_sdk-2025.9.1.dist-info}/top_level.txt +0 -0
@@ -213,6 +213,7 @@ class Exporter(BaseExporter):
213
213
  - **before_convert()**: Pre-process data before conversion
214
214
  - **after_convert()**: Post-process data after conversion
215
215
  - **process_file_saving()**: Custom file saving logic
216
+ - **additional_file_saving()**: Save additional files after processing all export items
216
217
 
217
218
  ### Helper Methods
218
219
 
@@ -225,6 +226,145 @@ class Exporter(BaseExporter):
225
226
  - Logging via `self.run.log_message()` and other run methods
226
227
  - Error handling and metrics collection via self.run methods
227
228
 
229
+ ## Additional File Saving
230
+
231
+ The `additional_file_saving()` method is called after all export items have been processed and is designed for saving files that depend on the collective data from all processed items. This is useful for creating:
232
+
233
+ - Metadata files (e.g., dataset statistics, class mappings)
234
+ - Configuration files (e.g., dataset.yaml for YOLO, classes.txt)
235
+ - Summary files (e.g., export reports, processing logs)
236
+ - Index files (e.g., file lists, directory structures)
237
+
238
+ ### Method Signature
239
+
240
+ ```python
241
+ def additional_file_saving(self, unique_export_path):
242
+ """Save additional files after processing all export items.
243
+
244
+ This method is called after the main export loop completes and is intended
245
+ for saving files that need to be created based on the collective data from
246
+ all processed export items (e.g., metadata files, configuration files,
247
+ summary files, etc.).
248
+
249
+ Args:
250
+ unique_export_path (str): The unique export directory path where
251
+ additional files should be saved.
252
+ """
253
+ pass
254
+ ```
255
+
256
+ ### Example Usage
257
+
258
+ ```python
259
+ class YOLOExporter(BaseExporter):
260
+ def __init__(self, run, export_items, path_root, **params):
261
+ super().__init__(run, export_items, path_root, **params)
262
+ self.class_names = set()
263
+ self.dataset_stats = {
264
+ 'total_images': 0,
265
+ 'total_annotations': 0,
266
+ 'class_distribution': {}
267
+ }
268
+
269
+ def convert_data(self, data):
270
+ # Track classes and stats during conversion
271
+ for annotation in data.get('annotations', []):
272
+ class_name = annotation['class_name']
273
+ self.class_names.add(class_name)
274
+ self.dataset_stats['class_distribution'][class_name] = \
275
+ self.dataset_stats['class_distribution'].get(class_name, 0) + 1
276
+
277
+ self.dataset_stats['total_images'] += 1
278
+ self.dataset_stats['total_annotations'] += len(data.get('annotations', []))
279
+
280
+ return data # ... rest of conversion logic
281
+
282
+ def additional_file_saving(self, unique_export_path):
283
+ """Save YOLO configuration and metadata files."""
284
+ data_dir = Path(unique_export_path) / 'data'
285
+ data_dir.mkdir(exist_ok=True)
286
+
287
+ # 1. Save classes.txt file
288
+ classes_file = data_dir / 'classes.txt'
289
+ with classes_file.open('w') as f:
290
+ for class_name in sorted(self.class_names):
291
+ f.write(f"{class_name}\n")
292
+ self.run.log_message(f"Saved classes file: {classes_file}")
293
+
294
+ # 2. Save dataset.yaml file
295
+ dataset_config = {
296
+ 'path': str(unique_export_path),
297
+ 'train': 'images',
298
+ 'val': 'images',
299
+ 'names': {i: name for i, name in enumerate(sorted(self.class_names))}
300
+ }
301
+
302
+ dataset_file = data_dir / 'dataset.yaml'
303
+ with dataset_file.open('w') as f:
304
+ yaml.dump(dataset_config, f, default_flow_style=False)
305
+ self.run.log_message(f"Saved dataset config: {dataset_file}")
306
+
307
+ # 3. Save export statistics
308
+ stats_file = data_dir / 'export_stats.json'
309
+ with stats_file.open('w') as f:
310
+ json.dump(self.dataset_stats, f, indent=2)
311
+ self.run.log_message(f"Saved export statistics: {stats_file}")
312
+ ```
313
+
314
+ ### Common Use Cases
315
+
316
+ #### 1. Dataset Configuration Files
317
+ ```python
318
+ def additional_file_saving(self, unique_export_path):
319
+ # Create dataset configuration for training frameworks
320
+ config = {
321
+ 'dataset_name': self.params.get('name'),
322
+ 'created_at': datetime.now().isoformat(),
323
+ 'total_samples': len(self.processed_items),
324
+ 'classes': list(self.class_mapping.keys())
325
+ }
326
+
327
+ config_file = Path(unique_export_path) / 'dataset_config.json'
328
+ with config_file.open('w') as f:
329
+ json.dump(config, f, indent=2)
330
+ ```
331
+
332
+ #### 2. Export Summary Reports
333
+ ```python
334
+ def additional_file_saving(self, unique_export_path):
335
+ # Generate export summary
336
+ summary = {
337
+ 'export_info': {
338
+ 'plugin_name': self.__class__.__name__,
339
+ 'export_time': datetime.now().isoformat(),
340
+ 'export_path': str(unique_export_path)
341
+ },
342
+ 'statistics': self.get_export_statistics(),
343
+ 'errors': self.get_error_summary()
344
+ }
345
+
346
+ summary_file = Path(unique_export_path) / 'export_summary.json'
347
+ with summary_file.open('w') as f:
348
+ json.dump(summary, f, indent=2)
349
+ ```
350
+
351
+ #### 3. Index and Manifest Files
352
+ ```python
353
+ def additional_file_saving(self, unique_export_path):
354
+ # Create file index for processed items
355
+ file_index = []
356
+ for item in self.processed_items:
357
+ file_index.append({
358
+ 'original_file': item['original_filename'],
359
+ 'json_file': f"{item['stem']}.json",
360
+ 'processed_at': item['timestamp']
361
+ })
362
+
363
+ index_file = Path(unique_export_path) / 'file_index.json'
364
+ with index_file.open('w') as f:
365
+ json.dump(file_index, f, indent=2)
366
+ ```
367
+
228
368
  ## Key Features
229
369
 
230
370
  - **Progress Tracking**: Built-in progress monitoring with `run.set_progress()`
@@ -14,7 +14,7 @@ Apache Ray 클러스터 관리 및 모니터링 기능을 위한 클라이언트
14
14
 
15
15
  ## 주요 기능
16
16
 
17
- - **Job 라이프사이클 관리**: Ray 작업 생성, 모니터링관리
17
+ - **Job 라이프사이클 관리**: Ray 작업 생성, 모니터링, 관리 중지
18
18
  - **실시간 로그 스트리밍**: WebSocket 및 HTTP 기반 로그 테일링
19
19
  - **노드 및 태스크 모니터링**: 클러스터 리소스 및 태스크 실행 모니터링
20
20
  - **Ray Serve 통합**: Ray Serve 애플리케이션 배포 및 관리
@@ -52,6 +52,11 @@ jobs = client.list_jobs()
52
52
  # 특정 작업 세부정보 가져오기
53
53
  job = client.get_job('job-12345')
54
54
 
55
+ # 필요한 경우 실행 중인 작업 중지
56
+ if job['status'] == 'RUNNING':
57
+ result = client.stop_job('job-12345')
58
+ print(f"작업 중지 시작: {result['status']}")
59
+
55
60
  # 실시간으로 로그 스트리밍
56
61
  for log_line in client.tail_job_logs('job-12345'):
57
62
  print(log_line.strip())
@@ -86,6 +91,22 @@ for job in jobs['results']:
86
91
  logs = client.list_job_logs('job-12345')
87
92
  ```
88
93
 
94
+ ### `stop_job(pk)`
95
+
96
+ Ray의 stop_job() API를 사용하여 실행 중인 작업을 정상적으로 중지합니다.
97
+
98
+ ```python
99
+ # 실행 중인 작업 중지
100
+ result = client.stop_job('job-12345')
101
+ print(f"중지 상태: {result['status']}")
102
+
103
+ # 중지 오류 처리
104
+ try:
105
+ client.stop_job('job-12345')
106
+ except ClientError as e:
107
+ print(f"중지 실패: {e}")
108
+ ```
109
+
89
110
  ## 실시간 로그 스트리밍
90
111
 
91
112
  ### `tail_job_logs(pk, stream_timeout=10, protocol='stream')`
@@ -221,7 +242,7 @@ except ClientError as e:
221
242
 
222
243
  ### 일반적인 오류 코드
223
244
 
224
- - **400**: 잘못된 매개변수 (job ID, timeout, protocol)
245
+ - **400**: 잘못된 매개변수 (job ID, timeout, protocol) 또는 이미 종료 상태인 작업
225
246
  - **404**: 리소스를 찾을 수 없음 (job, node, task, application)
226
247
  - **408**: 연결 또는 읽기 timeout
227
248
  - **429**: 스트림 제한 초과
@@ -318,4 +339,4 @@ RayClient는 적절한 스레드 안전 메커니즘을 통해 동시 사용을
318
339
 
319
340
  - [AgentClient](./agent.md) - Agent 전용 작업을 위한 클라이언트
320
341
  - [BaseClient](./base.md) - 기본 클라이언트 구현
321
- - [Network Utilities](../utils/network.md) - 스트리밍 및 유효성 검사 유틸리티
342
+ - [Network Utilities](../../features/utils/network.md) - 스트리밍 및 유효성 검사 유틸리티
@@ -22,13 +22,13 @@ Synapse SDK API는 다음 주요 모듈로 구성됩니다:
22
22
 
23
23
  핵심 플러그인 시스템 컴포넌트들.
24
24
 
25
- ### [유틸리티](./utils/file.md)
25
+ ### [유틸리티](../features/utils/file.md)
26
26
  도우미 함수 및 유틸리티들.
27
27
 
28
- - **[파일 유틸](./utils/file.md)** - 파일 작업 및 처리
29
- - **[네트워크](./utils/network.md)** - 스트리밍, 검증 및 연결 관리
30
- - **[스토리지](./utils/storage.md)** - 스토리지 제공자들 (S3, GCS, SFTP)
31
- - **[타입](./utils/types.md)** - 커스텀 타입 및 필드
28
+ - **[파일 유틸](../features/utils/file.md)** - 파일 작업 및 처리
29
+ - **[네트워크](../features/utils/network.md)** - 스트리밍, 검증 및 연결 관리
30
+ - **[스토리지](../features/utils/storage.md)** - 스토리지 제공자들 (S3, GCS, SFTP)
31
+ - **[타입](../features/utils/types.md)** - 커스텀 타입 및 필드
32
32
 
33
33
  ## 빠른 참조
34
34
 
@@ -8,17 +8,17 @@ sidebar_position: 5
8
8
 
9
9
  이 섹션에서는 Synapse SDK에서 제공하는 주요 기능과 기능성을 다룹니다.
10
10
 
11
- ## [플러그인 시스템](./plugins/index.md)
11
+ ## [플러그인 시스템](../plugins/plugins.md)
12
12
 
13
13
  ML 워크플로우 구축 및 관리를 위한 포괄적인 플러그인 프레임워크입니다.
14
14
 
15
- - **[플러그인 카테고리](./plugins/index.md#plugin-categories)** - 신경망, 내보내기, 업로드, 스마트 도구 및 검증 플러그인
16
- - **[실행 방법](./plugins/index.md#execution-methods)** - Job, Task 및 REST API 실행 모드
17
- - **[개발 가이드](./plugins/index.md#creating-plugins)** - 커스텀 플러그인 생성, 테스트 및 배포
15
+ - **[플러그인 카테고리](../plugins/plugins.md#플러그인-카테고리)** - 신경망, 내보내기, 업로드, 스마트 도구 및 검증 플러그인
16
+ - **[실행 방법](../plugins/plugins.md)** - Job, Task 및 REST API 실행 모드
17
+ - **[개발 가이드](../plugins/plugins.md)** - 커스텀 플러그인 생성, 테스트 및 배포
18
18
 
19
19
  ## [데이터 변환기](./converters/index.md)
20
20
 
21
21
  컴퓨터 비전 데이터셋을 위한 포괄적인 데이터 형식 변환 유틸리티입니다.
22
22
 
23
23
  - **[형식 변환기](./converters/index.md)** - DM, COCO, Pascal VOC 및 YOLO 형식 간 변환
24
- - **[버전 마이그레이션](./converters/index.md#dm-version-converter)** - 버전 간 DM 데이터셋 마이그레이션
24
+ - **[버전 마이그레이션](./converters/index.md)** - 버전 간 DM 데이터셋 마이그레이션
@@ -0,0 +1,415 @@
1
+ ---
2
+ id: file
3
+ title: 파일 유틸리티
4
+ sidebar_position: 1
5
+ ---
6
+
7
+ # 파일 유틸리티
8
+
9
+ 더 나은 유지보수성과 기능성을 위해 모듈형 구조로 구성된 포괄적인 파일 작업 및 처리 유틸리티입니다.
10
+
11
+ ## 모듈 개요
12
+
13
+ 파일 유틸리티는 다양한 작업을 위한 전문화된 모듈로 구성된 모듈형 구조로 리팩토링되었습니다:
14
+
15
+ - **`synapse_sdk.utils.file.archive`** - ZIP 아카이브 생성 및 추출
16
+ - **`synapse_sdk.utils.file.checksum`** - 파일 해시 계산 및 검증
17
+ - **`synapse_sdk.utils.file.chunking`** - 메모리 효율적인 청크 단위 파일 읽기
18
+ - **`synapse_sdk.utils.file.download`** - 비동기 지원을 포함한 파일 다운로드 유틸리티
19
+ - **`synapse_sdk.utils.file.encoding`** - Base64 인코딩 및 파일 형식 처리
20
+ - **`synapse_sdk.utils.file.io`** - JSON/YAML 파일용 일반 I/O 작업
21
+ - **`synapse_sdk.utils.file.video`** - 비디오 트랜스코딩 및 형식 변환
22
+
23
+ ### 하위 호환성
24
+
25
+ 모든 함수는 메인 모듈 임포트를 통해 여전히 액세스할 수 있습니다:
26
+
27
+ ```python
28
+ # 두 방법 모두 동일하게 작동합니다
29
+ from synapse_sdk.utils.file import read_file_in_chunks, download_file
30
+ from synapse_sdk.utils.file.chunking import read_file_in_chunks
31
+ from synapse_sdk.utils.file.download import download_file
32
+ ```
33
+
34
+ ## 아카이브 작업
35
+
36
+ ZIP 아카이브를 생성하고 추출하는 함수입니다.
37
+
38
+ ```python
39
+ from synapse_sdk.utils.file.archive import archive, unarchive
40
+
41
+ # 아카이브 생성
42
+ archive('/path/to/directory', '/path/to/output.zip')
43
+
44
+ # 아카이브 추출
45
+ unarchive('/path/to/archive.zip', '/path/to/extract/directory')
46
+ ```
47
+
48
+ ## 청크 파일 작업
49
+
50
+ ### read_file_in_chunks
51
+
52
+ 효율적인 메모리 사용을 위해 파일을 청크 단위로 읽습니다. 대용량 파일이나 업로드 또는 해싱을 위해 파일을 청크 단위로 처리할 때 특히 유용합니다.
53
+
54
+ ```python
55
+ from synapse_sdk.utils.file.chunking import read_file_in_chunks
56
+
57
+ # 기본 50MB 청크로 파일 읽기
58
+ for chunk in read_file_in_chunks('/path/to/large_file.bin'):
59
+ process_chunk(chunk)
60
+
61
+ # 사용자 정의 청크 크기로 읽기 (10MB)
62
+ for chunk in read_file_in_chunks('/path/to/file.bin', chunk_size=1024*1024*10):
63
+ upload_chunk(chunk)
64
+ ```
65
+
66
+ **매개변수:**
67
+
68
+ - `file_path` (str | Path): 읽을 파일의 경로
69
+ - `chunk_size` (int, 선택사항): 각 청크의 바이트 크기. 기본값은 50MB (52,428,800 바이트)
70
+
71
+ **반환값:**
72
+
73
+ - 파일 내용 청크를 바이트로 생성하는 제너레이터
74
+
75
+ **예외:**
76
+
77
+ - `FileNotFoundError`: 파일이 존재하지 않는 경우
78
+ - `PermissionError`: 권한으로 인해 파일을 읽을 수 없는 경우
79
+ - `OSError`: 파일 읽기 중 OS 수준 오류가 발생하는 경우
80
+
81
+ ### 사용 사례
82
+
83
+ **대용량 파일 처리**: 메모리에 맞지 않는 파일을 효율적으로 처리:
84
+
85
+ ```python
86
+ import hashlib
87
+
88
+ def calculate_hash_for_large_file(file_path):
89
+ hash_md5 = hashlib.md5()
90
+ for chunk in read_file_in_chunks(file_path):
91
+ hash_md5.update(chunk)
92
+ return hash_md5.hexdigest()
93
+ ```
94
+
95
+ **청크 업로드 통합**: `CoreClientMixin.create_chunked_upload` 메서드와 원활하게 통합:
96
+
97
+ ```python
98
+ from synapse_sdk.clients.backend.core import CoreClientMixin
99
+
100
+ client = CoreClientMixin(base_url='https://api.example.com')
101
+ result = client.create_chunked_upload('/path/to/large_file.zip')
102
+ ```
103
+
104
+ **모범 사례:**
105
+
106
+ - 최적의 업로드 성능을 위해 기본 청크 크기(50MB) 사용
107
+ - 사용 가능한 메모리와 네트워크 조건에 따라 청크 크기 조정
108
+ - 매우 큰 파일(>1GB)의 경우 더 나은 진행률 추적을 위해 작은 청크 사용 고려
109
+ - 파일 작업 시 항상 예외 처리
110
+
111
+ ## 체크섬 함수
112
+
113
+ ### calculate_checksum
114
+
115
+ 일반 파일의 체크섬을 계산합니다:
116
+
117
+ ```python
118
+ from synapse_sdk.utils.file.checksum import calculate_checksum
119
+
120
+ checksum = calculate_checksum('/path/to/file.bin')
121
+ ```
122
+
123
+ ### get_checksum_from_file
124
+
125
+ Django 의존성 없이 파일형 객체의 체크섬을 계산합니다. 이 함수는 `read()` 메서드가 있는 모든 파일형 객체와 함께 작동하므로 Django의 File 객체, BytesIO, StringIO 및 일반 파일 객체와 호환됩니다.
126
+
127
+ ```python
128
+ import hashlib
129
+ from io import BytesIO
130
+ from synapse_sdk.utils.file.checksum import get_checksum_from_file
131
+
132
+ # BytesIO를 사용한 기본 사용법 (기본값은 SHA1)
133
+ data = BytesIO(b'Hello, world!')
134
+ checksum = get_checksum_from_file(data)
135
+ print(checksum) # 16진수 문자열로 된 SHA1 해시
136
+
137
+ # 다른 해시 알고리즘 사용
138
+ checksum_md5 = get_checksum_from_file(data, digest_mod=hashlib.md5)
139
+ checksum_sha256 = get_checksum_from_file(data, digest_mod=hashlib.sha256)
140
+
141
+ # 실제 파일 객체와 함께
142
+ with open('/path/to/file.txt', 'rb') as f:
143
+ checksum = get_checksum_from_file(f)
144
+ ```
145
+
146
+ **매개변수:**
147
+
148
+ - `file` (IO[Any]): 청크 단위 읽기를 지원하는 read() 메서드가 있는 파일형 객체
149
+ - `digest_mod` (Callable[[], Any], 선택사항): hashlib의 해시 알고리즘. 기본값은 `hashlib.sha1`
150
+
151
+ **반환값:**
152
+
153
+ - `str`: 파일 내용의 16진수 다이제스트
154
+
155
+ **주요 기능:**
156
+
157
+ - **메모리 효율성**: 대용량 파일 처리를 위해 4KB 청크로 파일 읽기
158
+ - **자동 파일 포인터 재설정**: 파일 객체가 시킹을 지원하는 경우 처음으로 재설정
159
+ - **텍스트/바이너리 불가지론**: 텍스트(StringIO)와 바이너리(BytesIO) 파일 객체 모두 처리
160
+ - **Django 의존성 없음**: Django 없이 작동하면서 Django File 객체와 호환
161
+ - **유연한 해시 알고리즘**: 모든 hashlib 알고리즘 지원(SHA1, SHA256, MD5 등)
162
+
163
+ ## 다운로드 함수
164
+
165
+ 동기 및 비동기 지원을 모두 포함한 URL에서 파일을 다운로드하는 유틸리티입니다.
166
+
167
+ ```python
168
+ from synapse_sdk.utils.file.download import download_file, adownload_file
169
+
170
+ # 동기 다운로드
171
+ local_path = download_file(url, destination)
172
+
173
+ # 비동기 다운로드
174
+ import asyncio
175
+ local_path = await adownload_file(url, destination)
176
+
177
+ # 여러 파일의 URL을 경로로 변환
178
+ from synapse_sdk.utils.file.download import files_url_to_path
179
+ paths = files_url_to_path(url_list, destination_directory)
180
+ ```
181
+
182
+ ## 인코딩 함수
183
+
184
+ 파일용 Base64 인코딩 유틸리티입니다.
185
+
186
+ ```python
187
+ from synapse_sdk.utils.file.encoding import convert_file_to_base64
188
+
189
+ # 파일을 base64로 변환
190
+ base64_data = convert_file_to_base64('/path/to/file.jpg')
191
+ ```
192
+
193
+ ## I/O 함수
194
+
195
+ 구조화된 데이터 파일용 일반 I/O 작업입니다.
196
+
197
+ ```python
198
+ from synapse_sdk.utils.file.io import get_dict_from_file, get_temp_path
199
+
200
+ # JSON 또는 YAML 파일에서 딕셔너리 로드
201
+ config = get_dict_from_file('/path/to/config.json')
202
+ settings = get_dict_from_file('/path/to/settings.yaml')
203
+
204
+ # 임시 파일 경로 얻기
205
+ temp_path = get_temp_path()
206
+ temp_subpath = get_temp_path('subdir/file.tmp')
207
+ ```
208
+
209
+ ## 비디오 트랜스코딩
210
+
211
+ 형식 변환, 압축 및 최적화를 위해 FFmpeg를 사용하는 고급 비디오 트랜스코딩 기능입니다.
212
+
213
+ ### 요구사항
214
+
215
+ - **ffmpeg-python**: `pip install ffmpeg-python`
216
+ - **FFmpeg**: 시스템에 설치되어 PATH에서 사용 가능해야 함
217
+
218
+ ### 지원되는 비디오 형식
219
+
220
+ 비디오 모듈은 다양한 입력 형식을 지원합니다:
221
+ - **MP4** (.mp4, .m4v)
222
+ - **AVI** (.avi)
223
+ - **MOV** (.mov)
224
+ - **MKV** (.mkv)
225
+ - **WebM** (.webm)
226
+ - **FLV** (.flv)
227
+ - **WMV** (.wmv)
228
+ - **MPEG** (.mpeg, .mpg)
229
+ - **3GP** (.3gp)
230
+ - **OGV** (.ogv)
231
+
232
+ ### 핵심 함수
233
+
234
+ #### validate_video_format
235
+
236
+ 파일이 지원되는 비디오 형식인지 확인합니다:
237
+
238
+ ```python
239
+ from synapse_sdk.utils.file.video.transcode import validate_video_format
240
+
241
+ if validate_video_format('video.mp4'):
242
+ print("지원되는 형식")
243
+ else:
244
+ print("지원되지 않는 형식")
245
+ ```
246
+
247
+ #### get_video_info
248
+
249
+ 비디오 파일에서 메타데이터를 추출합니다:
250
+
251
+ ```python
252
+ from synapse_sdk.utils.file.video.transcode import get_video_info
253
+
254
+ info = get_video_info('input.mp4')
255
+ print(f"재생시간: {info['duration']} 초")
256
+ print(f"해상도: {info['width']}x{info['height']}")
257
+ print(f"비디오 코덱: {info['video_codec']}")
258
+ print(f"오디오 코덱: {info['audio_codec']}")
259
+ print(f"FPS: {info['fps']}")
260
+ ```
261
+
262
+ #### transcode_video
263
+
264
+ 광범위한 구성 옵션을 가진 주요 트랜스코딩 함수:
265
+
266
+ ```python
267
+ from synapse_sdk.utils.file.video.transcode import transcode_video, TranscodeConfig
268
+ from pathlib import Path
269
+
270
+ # 기본 설정으로 기본 트랜스코딩
271
+ output_path = transcode_video('input.avi', 'output.mp4')
272
+
273
+ # 사용자 정의 구성
274
+ config = TranscodeConfig(
275
+ vcodec='libx264', # 비디오 코덱
276
+ preset='fast', # 인코딩 속도 vs 품질
277
+ crf=20, # 품질 (낮을수록 품질 향상)
278
+ acodec='aac', # 오디오 코덱
279
+ audio_bitrate='128k', # 오디오 비트레이트
280
+ resolution='1920x1080', # 출력 해상도
281
+ fps=30, # 프레임 레이트
282
+ start_time=10.0, # 10초부터 시작
283
+ duration=60.0 # 60초만 처리
284
+ )
285
+
286
+ output_path = transcode_video('input.mkv', 'output.mp4', config)
287
+ ```
288
+
289
+ #### TranscodeConfig 옵션
290
+
291
+ ```python
292
+ @dataclass
293
+ class TranscodeConfig:
294
+ vcodec: str = 'libx264' # 비디오 코덱 (libx264, libx265 등)
295
+ preset: str = 'medium' # 인코딩 프리셋 (fast, medium, slow)
296
+ crf: int = 28 # 품질 팩터 (0-51, 낮을수록 품질 향상)
297
+ acodec: str = 'aac' # 오디오 코덱 (aac, opus 등)
298
+ audio_bitrate: str = '128k' # 오디오 비트레이트
299
+ movflags: str = '+faststart' # MP4 최적화 플래그
300
+ resolution: Optional[str] = None # 출력 해상도 (예: '1920x1080')
301
+ fps: Optional[int] = None # 출력 프레임 레이트
302
+ start_time: Optional[float] = None # 시작 시간(초)
303
+ duration: Optional[float] = None # 처리할 재생시간(초)
304
+ ```
305
+
306
+ #### 진행률 콜백 지원
307
+
308
+ 콜백 함수로 트랜스코딩 진행률을 모니터링합니다:
309
+
310
+ ```python
311
+ def progress_callback(progress_percent):
312
+ print(f"진행률: {progress_percent:.1f}%")
313
+
314
+ output_path = transcode_video(
315
+ 'input.mp4',
316
+ 'output.mp4',
317
+ progress_callback=progress_callback
318
+ )
319
+ ```
320
+
321
+ #### optimize_for_web
322
+
323
+ 사전 정의된 설정으로 빠른 웹 최적화:
324
+
325
+ ```python
326
+ from synapse_sdk.utils.file.video.transcode import optimize_for_web
327
+
328
+ # 빠른 시작으로 웹 스트리밍을 위해 최적화
329
+ web_video = optimize_for_web('input.mov', 'web_output.mp4')
330
+ ```
331
+
332
+ 이 함수는 최적화된 설정을 사용합니다:
333
+ - 빠른 인코딩 프리셋
334
+ - 웹 친화적 압축 (CRF 23)
335
+ - 스트리밍용 빠른 시작 플래그
336
+ - 더 나은 웹 호환성을 위한 프래그먼트 키프레임
337
+
338
+ ### 오류 처리
339
+
340
+ 비디오 모듈은 특정 예외를 제공합니다:
341
+
342
+ ```python
343
+ from synapse_sdk.utils.file.video.transcode import (
344
+ VideoTranscodeError,
345
+ UnsupportedFormatError,
346
+ FFmpegNotFoundError,
347
+ TranscodingFailedError
348
+ )
349
+
350
+ try:
351
+ transcode_video('input.xyz', 'output.mp4')
352
+ except UnsupportedFormatError:
353
+ print("입력 형식이 지원되지 않음")
354
+ except FFmpegNotFoundError:
355
+ print("FFmpeg가 설치되지 않음")
356
+ except TranscodingFailedError as e:
357
+ print(f"트랜스코딩 실패: {e}")
358
+ ```
359
+
360
+ ### 고급 사용 예제
361
+
362
+ **배치 처리**:
363
+
364
+ ```python
365
+ import os
366
+ from pathlib import Path
367
+
368
+ input_dir = Path('/path/to/videos')
369
+ output_dir = Path('/path/to/output')
370
+
371
+ for video_file in input_dir.glob('*'):
372
+ if validate_video_format(video_file):
373
+ output_file = output_dir / f"{video_file.stem}.mp4"
374
+ try:
375
+ transcode_video(video_file, output_file)
376
+ print(f"처리됨: {video_file.name}")
377
+ except VideoTranscodeError as e:
378
+ print(f"{video_file.name} 처리 실패: {e}")
379
+ ```
380
+
381
+ **품질 최적화**:
382
+
383
+ ```python
384
+ # 보관용 고품질
385
+ archive_config = TranscodeConfig(
386
+ preset='slow',
387
+ crf=18,
388
+ audio_bitrate='256k'
389
+ )
390
+
391
+ # 모바일용 작은 크기
392
+ mobile_config = TranscodeConfig(
393
+ preset='fast',
394
+ crf=28,
395
+ resolution='1280x720',
396
+ audio_bitrate='96k'
397
+ )
398
+
399
+ # 다른 구성 적용
400
+ archive_output = transcode_video(input_file, 'archive.mp4', archive_config)
401
+ mobile_output = transcode_video(input_file, 'mobile.mp4', mobile_config)
402
+ ```
403
+
404
+ **비디오 클리핑**:
405
+
406
+ ```python
407
+ # 1분부터 시작하여 30초 클립 추출
408
+ clip_config = TranscodeConfig(
409
+ start_time=60.0, # 1분에서 시작
410
+ duration=30.0, # 30초 추출
411
+ crf=20 # 고품질
412
+ )
413
+
414
+ clip = transcode_video('long_video.mp4', 'clip.mp4', clip_config)
415
+ ```
@@ -373,6 +373,6 @@ production_limits = StreamLimits(
373
373
 
374
374
  ## 참고
375
375
 
376
- - [RayClient](../clients/ray.md) - 네트워크 유틸리티의 주요 소비자
376
+ - [RayClient](../../api/clients/ray.md) - 네트워크 유틸리티의 주요 소비자
377
377
  - [File Utils](./file.md) - 파일 작업 및 처리
378
378
  - [Storage](./storage.md) - Storage 제공자