tamar-file-hub-client 0.1.9__tar.gz → 0.2.1__tar.gz
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 tamar-file-hub-client might be problematic. Click here for more details.
- {tamar_file_hub_client-0.1.9/tamar_file_hub_client.egg-info → tamar_file_hub_client-0.2.1}/PKG-INFO +189 -2
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/README.md +187 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/gen/file_service_pb2.py +9 -9
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/protos/file_service.proto +4 -1
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/schemas/file.py +3 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/file/async_blob_service.py +3 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/file/sync_blob_service.py +3 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/setup.py +2 -2
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1/tamar_file_hub_client.egg-info}/PKG-INFO +189 -2
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/tamar_file_hub_client.egg-info/requires.txt +1 -1
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/MANIFEST.in +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/client.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/enums/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/enums/export_format.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/enums/role.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/enums/upload_mode.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/errors/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/errors/exceptions.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/py.typed +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/async_client.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/gen/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/gen/file_service_pb2_grpc.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/gen/folder_service_pb2.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/gen/folder_service_pb2_grpc.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/gen/taple_service_pb2.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/gen/taple_service_pb2_grpc.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/interceptors.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/protos/folder_service.proto +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/protos/taple_service.proto +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/sync_client.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/schemas/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/schemas/context.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/schemas/folder.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/schemas/taple.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/file/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/file/async_file_service.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/file/base_file_service.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/file/sync_file_service.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/folder/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/folder/async_folder_service.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/folder/sync_folder_service.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/taple/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/taple/async_taple_service.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/taple/base_taple_service.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/taple/idempotent_taple_mixin.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/taple/sync_taple_service.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/__init__.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/converter.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/download_helper.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/file_utils.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/idempotency.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/ip_detector.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/logging.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/mime_extension_mapper.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/retry.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/smart_retry.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/upload_helper.py +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/setup.cfg +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/tamar_file_hub_client.egg-info/SOURCES.txt +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/tamar_file_hub_client.egg-info/dependency_links.txt +0 -0
- {tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/tamar_file_hub_client.egg-info/top_level.txt +0 -0
{tamar_file_hub_client-0.1.9/tamar_file_hub_client.egg-info → tamar_file_hub_client-0.2.1}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tamar-file-hub-client
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: A Python SDK for gRPC-based file management system
|
|
5
5
|
Home-page: https://github.com/Tamar-Edge-AI/file-hub-client
|
|
6
6
|
Author: Oscar Ou
|
|
@@ -25,7 +25,7 @@ Requires-Python: >=3.8
|
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
Requires-Dist: grpcio>=1.67.1
|
|
27
27
|
Requires-Dist: grpcio-tools>=1.67.1
|
|
28
|
-
Requires-Dist: protobuf>=
|
|
28
|
+
Requires-Dist: protobuf>=5.29.4
|
|
29
29
|
Requires-Dist: pydantic>=2.0.0
|
|
30
30
|
Requires-Dist: typing-extensions>=4.0.0; python_version < "3.10"
|
|
31
31
|
Requires-Dist: requests>=2.28.0
|
|
@@ -63,6 +63,7 @@ Dynamic: summary
|
|
|
63
63
|
- 📝 **类型注解**:完整的类型提示支持
|
|
64
64
|
- 🧩 **模块化设计**:清晰的代码结构,易于扩展
|
|
65
65
|
- 🎨 **图片和视频压缩**:支持多种规格的媒体文件压缩变体生成和管理
|
|
66
|
+
- 📊 **批量状态查询**:支持批量查询文件的上传、压缩、备份同步状态
|
|
66
67
|
- 🏗️ **分层服务架构**:文件服务分为传统文件(blob)和自定义类型(结构化数据),每种类型独立服务,语义清晰
|
|
67
68
|
- 🔧 **环境变量配置**:支持通过环境变量配置所有参数
|
|
68
69
|
- 👤 **用户上下文管理**:支持区分资源所有权(ownership)和操作者(operator)
|
|
@@ -214,6 +215,7 @@ File Hub Client 采用分层服务架构,将文件服务按类型和语义进
|
|
|
214
215
|
- 支持临时文件上传
|
|
215
216
|
- **媒体文件压缩**:支持图片和视频的多规格压缩变体生成
|
|
216
217
|
- **压缩管理**:获取压缩状态、管理变体、触发重新压缩
|
|
218
|
+
- **批量文件状态查询**:一次性查询多个文件的上传、压缩、同步状态
|
|
217
219
|
- 适用类型:PDF、图片、视频、音频、压缩包等
|
|
218
220
|
- **file_service**: 处理文件元数据操作(所有类型通用)
|
|
219
221
|
- 获取、重命名、删除文件
|
|
@@ -253,6 +255,12 @@ File Hub Client 采用分层服务架构,将文件服务按类型和语义进
|
|
|
253
255
|
- `GetVariantsResponse`: 获取变体响应
|
|
254
256
|
- `RecompressionResponse`: 重新压缩响应
|
|
255
257
|
- `VariantDownloadUrlResponse`: 变体下载URL响应
|
|
258
|
+
- `BatchFileStatusResponse`: 批量文件状态响应
|
|
259
|
+
- `FileStatusInfo`: 单个文件状态信息
|
|
260
|
+
- `FileStatusDetails`: 文件状态详细信息
|
|
261
|
+
- `FileUploadStatus`: 文件上传状态枚举
|
|
262
|
+
- `FileCompressionStatus`: 文件压缩状态枚举
|
|
263
|
+
- `FileSyncStatus`: 文件同步状态枚举
|
|
256
264
|
|
|
257
265
|
- **folder.py**: 文件夹相关的数据模型
|
|
258
266
|
- `FolderInfo`: 文件夹信息
|
|
@@ -1031,6 +1039,184 @@ with TamarFileHubClient() as client:
|
|
|
1031
1039
|
- 支持重新压缩以应用新的压缩设置
|
|
1032
1040
|
- 批量状态查询减少网络请求
|
|
1033
1041
|
|
|
1042
|
+
### 批量文件状态查询
|
|
1043
|
+
|
|
1044
|
+
File Hub Client 提供了高效的批量文件状态查询功能,可以一次性获取多个文件的上传、压缩、同步状态:
|
|
1045
|
+
|
|
1046
|
+
#### 基础批量查询
|
|
1047
|
+
|
|
1048
|
+
```python
|
|
1049
|
+
from file_hub_client import AsyncTamarFileHubClient
|
|
1050
|
+
|
|
1051
|
+
async with AsyncTamarFileHubClient() as client:
|
|
1052
|
+
client.set_user_context(org_id="123", user_id="456")
|
|
1053
|
+
|
|
1054
|
+
# 批量查询多个文件的状态
|
|
1055
|
+
file_ids = ["file-id-1", "file-id-2", "file-id-3"]
|
|
1056
|
+
response = await client.blobs.batch_get_file_status(
|
|
1057
|
+
file_ids=file_ids,
|
|
1058
|
+
include_details=False # 是否包含详细信息,默认False
|
|
1059
|
+
)
|
|
1060
|
+
|
|
1061
|
+
print(f"查询时间戳: {response.timestamp}")
|
|
1062
|
+
print(f"缓存命中数量: {response.cache_hit_count}")
|
|
1063
|
+
print(f"查询到 {len(response.statuses)} 个文件状态")
|
|
1064
|
+
|
|
1065
|
+
for status in response.statuses:
|
|
1066
|
+
print(f"文件ID: {status.file_id}")
|
|
1067
|
+
print(f" 上传状态: {status.upload_status.value}")
|
|
1068
|
+
print(f" 压缩状态: {status.compression_status.value}")
|
|
1069
|
+
print(f" 同步状态: {status.sync_status.value}")
|
|
1070
|
+
|
|
1071
|
+
if status.error_message:
|
|
1072
|
+
print(f" 错误信息: {status.error_message}")
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1075
|
+
#### 详细信息查询
|
|
1076
|
+
|
|
1077
|
+
```python
|
|
1078
|
+
# 查询详细状态信息
|
|
1079
|
+
detailed_response = await client.blobs.batch_get_file_status(
|
|
1080
|
+
file_ids=file_ids,
|
|
1081
|
+
include_details=True # 包含详细信息
|
|
1082
|
+
)
|
|
1083
|
+
|
|
1084
|
+
for status in detailed_response.statuses:
|
|
1085
|
+
print(f"文件ID: {status.file_id}")
|
|
1086
|
+
print(f" 上传状态: {status.upload_status.value}")
|
|
1087
|
+
print(f" 压缩状态: {status.compression_status.value}")
|
|
1088
|
+
print(f" 同步状态: {status.sync_status.value}")
|
|
1089
|
+
|
|
1090
|
+
if status.details:
|
|
1091
|
+
print(" 详细信息:")
|
|
1092
|
+
if status.details.file_size:
|
|
1093
|
+
print(f" 文件大小: {status.details.file_size} 字节")
|
|
1094
|
+
if status.details.storage_type:
|
|
1095
|
+
print(f" 存储类型: {status.details.storage_type}")
|
|
1096
|
+
if status.details.storage_region:
|
|
1097
|
+
print(f" 存储区域: {status.details.storage_region}")
|
|
1098
|
+
|
|
1099
|
+
# 压缩相关详细信息
|
|
1100
|
+
if status.details.compression_task_id:
|
|
1101
|
+
print(f" 压缩任务ID: {status.details.compression_task_id}")
|
|
1102
|
+
if status.details.compression_variants_count is not None:
|
|
1103
|
+
print(f" 压缩变体数量: {status.details.compression_variants_count}")
|
|
1104
|
+
if status.details.compression_progress is not None:
|
|
1105
|
+
print(f" 压缩进度: {status.details.compression_progress * 100:.1f}%")
|
|
1106
|
+
|
|
1107
|
+
# 同步相关详细信息
|
|
1108
|
+
if status.details.sync_regions_total is not None:
|
|
1109
|
+
print(f" 同步区域总数: {status.details.sync_regions_total}")
|
|
1110
|
+
if status.details.sync_regions_completed is not None:
|
|
1111
|
+
print(f" 已完成同步区域: {status.details.sync_regions_completed}")
|
|
1112
|
+
if status.details.sync_pending_regions:
|
|
1113
|
+
print(f" 待同步区域: {', '.join(status.details.sync_pending_regions)}")
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
#### 状态筛选和分析
|
|
1117
|
+
|
|
1118
|
+
```python
|
|
1119
|
+
from file_hub_client.schemas import (
|
|
1120
|
+
FileUploadStatus,
|
|
1121
|
+
FileCompressionStatus,
|
|
1122
|
+
FileSyncStatus
|
|
1123
|
+
)
|
|
1124
|
+
|
|
1125
|
+
# 查询文件状态
|
|
1126
|
+
response = await client.blobs.batch_get_file_status(file_ids=file_ids)
|
|
1127
|
+
|
|
1128
|
+
# 筛选出上传失败的文件
|
|
1129
|
+
failed_uploads = [
|
|
1130
|
+
status for status in response.statuses
|
|
1131
|
+
if status.upload_status == FileUploadStatus.UPLOAD_FAILED
|
|
1132
|
+
]
|
|
1133
|
+
|
|
1134
|
+
# 筛选出正在处理的文件
|
|
1135
|
+
processing_files = [
|
|
1136
|
+
status for status in response.statuses
|
|
1137
|
+
if (status.upload_status == FileUploadStatus.UPLOAD_PROCESSING or
|
|
1138
|
+
status.compression_status == FileCompressionStatus.COMPRESSION_PROCESSING or
|
|
1139
|
+
status.sync_status == FileSyncStatus.SYNC_PROCESSING)
|
|
1140
|
+
]
|
|
1141
|
+
|
|
1142
|
+
# 筛选出压缩不适用的文件(非图片/视频)
|
|
1143
|
+
non_compressible_files = [
|
|
1144
|
+
status for status in response.statuses
|
|
1145
|
+
if status.compression_status == FileCompressionStatus.COMPRESSION_NOT_APPLICABLE
|
|
1146
|
+
]
|
|
1147
|
+
|
|
1148
|
+
print(f"上传失败的文件: {len(failed_uploads)} 个")
|
|
1149
|
+
print(f"正在处理的文件: {len(processing_files)} 个")
|
|
1150
|
+
print(f"非媒体文件: {len(non_compressible_files)} 个")
|
|
1151
|
+
```
|
|
1152
|
+
|
|
1153
|
+
#### 同步客户端示例
|
|
1154
|
+
|
|
1155
|
+
```python
|
|
1156
|
+
from file_hub_client import TamarFileHubClient
|
|
1157
|
+
|
|
1158
|
+
with TamarFileHubClient() as client:
|
|
1159
|
+
client.set_user_context(org_id="123", user_id="456")
|
|
1160
|
+
|
|
1161
|
+
# 同步批量查询
|
|
1162
|
+
response = client.blobs.batch_get_file_status(
|
|
1163
|
+
file_ids=["file-1", "file-2", "file-3"],
|
|
1164
|
+
include_details=True
|
|
1165
|
+
)
|
|
1166
|
+
|
|
1167
|
+
for status in response.statuses:
|
|
1168
|
+
print(f"文件 {status.file_id[:8]}...")
|
|
1169
|
+
print(f" 状态: {status.upload_status.value}")
|
|
1170
|
+
|
|
1171
|
+
if status.details:
|
|
1172
|
+
print(f" 大小: {status.details.file_size} bytes")
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
#### 状态枚举说明
|
|
1176
|
+
|
|
1177
|
+
**上传状态 (FileUploadStatus):**
|
|
1178
|
+
- `UPLOAD_UNKNOWN`: 未知状态
|
|
1179
|
+
- `UPLOAD_PENDING`: 待上传
|
|
1180
|
+
- `UPLOAD_PROCESSING`: 上传中
|
|
1181
|
+
- `UPLOAD_COMPLETED`: 已完成
|
|
1182
|
+
- `UPLOAD_FAILED`: 失败
|
|
1183
|
+
|
|
1184
|
+
**压缩状态 (FileCompressionStatus):**
|
|
1185
|
+
- `COMPRESSION_UNKNOWN`: 未知状态
|
|
1186
|
+
- `COMPRESSION_NOT_APPLICABLE`: 不需要压缩(非图片/视频文件)
|
|
1187
|
+
- `COMPRESSION_PENDING`: 等待压缩
|
|
1188
|
+
- `COMPRESSION_PROCESSING`: 压缩中
|
|
1189
|
+
- `COMPRESSION_COMPLETED`: 已完成
|
|
1190
|
+
- `COMPRESSION_FAILED`: 失败
|
|
1191
|
+
- `COMPRESSION_SKIPPED`: 跳过压缩
|
|
1192
|
+
|
|
1193
|
+
**同步状态 (FileSyncStatus):**
|
|
1194
|
+
- `SYNC_UNKNOWN`: 未知状态
|
|
1195
|
+
- `SYNC_NOT_REQUIRED`: 不需要同步
|
|
1196
|
+
- `SYNC_PENDING`: 等待同步
|
|
1197
|
+
- `SYNC_PROCESSING`: 同步中
|
|
1198
|
+
- `SYNC_PARTIAL`: 部分完成
|
|
1199
|
+
- `SYNC_COMPLETED`: 全部完成
|
|
1200
|
+
- `SYNC_FAILED`: 同步失败
|
|
1201
|
+
|
|
1202
|
+
#### 使用场景
|
|
1203
|
+
|
|
1204
|
+
1. **文件处理监控**:
|
|
1205
|
+
- 实时监控文件上传、压缩、同步进度
|
|
1206
|
+
- 及时发现和处理失败的文件
|
|
1207
|
+
|
|
1208
|
+
2. **批量状态查询**:
|
|
1209
|
+
- 一次查询最多100个文件状态
|
|
1210
|
+
- 减少网络请求,提高性能
|
|
1211
|
+
|
|
1212
|
+
3. **业务流程控制**:
|
|
1213
|
+
- 根据文件状态决定后续业务逻辑
|
|
1214
|
+
- 确保文件完全准备就绪后再进行下一步操作
|
|
1215
|
+
|
|
1216
|
+
4. **性能优化**:
|
|
1217
|
+
- 利用缓存机制提高查询效率
|
|
1218
|
+
- 支持详细信息的按需获取
|
|
1219
|
+
|
|
1034
1220
|
### 文件管理操作
|
|
1035
1221
|
|
|
1036
1222
|
File Hub Client 提供了完整的文件管理功能,通过 `files` 服务访问:
|
|
@@ -2378,6 +2564,7 @@ MIT License
|
|
|
2378
2564
|
- **断点续传修复**: 解决断点续传中的HTTP头部和签名验证问题
|
|
2379
2565
|
- **AI生成文件支持**: 完善对AI生成内容(图片、视频、音频)的MIME类型处理
|
|
2380
2566
|
- **新功能**: 新增 `mime_type` 参数支持,允许用户显式指定文件MIME类型
|
|
2567
|
+
- **批量文件状态查询**: 新增 `batch_get_file_status` API,支持批量查询文件上传、压缩、同步状态
|
|
2381
2568
|
- **魔术字节检测**: 增强内容检测,支持26+种主流文件格式的自动识别
|
|
2382
2569
|
- **向下兼容**: 保持100%向下兼容,现有代码无需修改
|
|
2383
2570
|
- **核心修复**:
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
- 📝 **类型注解**:完整的类型提示支持
|
|
18
18
|
- 🧩 **模块化设计**:清晰的代码结构,易于扩展
|
|
19
19
|
- 🎨 **图片和视频压缩**:支持多种规格的媒体文件压缩变体生成和管理
|
|
20
|
+
- 📊 **批量状态查询**:支持批量查询文件的上传、压缩、备份同步状态
|
|
20
21
|
- 🏗️ **分层服务架构**:文件服务分为传统文件(blob)和自定义类型(结构化数据),每种类型独立服务,语义清晰
|
|
21
22
|
- 🔧 **环境变量配置**:支持通过环境变量配置所有参数
|
|
22
23
|
- 👤 **用户上下文管理**:支持区分资源所有权(ownership)和操作者(operator)
|
|
@@ -168,6 +169,7 @@ File Hub Client 采用分层服务架构,将文件服务按类型和语义进
|
|
|
168
169
|
- 支持临时文件上传
|
|
169
170
|
- **媒体文件压缩**:支持图片和视频的多规格压缩变体生成
|
|
170
171
|
- **压缩管理**:获取压缩状态、管理变体、触发重新压缩
|
|
172
|
+
- **批量文件状态查询**:一次性查询多个文件的上传、压缩、同步状态
|
|
171
173
|
- 适用类型:PDF、图片、视频、音频、压缩包等
|
|
172
174
|
- **file_service**: 处理文件元数据操作(所有类型通用)
|
|
173
175
|
- 获取、重命名、删除文件
|
|
@@ -207,6 +209,12 @@ File Hub Client 采用分层服务架构,将文件服务按类型和语义进
|
|
|
207
209
|
- `GetVariantsResponse`: 获取变体响应
|
|
208
210
|
- `RecompressionResponse`: 重新压缩响应
|
|
209
211
|
- `VariantDownloadUrlResponse`: 变体下载URL响应
|
|
212
|
+
- `BatchFileStatusResponse`: 批量文件状态响应
|
|
213
|
+
- `FileStatusInfo`: 单个文件状态信息
|
|
214
|
+
- `FileStatusDetails`: 文件状态详细信息
|
|
215
|
+
- `FileUploadStatus`: 文件上传状态枚举
|
|
216
|
+
- `FileCompressionStatus`: 文件压缩状态枚举
|
|
217
|
+
- `FileSyncStatus`: 文件同步状态枚举
|
|
210
218
|
|
|
211
219
|
- **folder.py**: 文件夹相关的数据模型
|
|
212
220
|
- `FolderInfo`: 文件夹信息
|
|
@@ -985,6 +993,184 @@ with TamarFileHubClient() as client:
|
|
|
985
993
|
- 支持重新压缩以应用新的压缩设置
|
|
986
994
|
- 批量状态查询减少网络请求
|
|
987
995
|
|
|
996
|
+
### 批量文件状态查询
|
|
997
|
+
|
|
998
|
+
File Hub Client 提供了高效的批量文件状态查询功能,可以一次性获取多个文件的上传、压缩、同步状态:
|
|
999
|
+
|
|
1000
|
+
#### 基础批量查询
|
|
1001
|
+
|
|
1002
|
+
```python
|
|
1003
|
+
from file_hub_client import AsyncTamarFileHubClient
|
|
1004
|
+
|
|
1005
|
+
async with AsyncTamarFileHubClient() as client:
|
|
1006
|
+
client.set_user_context(org_id="123", user_id="456")
|
|
1007
|
+
|
|
1008
|
+
# 批量查询多个文件的状态
|
|
1009
|
+
file_ids = ["file-id-1", "file-id-2", "file-id-3"]
|
|
1010
|
+
response = await client.blobs.batch_get_file_status(
|
|
1011
|
+
file_ids=file_ids,
|
|
1012
|
+
include_details=False # 是否包含详细信息,默认False
|
|
1013
|
+
)
|
|
1014
|
+
|
|
1015
|
+
print(f"查询时间戳: {response.timestamp}")
|
|
1016
|
+
print(f"缓存命中数量: {response.cache_hit_count}")
|
|
1017
|
+
print(f"查询到 {len(response.statuses)} 个文件状态")
|
|
1018
|
+
|
|
1019
|
+
for status in response.statuses:
|
|
1020
|
+
print(f"文件ID: {status.file_id}")
|
|
1021
|
+
print(f" 上传状态: {status.upload_status.value}")
|
|
1022
|
+
print(f" 压缩状态: {status.compression_status.value}")
|
|
1023
|
+
print(f" 同步状态: {status.sync_status.value}")
|
|
1024
|
+
|
|
1025
|
+
if status.error_message:
|
|
1026
|
+
print(f" 错误信息: {status.error_message}")
|
|
1027
|
+
```
|
|
1028
|
+
|
|
1029
|
+
#### 详细信息查询
|
|
1030
|
+
|
|
1031
|
+
```python
|
|
1032
|
+
# 查询详细状态信息
|
|
1033
|
+
detailed_response = await client.blobs.batch_get_file_status(
|
|
1034
|
+
file_ids=file_ids,
|
|
1035
|
+
include_details=True # 包含详细信息
|
|
1036
|
+
)
|
|
1037
|
+
|
|
1038
|
+
for status in detailed_response.statuses:
|
|
1039
|
+
print(f"文件ID: {status.file_id}")
|
|
1040
|
+
print(f" 上传状态: {status.upload_status.value}")
|
|
1041
|
+
print(f" 压缩状态: {status.compression_status.value}")
|
|
1042
|
+
print(f" 同步状态: {status.sync_status.value}")
|
|
1043
|
+
|
|
1044
|
+
if status.details:
|
|
1045
|
+
print(" 详细信息:")
|
|
1046
|
+
if status.details.file_size:
|
|
1047
|
+
print(f" 文件大小: {status.details.file_size} 字节")
|
|
1048
|
+
if status.details.storage_type:
|
|
1049
|
+
print(f" 存储类型: {status.details.storage_type}")
|
|
1050
|
+
if status.details.storage_region:
|
|
1051
|
+
print(f" 存储区域: {status.details.storage_region}")
|
|
1052
|
+
|
|
1053
|
+
# 压缩相关详细信息
|
|
1054
|
+
if status.details.compression_task_id:
|
|
1055
|
+
print(f" 压缩任务ID: {status.details.compression_task_id}")
|
|
1056
|
+
if status.details.compression_variants_count is not None:
|
|
1057
|
+
print(f" 压缩变体数量: {status.details.compression_variants_count}")
|
|
1058
|
+
if status.details.compression_progress is not None:
|
|
1059
|
+
print(f" 压缩进度: {status.details.compression_progress * 100:.1f}%")
|
|
1060
|
+
|
|
1061
|
+
# 同步相关详细信息
|
|
1062
|
+
if status.details.sync_regions_total is not None:
|
|
1063
|
+
print(f" 同步区域总数: {status.details.sync_regions_total}")
|
|
1064
|
+
if status.details.sync_regions_completed is not None:
|
|
1065
|
+
print(f" 已完成同步区域: {status.details.sync_regions_completed}")
|
|
1066
|
+
if status.details.sync_pending_regions:
|
|
1067
|
+
print(f" 待同步区域: {', '.join(status.details.sync_pending_regions)}")
|
|
1068
|
+
```
|
|
1069
|
+
|
|
1070
|
+
#### 状态筛选和分析
|
|
1071
|
+
|
|
1072
|
+
```python
|
|
1073
|
+
from file_hub_client.schemas import (
|
|
1074
|
+
FileUploadStatus,
|
|
1075
|
+
FileCompressionStatus,
|
|
1076
|
+
FileSyncStatus
|
|
1077
|
+
)
|
|
1078
|
+
|
|
1079
|
+
# 查询文件状态
|
|
1080
|
+
response = await client.blobs.batch_get_file_status(file_ids=file_ids)
|
|
1081
|
+
|
|
1082
|
+
# 筛选出上传失败的文件
|
|
1083
|
+
failed_uploads = [
|
|
1084
|
+
status for status in response.statuses
|
|
1085
|
+
if status.upload_status == FileUploadStatus.UPLOAD_FAILED
|
|
1086
|
+
]
|
|
1087
|
+
|
|
1088
|
+
# 筛选出正在处理的文件
|
|
1089
|
+
processing_files = [
|
|
1090
|
+
status for status in response.statuses
|
|
1091
|
+
if (status.upload_status == FileUploadStatus.UPLOAD_PROCESSING or
|
|
1092
|
+
status.compression_status == FileCompressionStatus.COMPRESSION_PROCESSING or
|
|
1093
|
+
status.sync_status == FileSyncStatus.SYNC_PROCESSING)
|
|
1094
|
+
]
|
|
1095
|
+
|
|
1096
|
+
# 筛选出压缩不适用的文件(非图片/视频)
|
|
1097
|
+
non_compressible_files = [
|
|
1098
|
+
status for status in response.statuses
|
|
1099
|
+
if status.compression_status == FileCompressionStatus.COMPRESSION_NOT_APPLICABLE
|
|
1100
|
+
]
|
|
1101
|
+
|
|
1102
|
+
print(f"上传失败的文件: {len(failed_uploads)} 个")
|
|
1103
|
+
print(f"正在处理的文件: {len(processing_files)} 个")
|
|
1104
|
+
print(f"非媒体文件: {len(non_compressible_files)} 个")
|
|
1105
|
+
```
|
|
1106
|
+
|
|
1107
|
+
#### 同步客户端示例
|
|
1108
|
+
|
|
1109
|
+
```python
|
|
1110
|
+
from file_hub_client import TamarFileHubClient
|
|
1111
|
+
|
|
1112
|
+
with TamarFileHubClient() as client:
|
|
1113
|
+
client.set_user_context(org_id="123", user_id="456")
|
|
1114
|
+
|
|
1115
|
+
# 同步批量查询
|
|
1116
|
+
response = client.blobs.batch_get_file_status(
|
|
1117
|
+
file_ids=["file-1", "file-2", "file-3"],
|
|
1118
|
+
include_details=True
|
|
1119
|
+
)
|
|
1120
|
+
|
|
1121
|
+
for status in response.statuses:
|
|
1122
|
+
print(f"文件 {status.file_id[:8]}...")
|
|
1123
|
+
print(f" 状态: {status.upload_status.value}")
|
|
1124
|
+
|
|
1125
|
+
if status.details:
|
|
1126
|
+
print(f" 大小: {status.details.file_size} bytes")
|
|
1127
|
+
```
|
|
1128
|
+
|
|
1129
|
+
#### 状态枚举说明
|
|
1130
|
+
|
|
1131
|
+
**上传状态 (FileUploadStatus):**
|
|
1132
|
+
- `UPLOAD_UNKNOWN`: 未知状态
|
|
1133
|
+
- `UPLOAD_PENDING`: 待上传
|
|
1134
|
+
- `UPLOAD_PROCESSING`: 上传中
|
|
1135
|
+
- `UPLOAD_COMPLETED`: 已完成
|
|
1136
|
+
- `UPLOAD_FAILED`: 失败
|
|
1137
|
+
|
|
1138
|
+
**压缩状态 (FileCompressionStatus):**
|
|
1139
|
+
- `COMPRESSION_UNKNOWN`: 未知状态
|
|
1140
|
+
- `COMPRESSION_NOT_APPLICABLE`: 不需要压缩(非图片/视频文件)
|
|
1141
|
+
- `COMPRESSION_PENDING`: 等待压缩
|
|
1142
|
+
- `COMPRESSION_PROCESSING`: 压缩中
|
|
1143
|
+
- `COMPRESSION_COMPLETED`: 已完成
|
|
1144
|
+
- `COMPRESSION_FAILED`: 失败
|
|
1145
|
+
- `COMPRESSION_SKIPPED`: 跳过压缩
|
|
1146
|
+
|
|
1147
|
+
**同步状态 (FileSyncStatus):**
|
|
1148
|
+
- `SYNC_UNKNOWN`: 未知状态
|
|
1149
|
+
- `SYNC_NOT_REQUIRED`: 不需要同步
|
|
1150
|
+
- `SYNC_PENDING`: 等待同步
|
|
1151
|
+
- `SYNC_PROCESSING`: 同步中
|
|
1152
|
+
- `SYNC_PARTIAL`: 部分完成
|
|
1153
|
+
- `SYNC_COMPLETED`: 全部完成
|
|
1154
|
+
- `SYNC_FAILED`: 同步失败
|
|
1155
|
+
|
|
1156
|
+
#### 使用场景
|
|
1157
|
+
|
|
1158
|
+
1. **文件处理监控**:
|
|
1159
|
+
- 实时监控文件上传、压缩、同步进度
|
|
1160
|
+
- 及时发现和处理失败的文件
|
|
1161
|
+
|
|
1162
|
+
2. **批量状态查询**:
|
|
1163
|
+
- 一次查询最多100个文件状态
|
|
1164
|
+
- 减少网络请求,提高性能
|
|
1165
|
+
|
|
1166
|
+
3. **业务流程控制**:
|
|
1167
|
+
- 根据文件状态决定后续业务逻辑
|
|
1168
|
+
- 确保文件完全准备就绪后再进行下一步操作
|
|
1169
|
+
|
|
1170
|
+
4. **性能优化**:
|
|
1171
|
+
- 利用缓存机制提高查询效率
|
|
1172
|
+
- 支持详细信息的按需获取
|
|
1173
|
+
|
|
988
1174
|
### 文件管理操作
|
|
989
1175
|
|
|
990
1176
|
File Hub Client 提供了完整的文件管理功能,通过 `files` 服务访问:
|
|
@@ -2332,6 +2518,7 @@ MIT License
|
|
|
2332
2518
|
- **断点续传修复**: 解决断点续传中的HTTP头部和签名验证问题
|
|
2333
2519
|
- **AI生成文件支持**: 完善对AI生成内容(图片、视频、音频)的MIME类型处理
|
|
2334
2520
|
- **新功能**: 新增 `mime_type` 参数支持,允许用户显式指定文件MIME类型
|
|
2521
|
+
- **批量文件状态查询**: 新增 `batch_get_file_status` API,支持批量查询文件上传、压缩、同步状态
|
|
2335
2522
|
- **魔术字节检测**: 增强内容检测,支持26+种主流文件格式的自动识别
|
|
2336
2523
|
- **向下兼容**: 保持100%向下兼容,现有代码无需修改
|
|
2337
2524
|
- **核心修复**:
|
|
@@ -26,19 +26,19 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__
|
|
|
26
26
|
from google.protobuf import struct_pb2 as google_dot_protobuf_dot_struct__pb2
|
|
27
27
|
|
|
28
28
|
|
|
29
|
-
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x66ile_service.proto\x12\x04\x66ile\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\"\xab\x01\n\x04\x46ile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tfolder_id\x18\x02 \x01(\t\x12\x11\n\tfile_name\x18\x03 \x01(\t\x12\x11\n\tfile_type\x18\x04 \x01(\t\x12.\n\ncreated_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xb7\x02\n\nUploadFile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tfolder_id\x18\x02 \x01(\t\x12\x0f\n\x07\x66ile_id\x18\x03 \x01(\t\x12\x14\n\x0cstorage_type\x18\x04 \x01(\t\x12\x13\n\x0bstored_name\x18\x05 \x01(\t\x12\x13\n\x0bstored_path\x18\x06 \x01(\t\x12\x11\n\tfile_name\x18\x07 \x01(\t\x12\x11\n\tfile_size\x18\x08 \x01(\x03\x12\x10\n\x08\x66ile_ext\x18\t \x01(\t\x12\x11\n\tmime_type\x18\n \x01(\t\x12\x0e\n\x06status\x18\x0b \x01(\t\x12.\n\ncreated_at\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\x9f\x02\n\x11UploadFileRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x03 \x01(\x0c\x12\x11\n\tfile_type\x18\x04 \x01(\t\x12\x11\n\tmime_type\x18\x05 \x01(\t\x12\x19\n\x0cis_temporary\x18\x06 \x01(\x08H\x01\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x07 \x01(\x05H\x02\x88\x01\x01\x12#\n\x16keep_original_filename\x18\x08 \x01(\x08H\x03\x88\x01\x01\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_secondsB\x19\n\x17_keep_original_filename\"\xb3\x02\n\x10UploadUrlRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x11\n\tfile_type\x18\x03 \x01(\t\x12\x11\n\tmime_type\x18\x04 \x01(\t\x12\x11\n\tfile_size\x18\x05 \x01(\x03\x12\x11\n\tfile_hash\x18\x06 \x01(\t\x12\x19\n\x0cis_temporary\x18\x07 \x01(\x08H\x01\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x08 \x01(\x05H\x02\x88\x01\x01\x12#\n\x16keep_original_filename\x18\t \x01(\x08H\x03\x88\x01\x01\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_secondsB\x19\n\x17_keep_original_filename\")\n\x16UploadCompletedRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"u\n\x12\x44ownloadUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x13\n\x06is_cdn\x18\x03 \x01(\x08H\x00\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x02 \x01(\x05H\x01\x88\x01\x01\x42\t\n\x07_is_cdnB\x11\n\x0f_expire_seconds\"\xd4\x01\n\x10ShareLinkRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x11\n\tis_public\x18\x02 \x01(\x08\x12\x14\n\x0c\x61\x63\x63\x65ss_scope\x18\x03 \x01(\t\x12\x1b\n\x0e\x65xpire_seconds\x18\x04 \x01(\x05H\x00\x88\x01\x01\x12\x17\n\nmax_access\x18\x05 \x01(\x05H\x01\x88\x01\x01\x12\x1b\n\x0eshare_password\x18\x06 \x01(\tH\x02\x88\x01\x01\x42\x11\n\x0f_expire_secondsB\r\n\x0b_max_accessB\x11\n\x0f_share_password\"\x82\x01\n\x10\x46ileVisitRequest\x12\x15\n\rfile_share_id\x18\x01 \x01(\t\x12\x13\n\x0b\x61\x63\x63\x65ss_type\x18\x02 \x01(\t\x12\x17\n\x0f\x61\x63\x63\x65ss_duration\x18\x03 \x01(\x05\x12)\n\x08metadata\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\"!\n\x0eGetFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"6\n\x11RenameFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x10\n\x08new_name\x18\x02 \x01(\t\"$\n\x11\x44\x65leteFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"\x8d\x02\n\x10ListFilesRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tfile_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x11\n\tfile_type\x18\x03 \x03(\t\x12\x1c\n\x0f\x63reated_by_role\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x17\n\ncreated_by\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x16\n\tpage_size\x18\x06 \x01(\x05H\x04\x88\x01\x01\x12\x11\n\x04page\x18\x07 \x01(\x05H\x05\x88\x01\x01\x42\x0c\n\n_folder_idB\x0c\n\n_file_nameB\x12\n\x10_created_by_roleB\r\n\x0b_created_byB\x0c\n\n_page_sizeB\x07\n\x05_page\"{\n\x17\x42\x61tchDownloadUrlRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\x12\x13\n\x06is_cdn\x18\x02 \x01(\x08H\x00\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x03 \x01(\x05H\x01\x88\x01\x01\x42\t\n\x07_is_cdnB\x11\n\x0f_expire_seconds\"#\n\x10GetGcsUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\")\n\x15\x42\x61tchGetGcsUrlRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\"U\n\x12UploadFileResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12%\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFile\"a\n\x11UploadUrlResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12%\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFile\x12\x0b\n\x03url\x18\x03 \x01(\t\"\"\n\x13\x44ownloadUrlResponse\x12\x0b\n\x03url\x18\x01 \x01(\t\"*\n\x11ShareLinkResponse\x12\x15\n\rfile_share_id\x18\x01 \x01(\t\"-\n\x10\x46ileListResponse\x12\x19\n\x05\x66iles\x18\x01 \x03(\x0b\x32\n.file.File\"g\n\x0fGetFileResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12*\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFileH\x00\x88\x01\x01\x42\x0e\n\x0c_upload_file\"H\n\x18\x42\x61tchDownloadUrlResponse\x12,\n\rdownload_urls\x18\x01 \x03(\x0b\x32\x15.file.DownloadUrlInfo\"`\n\x0f\x44ownloadUrlInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x11\n\tmime_type\x18\x03 \x01(\t\x12\x12\n\x05\x65rror\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"7\n\x11GetGcsUrlResponse\x12\x0f\n\x07gcs_url\x18\x01 \x01(\t\x12\x11\n\tmime_type\x18\x02 \x01(\t\"<\n\x16\x42\x61tchGetGcsUrlResponse\x12\"\n\x08gcs_urls\x18\x01 \x03(\x0b\x32\x10.file.GcsUrlInfo\"_\n\nGcsUrlInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x0f\n\x07gcs_url\x18\x02 \x01(\t\x12\x11\n\tmime_type\x18\x03 \x01(\t\x12\x12\n\x05\x65rror\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"+\n\x18\x43ompressionStatusRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"\x84\x01\n\x19\x43ompressionStatusResponse\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x1a\n\rerror_message\x18\x02 \x01(\tH\x00\x88\x01\x01\x12)\n\x08variants\x18\x03 \x03(\x0b\x32\x17.file.CompressedVariantB\x10\n\x0e_error_message\"Q\n\x12GetVariantsRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x19\n\x0cvariant_type\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0f\n\r_variant_type\"@\n\x13GetVariantsResponse\x12)\n\x08variants\x18\x01 \x03(\x0b\x32\x17.file.CompressedVariant\"\xc7\x02\n\x11\x43ompressedVariant\x12\x14\n\x0cvariant_name\x18\x01 \x01(\t\x12\x14\n\x0cvariant_type\x18\x02 \x01(\t\x12\x12\n\nmedia_type\x18\x03 \x01(\t\x12\r\n\x05width\x18\x04 \x01(\x05\x12\x0e\n\x06height\x18\x05 \x01(\x05\x12\x11\n\tfile_size\x18\x06 \x01(\x03\x12\x0e\n\x06\x66ormat\x18\x07 \x01(\t\x12\x14\n\x07quality\x18\x08 \x01(\x05H\x00\x88\x01\x01\x12\x15\n\x08\x64uration\x18\t \x01(\x01H\x01\x88\x01\x01\x12\x14\n\x07\x62itrate\x18\n \x01(\x03H\x02\x88\x01\x01\x12\x10\n\x03\x66ps\x18\x0b \x01(\x05H\x03\x88\x01\x01\x12\x19\n\x11\x63ompression_ratio\x18\x0c \x01(\x01\x12\x13\n\x0bstored_path\x18\r \x01(\tB\n\n\x08_qualityB\x0b\n\t_durationB\n\n\x08_bitrateB\x06\n\x04_fps\"Y\n\x14RecompressionRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x1c\n\x0f\x66orce_reprocess\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_force_reprocess\"8\n\x15RecompressionResponse\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\"\x92\x01\n\x19VariantDownloadUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x14\n\x0cvariant_name\x18\x02 \x01(\t\x12\x1b\n\x0e\x65xpire_seconds\x18\x03 \x01(\x05H\x00\x88\x01\x01\x12\x13\n\x06is_cdn\x18\x04 \x01(\x08H\x01\x88\x01\x01\x42\x11\n\x0f_expire_secondsB\t\n\x07_is_cdn\"\x8c\x01\n\x1aVariantDownloadUrlResponse\x12\x0b\n\x03url\x18\x01 \x01(\t\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x32\n\x0cvariant_info\x18\x03 \x01(\x0b\x32\x17.file.CompressedVariantH\x01\x88\x01\x01\x42\x08\n\x06_errorB\x0f\n\r_variant_info\"\\\n\x16\x42\x61tchFileStatusRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\x12\x1c\n\x0finclude_details\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_include_details\"m\n\x17\x42\x61tchFileStatusResponse\x12&\n\x08statuses\x18\x01 \x03(\x0b\x32\x14.file.FileStatusInfo\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\x17\n\x0f\x63\x61\x63he_hit_count\x18\x03 \x01(\x05\"\x9d\x02\n\x0e\x46ileStatusInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12-\n\rupload_status\x18\x02 \x01(\x0e\x32\x16.file.FileUploadStatus\x12\x37\n\x12\x63ompression_status\x18\x03 \x01(\x0e\x32\x1b.file.FileCompressionStatus\x12)\n\x0bsync_status\x18\x04 \x01(\x0e\x32\x14.file.FileSyncStatus\x12-\n\x07\x64\x65tails\x18\x05 \x01(\x0b\x32\x17.file.FileStatusDetailsH\x00\x88\x01\x01\x12\x1a\n\rerror_message\x18\x06 \x01(\tH\x01\x88\x01\x01\x42\n\n\x08_detailsB\x10\n\x0e_error_message\"\xe9\x03\n\x11\x46ileStatusDetails\x12\x16\n\tfile_size\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12\x19\n\x0cstorage_type\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1b\n\x0estorage_region\x18\x03 \x01(\tH\x02\x88\x01\x01\x12 \n\x13\x63ompression_task_id\x18\x04 \x01(\tH\x03\x88\x01\x01\x12\'\n\x1a\x63ompression_variants_count\x18\x05 \x01(\x05H\x04\x88\x01\x01\x12!\n\x14\x63ompression_progress\x18\x06 \x01(\x01H\x05\x88\x01\x01\x12\x1f\n\x12sync_regions_total\x18\x07 \x01(\x05H\x06\x88\x01\x01\x12#\n\x16sync_regions_completed\x18\x08 \x01(\x05H\x07\x88\x01\x01\x12\x1c\n\x14sync_pending_regions\x18\t \x03(\tB\x0c\n\n_file_sizeB\x0f\n\r_storage_typeB\x11\n\x0f_storage_regionB\x16\n\x14_compression_task_idB\x1d\n\x1b_compression_variants_countB\x17\n\x15_compression_progressB\x15\n\x13_sync_regions_totalB\x19\n\x17_sync_regions_completed\"\x07\n\x05\x45mpty*z\n\x10\x46ileUploadStatus\x12\x12\n\x0eUPLOAD_UNKNOWN\x10\x00\x12\x12\n\x0eUPLOAD_PENDING\x10\x01\x12\x15\n\x11UPLOAD_PROCESSING\x10\x02\x12\x14\n\x10UPLOAD_COMPLETED\x10\x03\x12\x11\n\rUPLOAD_FAILED\x10\x04*\xd1\x01\n\x15\x46ileCompressionStatus\x12\x17\n\x13\x43OMPRESSION_UNKNOWN\x10\x00\x12\x1e\n\x1a\x43OMPRESSION_NOT_APPLICABLE\x10\x01\x12\x17\n\x13\x43OMPRESSION_PENDING\x10\x02\x12\x1a\n\x16\x43OMPRESSION_PROCESSING\x10\x03\x12\x19\n\x15\x43OMPRESSION_COMPLETED\x10\x04\x12\x16\n\x12\x43OMPRESSION_FAILED\x10\x05\x12\x17\n\x13\x43OMPRESSION_SKIPPED\x10\x06*\x97\x01\n\x0e\x46ileSyncStatus\x12\x10\n\x0cSYNC_UNKNOWN\x10\x00\x12\x15\n\x11SYNC_NOT_REQUIRED\x10\x01\x12\x10\n\x0cSYNC_PENDING\x10\x02\x12\x13\n\x0fSYNC_PROCESSING\x10\x03\x12\x10\n\x0cSYNC_PARTIAL\x10\x04\x12\x12\n\x0eSYNC_COMPLETED\x10\x05\x12\x0f\n\x0bSYNC_FAILED\x10\x06\x32\xda\n\n\x0b\x46ileService\x12?\n\nUploadFile\x12\x17.file.UploadFileRequest\x1a\x18.file.UploadFileResponse\x12\x44\n\x11GenerateUploadUrl\x12\x16.file.UploadUrlRequest\x1a\x17.file.UploadUrlResponse\x12M\n\x1aGenerateResumableUploadUrl\x12\x16.file.UploadUrlRequest\x1a\x17.file.UploadUrlResponse\x12\x43\n\x16\x43onfirmUploadCompleted\x12\x1c.file.UploadCompletedRequest\x1a\x0b.file.Empty\x12J\n\x13GenerateDownloadUrl\x12\x18.file.DownloadUrlRequest\x1a\x19.file.DownloadUrlResponse\x12Y\n\x18\x42\x61tchGenerateDownloadUrl\x12\x1d.file.BatchDownloadUrlRequest\x1a\x1e.file.BatchDownloadUrlResponse\x12<\n\tGetGcsUrl\x12\x16.file.GetGcsUrlRequest\x1a\x17.file.GetGcsUrlResponse\x12K\n\x0e\x42\x61tchGetGcsUrl\x12\x1b.file.BatchGetGcsUrlRequest\x1a\x1c.file.BatchGetGcsUrlResponse\x12\x44\n\x11GenerateShareLink\x12\x16.file.ShareLinkRequest\x1a\x17.file.ShareLinkResponse\x12\x30\n\tVisitFile\x12\x16.file.FileVisitRequest\x1a\x0b.file.Empty\x12\x36\n\x07GetFile\x12\x14.file.GetFileRequest\x1a\x15.file.GetFileResponse\x12\x31\n\nRenameFile\x12\x17.file.RenameFileRequest\x1a\n.file.File\x12\x32\n\nDeleteFile\x12\x17.file.DeleteFileRequest\x1a\x0b.file.Empty\x12;\n\tListFiles\x12\x16.file.ListFilesRequest\x1a\x16.file.FileListResponse\x12W\n\x14GetCompressionStatus\x12\x1e.file.CompressionStatusRequest\x1a\x1f.file.CompressionStatusResponse\x12L\n\x15GetCompressedVariants\x12\x18.file.GetVariantsRequest\x1a\x19.file.GetVariantsResponse\x12O\n\x14TriggerRecompression\x12\x1a.file.RecompressionRequest\x1a\x1b.file.RecompressionResponse\x12_\n\x1aGenerateVariantDownloadUrl\x12\x1f.file.VariantDownloadUrlRequest\x1a .file.VariantDownloadUrlResponse\x12Q\n\x12\x42\x61tchGetFileStatus\x12\x1c.file.BatchFileStatusRequest\x1a\x1d.file.BatchFileStatusResponseb\x06proto3')
|
|
29
|
+
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12\x66ile_service.proto\x12\x04\x66ile\x1a\x1fgoogle/protobuf/timestamp.proto\x1a\x1cgoogle/protobuf/struct.proto\"\xab\x01\n\x04\x46ile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tfolder_id\x18\x02 \x01(\t\x12\x11\n\tfile_name\x18\x03 \x01(\t\x12\x11\n\tfile_type\x18\x04 \x01(\t\x12.\n\ncreated_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xb7\x02\n\nUploadFile\x12\n\n\x02id\x18\x01 \x01(\t\x12\x11\n\tfolder_id\x18\x02 \x01(\t\x12\x0f\n\x07\x66ile_id\x18\x03 \x01(\t\x12\x14\n\x0cstorage_type\x18\x04 \x01(\t\x12\x13\n\x0bstored_name\x18\x05 \x01(\t\x12\x13\n\x0bstored_path\x18\x06 \x01(\t\x12\x11\n\tfile_name\x18\x07 \x01(\t\x12\x11\n\tfile_size\x18\x08 \x01(\x03\x12\x10\n\x08\x66ile_ext\x18\t \x01(\t\x12\x11\n\tmime_type\x18\n \x01(\t\x12\x0e\n\x06status\x18\x0b \x01(\t\x12.\n\ncreated_at\x18\x0c \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12.\n\nupdated_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\x9f\x02\n\x11UploadFileRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x0f\n\x07\x63ontent\x18\x03 \x01(\x0c\x12\x11\n\tfile_type\x18\x04 \x01(\t\x12\x11\n\tmime_type\x18\x05 \x01(\t\x12\x19\n\x0cis_temporary\x18\x06 \x01(\x08H\x01\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x07 \x01(\x05H\x02\x88\x01\x01\x12#\n\x16keep_original_filename\x18\x08 \x01(\x08H\x03\x88\x01\x01\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_secondsB\x19\n\x17_keep_original_filename\"\xb3\x02\n\x10UploadUrlRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x11\n\tfile_name\x18\x02 \x01(\t\x12\x11\n\tfile_type\x18\x03 \x01(\t\x12\x11\n\tmime_type\x18\x04 \x01(\t\x12\x11\n\tfile_size\x18\x05 \x01(\x03\x12\x11\n\tfile_hash\x18\x06 \x01(\t\x12\x19\n\x0cis_temporary\x18\x07 \x01(\x08H\x01\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x08 \x01(\x05H\x02\x88\x01\x01\x12#\n\x16keep_original_filename\x18\t \x01(\x08H\x03\x88\x01\x01\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_secondsB\x19\n\x17_keep_original_filename\")\n\x16UploadCompletedRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"u\n\x12\x44ownloadUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x13\n\x06is_cdn\x18\x03 \x01(\x08H\x00\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x02 \x01(\x05H\x01\x88\x01\x01\x42\t\n\x07_is_cdnB\x11\n\x0f_expire_seconds\"\xd4\x01\n\x10ShareLinkRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x11\n\tis_public\x18\x02 \x01(\x08\x12\x14\n\x0c\x61\x63\x63\x65ss_scope\x18\x03 \x01(\t\x12\x1b\n\x0e\x65xpire_seconds\x18\x04 \x01(\x05H\x00\x88\x01\x01\x12\x17\n\nmax_access\x18\x05 \x01(\x05H\x01\x88\x01\x01\x12\x1b\n\x0eshare_password\x18\x06 \x01(\tH\x02\x88\x01\x01\x42\x11\n\x0f_expire_secondsB\r\n\x0b_max_accessB\x11\n\x0f_share_password\"\x82\x01\n\x10\x46ileVisitRequest\x12\x15\n\rfile_share_id\x18\x01 \x01(\t\x12\x13\n\x0b\x61\x63\x63\x65ss_type\x18\x02 \x01(\t\x12\x17\n\x0f\x61\x63\x63\x65ss_duration\x18\x03 \x01(\x05\x12)\n\x08metadata\x18\x04 \x01(\x0b\x32\x17.google.protobuf.Struct\"!\n\x0eGetFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"6\n\x11RenameFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x10\n\x08new_name\x18\x02 \x01(\t\"$\n\x11\x44\x65leteFileRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"\x8d\x02\n\x10ListFilesRequest\x12\x16\n\tfolder_id\x18\x01 \x01(\tH\x00\x88\x01\x01\x12\x16\n\tfile_name\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x11\n\tfile_type\x18\x03 \x03(\t\x12\x1c\n\x0f\x63reated_by_role\x18\x04 \x01(\tH\x02\x88\x01\x01\x12\x17\n\ncreated_by\x18\x05 \x01(\tH\x03\x88\x01\x01\x12\x16\n\tpage_size\x18\x06 \x01(\x05H\x04\x88\x01\x01\x12\x11\n\x04page\x18\x07 \x01(\x05H\x05\x88\x01\x01\x42\x0c\n\n_folder_idB\x0c\n\n_file_nameB\x12\n\x10_created_by_roleB\r\n\x0b_created_byB\x0c\n\n_page_sizeB\x07\n\x05_page\"{\n\x17\x42\x61tchDownloadUrlRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\x12\x13\n\x06is_cdn\x18\x02 \x01(\x08H\x00\x88\x01\x01\x12\x1b\n\x0e\x65xpire_seconds\x18\x03 \x01(\x05H\x01\x88\x01\x01\x42\t\n\x07_is_cdnB\x11\n\x0f_expire_seconds\"#\n\x10GetGcsUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\")\n\x15\x42\x61tchGetGcsUrlRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\"U\n\x12UploadFileResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12%\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFile\"a\n\x11UploadUrlResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12%\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFile\x12\x0b\n\x03url\x18\x03 \x01(\t\"\"\n\x13\x44ownloadUrlResponse\x12\x0b\n\x03url\x18\x01 \x01(\t\"*\n\x11ShareLinkResponse\x12\x15\n\rfile_share_id\x18\x01 \x01(\t\"-\n\x10\x46ileListResponse\x12\x19\n\x05\x66iles\x18\x01 \x03(\x0b\x32\n.file.File\"g\n\x0fGetFileResponse\x12\x18\n\x04\x66ile\x18\x01 \x01(\x0b\x32\n.file.File\x12*\n\x0bupload_file\x18\x02 \x01(\x0b\x32\x10.file.UploadFileH\x00\x88\x01\x01\x42\x0e\n\x0c_upload_file\"H\n\x18\x42\x61tchDownloadUrlResponse\x12,\n\rdownload_urls\x18\x01 \x03(\x0b\x32\x15.file.DownloadUrlInfo\"`\n\x0f\x44ownloadUrlInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x11\n\tmime_type\x18\x03 \x01(\t\x12\x12\n\x05\x65rror\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"7\n\x11GetGcsUrlResponse\x12\x0f\n\x07gcs_url\x18\x01 \x01(\t\x12\x11\n\tmime_type\x18\x02 \x01(\t\"<\n\x16\x42\x61tchGetGcsUrlResponse\x12\"\n\x08gcs_urls\x18\x01 \x03(\x0b\x32\x10.file.GcsUrlInfo\"_\n\nGcsUrlInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x0f\n\x07gcs_url\x18\x02 \x01(\t\x12\x11\n\tmime_type\x18\x03 \x01(\t\x12\x12\n\x05\x65rror\x18\x04 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"+\n\x18\x43ompressionStatusRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\"\x84\x01\n\x19\x43ompressionStatusResponse\x12\x0e\n\x06status\x18\x01 \x01(\t\x12\x1a\n\rerror_message\x18\x02 \x01(\tH\x00\x88\x01\x01\x12)\n\x08variants\x18\x03 \x03(\x0b\x32\x17.file.CompressedVariantB\x10\n\x0e_error_message\"Q\n\x12GetVariantsRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x19\n\x0cvariant_type\x18\x02 \x01(\tH\x00\x88\x01\x01\x42\x0f\n\r_variant_type\"@\n\x13GetVariantsResponse\x12)\n\x08variants\x18\x01 \x03(\x0b\x32\x17.file.CompressedVariant\"\xc7\x02\n\x11\x43ompressedVariant\x12\x14\n\x0cvariant_name\x18\x01 \x01(\t\x12\x14\n\x0cvariant_type\x18\x02 \x01(\t\x12\x12\n\nmedia_type\x18\x03 \x01(\t\x12\r\n\x05width\x18\x04 \x01(\x05\x12\x0e\n\x06height\x18\x05 \x01(\x05\x12\x11\n\tfile_size\x18\x06 \x01(\x03\x12\x0e\n\x06\x66ormat\x18\x07 \x01(\t\x12\x14\n\x07quality\x18\x08 \x01(\x05H\x00\x88\x01\x01\x12\x15\n\x08\x64uration\x18\t \x01(\x01H\x01\x88\x01\x01\x12\x14\n\x07\x62itrate\x18\n \x01(\x03H\x02\x88\x01\x01\x12\x10\n\x03\x66ps\x18\x0b \x01(\x05H\x03\x88\x01\x01\x12\x19\n\x11\x63ompression_ratio\x18\x0c \x01(\x01\x12\x13\n\x0bstored_path\x18\r \x01(\tB\n\n\x08_qualityB\x0b\n\t_durationB\n\n\x08_bitrateB\x06\n\x04_fps\"Y\n\x14RecompressionRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x1c\n\x0f\x66orce_reprocess\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_force_reprocess\"8\n\x15RecompressionResponse\x12\x0f\n\x07task_id\x18\x01 \x01(\t\x12\x0e\n\x06status\x18\x02 \x01(\t\"\x92\x01\n\x19VariantDownloadUrlRequest\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x14\n\x0cvariant_name\x18\x02 \x01(\t\x12\x1b\n\x0e\x65xpire_seconds\x18\x03 \x01(\x05H\x00\x88\x01\x01\x12\x13\n\x06is_cdn\x18\x04 \x01(\x08H\x01\x88\x01\x01\x42\x11\n\x0f_expire_secondsB\t\n\x07_is_cdn\"\x8c\x01\n\x1aVariantDownloadUrlResponse\x12\x0b\n\x03url\x18\x01 \x01(\t\x12\x12\n\x05\x65rror\x18\x02 \x01(\tH\x00\x88\x01\x01\x12\x32\n\x0cvariant_info\x18\x03 \x01(\x0b\x32\x17.file.CompressedVariantH\x01\x88\x01\x01\x42\x08\n\x06_errorB\x0f\n\r_variant_info\"\\\n\x16\x42\x61tchFileStatusRequest\x12\x10\n\x08\x66ile_ids\x18\x01 \x03(\t\x12\x1c\n\x0finclude_details\x18\x02 \x01(\x08H\x00\x88\x01\x01\x42\x12\n\x10_include_details\"m\n\x17\x42\x61tchFileStatusResponse\x12&\n\x08statuses\x18\x01 \x03(\x0b\x32\x14.file.FileStatusInfo\x12\x11\n\ttimestamp\x18\x02 \x01(\x03\x12\x17\n\x0f\x63\x61\x63he_hit_count\x18\x03 \x01(\x05\"\x9d\x02\n\x0e\x46ileStatusInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12-\n\rupload_status\x18\x02 \x01(\x0e\x32\x16.file.FileUploadStatus\x12\x37\n\x12\x63ompression_status\x18\x03 \x01(\x0e\x32\x1b.file.FileCompressionStatus\x12)\n\x0bsync_status\x18\x04 \x01(\x0e\x32\x14.file.FileSyncStatus\x12-\n\x07\x64\x65tails\x18\x05 \x01(\x0b\x32\x17.file.FileStatusDetailsH\x00\x88\x01\x01\x12\x1a\n\rerror_message\x18\x06 \x01(\tH\x01\x88\x01\x01\x42\n\n\x08_detailsB\x10\n\x0e_error_message\"\xe9\x03\n\x11\x46ileStatusDetails\x12\x16\n\tfile_size\x18\x01 \x01(\x03H\x00\x88\x01\x01\x12\x19\n\x0cstorage_type\x18\x02 \x01(\tH\x01\x88\x01\x01\x12\x1b\n\x0estorage_region\x18\x03 \x01(\tH\x02\x88\x01\x01\x12 \n\x13\x63ompression_task_id\x18\x04 \x01(\tH\x03\x88\x01\x01\x12\'\n\x1a\x63ompression_variants_count\x18\x05 \x01(\x05H\x04\x88\x01\x01\x12!\n\x14\x63ompression_progress\x18\x06 \x01(\x01H\x05\x88\x01\x01\x12\x1f\n\x12sync_regions_total\x18\x07 \x01(\x05H\x06\x88\x01\x01\x12#\n\x16sync_regions_completed\x18\x08 \x01(\x05H\x07\x88\x01\x01\x12\x1c\n\x14sync_pending_regions\x18\t \x03(\tB\x0c\n\n_file_sizeB\x0f\n\r_storage_typeB\x11\n\x0f_storage_regionB\x16\n\x14_compression_task_idB\x1d\n\x1b_compression_variants_countB\x17\n\x15_compression_progressB\x15\n\x13_sync_regions_totalB\x19\n\x17_sync_regions_completed\"\x07\n\x05\x45mpty*\x95\x01\n\x10\x46ileUploadStatus\x12\x12\n\x0eUPLOAD_UNKNOWN\x10\x00\x12\x12\n\x0eUPLOAD_PENDING\x10\x01\x12\x15\n\x11UPLOAD_PROCESSING\x10\x02\x12\x14\n\x10UPLOAD_COMPLETED\x10\x03\x12\x11\n\rUPLOAD_FAILED\x10\x04\x12\x19\n\x15UPLOAD_FILE_NOT_FOUND\x10\x05*\xf1\x01\n\x15\x46ileCompressionStatus\x12\x17\n\x13\x43OMPRESSION_UNKNOWN\x10\x00\x12\x1e\n\x1a\x43OMPRESSION_NOT_APPLICABLE\x10\x01\x12\x17\n\x13\x43OMPRESSION_PENDING\x10\x02\x12\x1a\n\x16\x43OMPRESSION_PROCESSING\x10\x03\x12\x19\n\x15\x43OMPRESSION_COMPLETED\x10\x04\x12\x16\n\x12\x43OMPRESSION_FAILED\x10\x05\x12\x17\n\x13\x43OMPRESSION_SKIPPED\x10\x06\x12\x1e\n\x1a\x43OMPRESSION_FILE_NOT_FOUND\x10\x07*\xb0\x01\n\x0e\x46ileSyncStatus\x12\x10\n\x0cSYNC_UNKNOWN\x10\x00\x12\x15\n\x11SYNC_NOT_REQUIRED\x10\x01\x12\x10\n\x0cSYNC_PENDING\x10\x02\x12\x13\n\x0fSYNC_PROCESSING\x10\x03\x12\x10\n\x0cSYNC_PARTIAL\x10\x04\x12\x12\n\x0eSYNC_COMPLETED\x10\x05\x12\x0f\n\x0bSYNC_FAILED\x10\x06\x12\x17\n\x13SYNC_FILE_NOT_FOUND\x10\x07\x32\xda\n\n\x0b\x46ileService\x12?\n\nUploadFile\x12\x17.file.UploadFileRequest\x1a\x18.file.UploadFileResponse\x12\x44\n\x11GenerateUploadUrl\x12\x16.file.UploadUrlRequest\x1a\x17.file.UploadUrlResponse\x12M\n\x1aGenerateResumableUploadUrl\x12\x16.file.UploadUrlRequest\x1a\x17.file.UploadUrlResponse\x12\x43\n\x16\x43onfirmUploadCompleted\x12\x1c.file.UploadCompletedRequest\x1a\x0b.file.Empty\x12J\n\x13GenerateDownloadUrl\x12\x18.file.DownloadUrlRequest\x1a\x19.file.DownloadUrlResponse\x12Y\n\x18\x42\x61tchGenerateDownloadUrl\x12\x1d.file.BatchDownloadUrlRequest\x1a\x1e.file.BatchDownloadUrlResponse\x12<\n\tGetGcsUrl\x12\x16.file.GetGcsUrlRequest\x1a\x17.file.GetGcsUrlResponse\x12K\n\x0e\x42\x61tchGetGcsUrl\x12\x1b.file.BatchGetGcsUrlRequest\x1a\x1c.file.BatchGetGcsUrlResponse\x12\x44\n\x11GenerateShareLink\x12\x16.file.ShareLinkRequest\x1a\x17.file.ShareLinkResponse\x12\x30\n\tVisitFile\x12\x16.file.FileVisitRequest\x1a\x0b.file.Empty\x12\x36\n\x07GetFile\x12\x14.file.GetFileRequest\x1a\x15.file.GetFileResponse\x12\x31\n\nRenameFile\x12\x17.file.RenameFileRequest\x1a\n.file.File\x12\x32\n\nDeleteFile\x12\x17.file.DeleteFileRequest\x1a\x0b.file.Empty\x12;\n\tListFiles\x12\x16.file.ListFilesRequest\x1a\x16.file.FileListResponse\x12W\n\x14GetCompressionStatus\x12\x1e.file.CompressionStatusRequest\x1a\x1f.file.CompressionStatusResponse\x12L\n\x15GetCompressedVariants\x12\x18.file.GetVariantsRequest\x1a\x19.file.GetVariantsResponse\x12O\n\x14TriggerRecompression\x12\x1a.file.RecompressionRequest\x1a\x1b.file.RecompressionResponse\x12_\n\x1aGenerateVariantDownloadUrl\x12\x1f.file.VariantDownloadUrlRequest\x1a .file.VariantDownloadUrlResponse\x12Q\n\x12\x42\x61tchGetFileStatus\x12\x1c.file.BatchFileStatusRequest\x1a\x1d.file.BatchFileStatusResponseb\x06proto3')
|
|
30
30
|
|
|
31
31
|
_globals = globals()
|
|
32
32
|
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
|
|
33
33
|
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'file_service_pb2', _globals)
|
|
34
34
|
if not _descriptor._USE_C_DESCRIPTORS:
|
|
35
35
|
DESCRIPTOR._loaded_options = None
|
|
36
|
-
_globals['_FILEUPLOADSTATUS']._serialized_start=
|
|
37
|
-
_globals['_FILEUPLOADSTATUS']._serialized_end=
|
|
38
|
-
_globals['_FILECOMPRESSIONSTATUS']._serialized_start=
|
|
39
|
-
_globals['_FILECOMPRESSIONSTATUS']._serialized_end=
|
|
40
|
-
_globals['_FILESYNCSTATUS']._serialized_start=
|
|
41
|
-
_globals['_FILESYNCSTATUS']._serialized_end=
|
|
36
|
+
_globals['_FILEUPLOADSTATUS']._serialized_start=5196
|
|
37
|
+
_globals['_FILEUPLOADSTATUS']._serialized_end=5345
|
|
38
|
+
_globals['_FILECOMPRESSIONSTATUS']._serialized_start=5348
|
|
39
|
+
_globals['_FILECOMPRESSIONSTATUS']._serialized_end=5589
|
|
40
|
+
_globals['_FILESYNCSTATUS']._serialized_start=5592
|
|
41
|
+
_globals['_FILESYNCSTATUS']._serialized_end=5768
|
|
42
42
|
_globals['_FILE']._serialized_start=92
|
|
43
43
|
_globals['_FILE']._serialized_end=263
|
|
44
44
|
_globals['_UPLOADFILE']._serialized_start=266
|
|
@@ -119,6 +119,6 @@ if not _descriptor._USE_C_DESCRIPTORS:
|
|
|
119
119
|
_globals['_FILESTATUSDETAILS']._serialized_end=5184
|
|
120
120
|
_globals['_EMPTY']._serialized_start=5186
|
|
121
121
|
_globals['_EMPTY']._serialized_end=5193
|
|
122
|
-
_globals['_FILESERVICE']._serialized_start=
|
|
123
|
-
_globals['_FILESERVICE']._serialized_end=
|
|
122
|
+
_globals['_FILESERVICE']._serialized_start=5771
|
|
123
|
+
_globals['_FILESERVICE']._serialized_end=7141
|
|
124
124
|
# @@protoc_insertion_point(module_scope)
|
|
@@ -317,6 +317,7 @@ enum FileUploadStatus {
|
|
|
317
317
|
UPLOAD_PROCESSING = 2; // 上传中
|
|
318
318
|
UPLOAD_COMPLETED = 3; // 已完成
|
|
319
319
|
UPLOAD_FAILED = 4; // 失败
|
|
320
|
+
UPLOAD_FILE_NOT_FOUND = 5; // 文件不存在
|
|
320
321
|
}
|
|
321
322
|
|
|
322
323
|
// 文件压缩状态枚举
|
|
@@ -328,6 +329,7 @@ enum FileCompressionStatus {
|
|
|
328
329
|
COMPRESSION_COMPLETED = 4; // 已完成
|
|
329
330
|
COMPRESSION_FAILED = 5; // 失败
|
|
330
331
|
COMPRESSION_SKIPPED = 6; // 跳过压缩
|
|
332
|
+
COMPRESSION_FILE_NOT_FOUND = 7; // 文件不存在
|
|
331
333
|
}
|
|
332
334
|
|
|
333
335
|
// 文件同步状态枚举
|
|
@@ -335,10 +337,11 @@ enum FileSyncStatus {
|
|
|
335
337
|
SYNC_UNKNOWN = 0;
|
|
336
338
|
SYNC_NOT_REQUIRED = 1; // 不需要同步
|
|
337
339
|
SYNC_PENDING = 2; // 等待同步
|
|
338
|
-
SYNC_PROCESSING = 3; // 同步中
|
|
340
|
+
SYNC_PROCESSING = 3; // 同步中
|
|
339
341
|
SYNC_PARTIAL = 4; // 部分完成
|
|
340
342
|
SYNC_COMPLETED = 5; // 全部完成
|
|
341
343
|
SYNC_FAILED = 6; // 同步失败
|
|
344
|
+
SYNC_FILE_NOT_FOUND = 7; // 文件不存在
|
|
342
345
|
}
|
|
343
346
|
|
|
344
347
|
message Empty {}
|
|
@@ -181,6 +181,7 @@ class FileUploadStatus(str, Enum):
|
|
|
181
181
|
UPLOAD_PROCESSING = "UPLOAD_PROCESSING"
|
|
182
182
|
UPLOAD_COMPLETED = "UPLOAD_COMPLETED"
|
|
183
183
|
UPLOAD_FAILED = "UPLOAD_FAILED"
|
|
184
|
+
UPLOAD_FILE_NOT_FOUND = "UPLOAD_FILE_NOT_FOUND"
|
|
184
185
|
|
|
185
186
|
|
|
186
187
|
class FileCompressionStatus(str, Enum):
|
|
@@ -192,6 +193,7 @@ class FileCompressionStatus(str, Enum):
|
|
|
192
193
|
COMPRESSION_COMPLETED = "COMPRESSION_COMPLETED"
|
|
193
194
|
COMPRESSION_FAILED = "COMPRESSION_FAILED"
|
|
194
195
|
COMPRESSION_SKIPPED = "COMPRESSION_SKIPPED"
|
|
196
|
+
COMPRESSION_FILE_NOT_FOUND = "COMPRESSION_FILE_NOT_FOUND"
|
|
195
197
|
|
|
196
198
|
|
|
197
199
|
class FileSyncStatus(str, Enum):
|
|
@@ -203,6 +205,7 @@ class FileSyncStatus(str, Enum):
|
|
|
203
205
|
SYNC_PARTIAL = "SYNC_PARTIAL"
|
|
204
206
|
SYNC_COMPLETED = "SYNC_COMPLETED"
|
|
205
207
|
SYNC_FAILED = "SYNC_FAILED"
|
|
208
|
+
SYNC_FILE_NOT_FOUND = "SYNC_FILE_NOT_FOUND"
|
|
206
209
|
|
|
207
210
|
|
|
208
211
|
class FileStatusDetails(BaseModel):
|
|
@@ -1076,6 +1076,7 @@ class AsyncBlobService(BaseFileService):
|
|
|
1076
1076
|
2: FileUploadStatus.UPLOAD_PROCESSING,
|
|
1077
1077
|
3: FileUploadStatus.UPLOAD_COMPLETED,
|
|
1078
1078
|
4: FileUploadStatus.UPLOAD_FAILED,
|
|
1079
|
+
5: FileUploadStatus.UPLOAD_FILE_NOT_FOUND,
|
|
1079
1080
|
}
|
|
1080
1081
|
return status_map.get(proto_status, FileUploadStatus.UPLOAD_UNKNOWN)
|
|
1081
1082
|
|
|
@@ -1089,6 +1090,7 @@ class AsyncBlobService(BaseFileService):
|
|
|
1089
1090
|
4: FileCompressionStatus.COMPRESSION_COMPLETED,
|
|
1090
1091
|
5: FileCompressionStatus.COMPRESSION_FAILED,
|
|
1091
1092
|
6: FileCompressionStatus.COMPRESSION_SKIPPED,
|
|
1093
|
+
7: FileCompressionStatus.COMPRESSION_FILE_NOT_FOUND,
|
|
1092
1094
|
}
|
|
1093
1095
|
return status_map.get(proto_status, FileCompressionStatus.COMPRESSION_UNKNOWN)
|
|
1094
1096
|
|
|
@@ -1102,5 +1104,6 @@ class AsyncBlobService(BaseFileService):
|
|
|
1102
1104
|
4: FileSyncStatus.SYNC_PARTIAL,
|
|
1103
1105
|
5: FileSyncStatus.SYNC_COMPLETED,
|
|
1104
1106
|
6: FileSyncStatus.SYNC_FAILED,
|
|
1107
|
+
7: FileSyncStatus.SYNC_FILE_NOT_FOUND,
|
|
1105
1108
|
}
|
|
1106
1109
|
return status_map.get(proto_status, FileSyncStatus.SYNC_UNKNOWN)
|
|
@@ -1074,6 +1074,7 @@ class SyncBlobService(BaseFileService):
|
|
|
1074
1074
|
2: FileUploadStatus.UPLOAD_PROCESSING,
|
|
1075
1075
|
3: FileUploadStatus.UPLOAD_COMPLETED,
|
|
1076
1076
|
4: FileUploadStatus.UPLOAD_FAILED,
|
|
1077
|
+
5: FileUploadStatus.UPLOAD_FILE_NOT_FOUND,
|
|
1077
1078
|
}
|
|
1078
1079
|
return status_map.get(proto_status, FileUploadStatus.UPLOAD_UNKNOWN)
|
|
1079
1080
|
|
|
@@ -1087,6 +1088,7 @@ class SyncBlobService(BaseFileService):
|
|
|
1087
1088
|
4: FileCompressionStatus.COMPRESSION_COMPLETED,
|
|
1088
1089
|
5: FileCompressionStatus.COMPRESSION_FAILED,
|
|
1089
1090
|
6: FileCompressionStatus.COMPRESSION_SKIPPED,
|
|
1091
|
+
7: FileCompressionStatus.COMPRESSION_FILE_NOT_FOUND,
|
|
1090
1092
|
}
|
|
1091
1093
|
return status_map.get(proto_status, FileCompressionStatus.COMPRESSION_UNKNOWN)
|
|
1092
1094
|
|
|
@@ -1100,5 +1102,6 @@ class SyncBlobService(BaseFileService):
|
|
|
1100
1102
|
4: FileSyncStatus.SYNC_PARTIAL,
|
|
1101
1103
|
5: FileSyncStatus.SYNC_COMPLETED,
|
|
1102
1104
|
6: FileSyncStatus.SYNC_FAILED,
|
|
1105
|
+
7: FileSyncStatus.SYNC_FILE_NOT_FOUND,
|
|
1103
1106
|
}
|
|
1104
1107
|
return status_map.get(proto_status, FileSyncStatus.SYNC_UNKNOWN)
|
|
@@ -2,7 +2,7 @@ from setuptools import setup, find_packages
|
|
|
2
2
|
|
|
3
3
|
setup(
|
|
4
4
|
name="tamar-file-hub-client",
|
|
5
|
-
version="0.1
|
|
5
|
+
version="0.2.1",
|
|
6
6
|
description="A Python SDK for gRPC-based file management system",
|
|
7
7
|
long_description=open("README.md", encoding="utf-8").read(),
|
|
8
8
|
long_description_content_type="text/markdown",
|
|
@@ -22,7 +22,7 @@ setup(
|
|
|
22
22
|
install_requires=[
|
|
23
23
|
"grpcio>=1.67.1",
|
|
24
24
|
"grpcio-tools>=1.67.1",
|
|
25
|
-
"protobuf>=
|
|
25
|
+
"protobuf>=5.29.4",
|
|
26
26
|
"pydantic>=2.0.0",
|
|
27
27
|
"typing-extensions>=4.0.0;python_version<'3.10'",
|
|
28
28
|
"requests>=2.28.0",
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1/tamar_file_hub_client.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tamar-file-hub-client
|
|
3
|
-
Version: 0.1
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: A Python SDK for gRPC-based file management system
|
|
5
5
|
Home-page: https://github.com/Tamar-Edge-AI/file-hub-client
|
|
6
6
|
Author: Oscar Ou
|
|
@@ -25,7 +25,7 @@ Requires-Python: >=3.8
|
|
|
25
25
|
Description-Content-Type: text/markdown
|
|
26
26
|
Requires-Dist: grpcio>=1.67.1
|
|
27
27
|
Requires-Dist: grpcio-tools>=1.67.1
|
|
28
|
-
Requires-Dist: protobuf>=
|
|
28
|
+
Requires-Dist: protobuf>=5.29.4
|
|
29
29
|
Requires-Dist: pydantic>=2.0.0
|
|
30
30
|
Requires-Dist: typing-extensions>=4.0.0; python_version < "3.10"
|
|
31
31
|
Requires-Dist: requests>=2.28.0
|
|
@@ -63,6 +63,7 @@ Dynamic: summary
|
|
|
63
63
|
- 📝 **类型注解**:完整的类型提示支持
|
|
64
64
|
- 🧩 **模块化设计**:清晰的代码结构,易于扩展
|
|
65
65
|
- 🎨 **图片和视频压缩**:支持多种规格的媒体文件压缩变体生成和管理
|
|
66
|
+
- 📊 **批量状态查询**:支持批量查询文件的上传、压缩、备份同步状态
|
|
66
67
|
- 🏗️ **分层服务架构**:文件服务分为传统文件(blob)和自定义类型(结构化数据),每种类型独立服务,语义清晰
|
|
67
68
|
- 🔧 **环境变量配置**:支持通过环境变量配置所有参数
|
|
68
69
|
- 👤 **用户上下文管理**:支持区分资源所有权(ownership)和操作者(operator)
|
|
@@ -214,6 +215,7 @@ File Hub Client 采用分层服务架构,将文件服务按类型和语义进
|
|
|
214
215
|
- 支持临时文件上传
|
|
215
216
|
- **媒体文件压缩**:支持图片和视频的多规格压缩变体生成
|
|
216
217
|
- **压缩管理**:获取压缩状态、管理变体、触发重新压缩
|
|
218
|
+
- **批量文件状态查询**:一次性查询多个文件的上传、压缩、同步状态
|
|
217
219
|
- 适用类型:PDF、图片、视频、音频、压缩包等
|
|
218
220
|
- **file_service**: 处理文件元数据操作(所有类型通用)
|
|
219
221
|
- 获取、重命名、删除文件
|
|
@@ -253,6 +255,12 @@ File Hub Client 采用分层服务架构,将文件服务按类型和语义进
|
|
|
253
255
|
- `GetVariantsResponse`: 获取变体响应
|
|
254
256
|
- `RecompressionResponse`: 重新压缩响应
|
|
255
257
|
- `VariantDownloadUrlResponse`: 变体下载URL响应
|
|
258
|
+
- `BatchFileStatusResponse`: 批量文件状态响应
|
|
259
|
+
- `FileStatusInfo`: 单个文件状态信息
|
|
260
|
+
- `FileStatusDetails`: 文件状态详细信息
|
|
261
|
+
- `FileUploadStatus`: 文件上传状态枚举
|
|
262
|
+
- `FileCompressionStatus`: 文件压缩状态枚举
|
|
263
|
+
- `FileSyncStatus`: 文件同步状态枚举
|
|
256
264
|
|
|
257
265
|
- **folder.py**: 文件夹相关的数据模型
|
|
258
266
|
- `FolderInfo`: 文件夹信息
|
|
@@ -1031,6 +1039,184 @@ with TamarFileHubClient() as client:
|
|
|
1031
1039
|
- 支持重新压缩以应用新的压缩设置
|
|
1032
1040
|
- 批量状态查询减少网络请求
|
|
1033
1041
|
|
|
1042
|
+
### 批量文件状态查询
|
|
1043
|
+
|
|
1044
|
+
File Hub Client 提供了高效的批量文件状态查询功能,可以一次性获取多个文件的上传、压缩、同步状态:
|
|
1045
|
+
|
|
1046
|
+
#### 基础批量查询
|
|
1047
|
+
|
|
1048
|
+
```python
|
|
1049
|
+
from file_hub_client import AsyncTamarFileHubClient
|
|
1050
|
+
|
|
1051
|
+
async with AsyncTamarFileHubClient() as client:
|
|
1052
|
+
client.set_user_context(org_id="123", user_id="456")
|
|
1053
|
+
|
|
1054
|
+
# 批量查询多个文件的状态
|
|
1055
|
+
file_ids = ["file-id-1", "file-id-2", "file-id-3"]
|
|
1056
|
+
response = await client.blobs.batch_get_file_status(
|
|
1057
|
+
file_ids=file_ids,
|
|
1058
|
+
include_details=False # 是否包含详细信息,默认False
|
|
1059
|
+
)
|
|
1060
|
+
|
|
1061
|
+
print(f"查询时间戳: {response.timestamp}")
|
|
1062
|
+
print(f"缓存命中数量: {response.cache_hit_count}")
|
|
1063
|
+
print(f"查询到 {len(response.statuses)} 个文件状态")
|
|
1064
|
+
|
|
1065
|
+
for status in response.statuses:
|
|
1066
|
+
print(f"文件ID: {status.file_id}")
|
|
1067
|
+
print(f" 上传状态: {status.upload_status.value}")
|
|
1068
|
+
print(f" 压缩状态: {status.compression_status.value}")
|
|
1069
|
+
print(f" 同步状态: {status.sync_status.value}")
|
|
1070
|
+
|
|
1071
|
+
if status.error_message:
|
|
1072
|
+
print(f" 错误信息: {status.error_message}")
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1075
|
+
#### 详细信息查询
|
|
1076
|
+
|
|
1077
|
+
```python
|
|
1078
|
+
# 查询详细状态信息
|
|
1079
|
+
detailed_response = await client.blobs.batch_get_file_status(
|
|
1080
|
+
file_ids=file_ids,
|
|
1081
|
+
include_details=True # 包含详细信息
|
|
1082
|
+
)
|
|
1083
|
+
|
|
1084
|
+
for status in detailed_response.statuses:
|
|
1085
|
+
print(f"文件ID: {status.file_id}")
|
|
1086
|
+
print(f" 上传状态: {status.upload_status.value}")
|
|
1087
|
+
print(f" 压缩状态: {status.compression_status.value}")
|
|
1088
|
+
print(f" 同步状态: {status.sync_status.value}")
|
|
1089
|
+
|
|
1090
|
+
if status.details:
|
|
1091
|
+
print(" 详细信息:")
|
|
1092
|
+
if status.details.file_size:
|
|
1093
|
+
print(f" 文件大小: {status.details.file_size} 字节")
|
|
1094
|
+
if status.details.storage_type:
|
|
1095
|
+
print(f" 存储类型: {status.details.storage_type}")
|
|
1096
|
+
if status.details.storage_region:
|
|
1097
|
+
print(f" 存储区域: {status.details.storage_region}")
|
|
1098
|
+
|
|
1099
|
+
# 压缩相关详细信息
|
|
1100
|
+
if status.details.compression_task_id:
|
|
1101
|
+
print(f" 压缩任务ID: {status.details.compression_task_id}")
|
|
1102
|
+
if status.details.compression_variants_count is not None:
|
|
1103
|
+
print(f" 压缩变体数量: {status.details.compression_variants_count}")
|
|
1104
|
+
if status.details.compression_progress is not None:
|
|
1105
|
+
print(f" 压缩进度: {status.details.compression_progress * 100:.1f}%")
|
|
1106
|
+
|
|
1107
|
+
# 同步相关详细信息
|
|
1108
|
+
if status.details.sync_regions_total is not None:
|
|
1109
|
+
print(f" 同步区域总数: {status.details.sync_regions_total}")
|
|
1110
|
+
if status.details.sync_regions_completed is not None:
|
|
1111
|
+
print(f" 已完成同步区域: {status.details.sync_regions_completed}")
|
|
1112
|
+
if status.details.sync_pending_regions:
|
|
1113
|
+
print(f" 待同步区域: {', '.join(status.details.sync_pending_regions)}")
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
#### 状态筛选和分析
|
|
1117
|
+
|
|
1118
|
+
```python
|
|
1119
|
+
from file_hub_client.schemas import (
|
|
1120
|
+
FileUploadStatus,
|
|
1121
|
+
FileCompressionStatus,
|
|
1122
|
+
FileSyncStatus
|
|
1123
|
+
)
|
|
1124
|
+
|
|
1125
|
+
# 查询文件状态
|
|
1126
|
+
response = await client.blobs.batch_get_file_status(file_ids=file_ids)
|
|
1127
|
+
|
|
1128
|
+
# 筛选出上传失败的文件
|
|
1129
|
+
failed_uploads = [
|
|
1130
|
+
status for status in response.statuses
|
|
1131
|
+
if status.upload_status == FileUploadStatus.UPLOAD_FAILED
|
|
1132
|
+
]
|
|
1133
|
+
|
|
1134
|
+
# 筛选出正在处理的文件
|
|
1135
|
+
processing_files = [
|
|
1136
|
+
status for status in response.statuses
|
|
1137
|
+
if (status.upload_status == FileUploadStatus.UPLOAD_PROCESSING or
|
|
1138
|
+
status.compression_status == FileCompressionStatus.COMPRESSION_PROCESSING or
|
|
1139
|
+
status.sync_status == FileSyncStatus.SYNC_PROCESSING)
|
|
1140
|
+
]
|
|
1141
|
+
|
|
1142
|
+
# 筛选出压缩不适用的文件(非图片/视频)
|
|
1143
|
+
non_compressible_files = [
|
|
1144
|
+
status for status in response.statuses
|
|
1145
|
+
if status.compression_status == FileCompressionStatus.COMPRESSION_NOT_APPLICABLE
|
|
1146
|
+
]
|
|
1147
|
+
|
|
1148
|
+
print(f"上传失败的文件: {len(failed_uploads)} 个")
|
|
1149
|
+
print(f"正在处理的文件: {len(processing_files)} 个")
|
|
1150
|
+
print(f"非媒体文件: {len(non_compressible_files)} 个")
|
|
1151
|
+
```
|
|
1152
|
+
|
|
1153
|
+
#### 同步客户端示例
|
|
1154
|
+
|
|
1155
|
+
```python
|
|
1156
|
+
from file_hub_client import TamarFileHubClient
|
|
1157
|
+
|
|
1158
|
+
with TamarFileHubClient() as client:
|
|
1159
|
+
client.set_user_context(org_id="123", user_id="456")
|
|
1160
|
+
|
|
1161
|
+
# 同步批量查询
|
|
1162
|
+
response = client.blobs.batch_get_file_status(
|
|
1163
|
+
file_ids=["file-1", "file-2", "file-3"],
|
|
1164
|
+
include_details=True
|
|
1165
|
+
)
|
|
1166
|
+
|
|
1167
|
+
for status in response.statuses:
|
|
1168
|
+
print(f"文件 {status.file_id[:8]}...")
|
|
1169
|
+
print(f" 状态: {status.upload_status.value}")
|
|
1170
|
+
|
|
1171
|
+
if status.details:
|
|
1172
|
+
print(f" 大小: {status.details.file_size} bytes")
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
#### 状态枚举说明
|
|
1176
|
+
|
|
1177
|
+
**上传状态 (FileUploadStatus):**
|
|
1178
|
+
- `UPLOAD_UNKNOWN`: 未知状态
|
|
1179
|
+
- `UPLOAD_PENDING`: 待上传
|
|
1180
|
+
- `UPLOAD_PROCESSING`: 上传中
|
|
1181
|
+
- `UPLOAD_COMPLETED`: 已完成
|
|
1182
|
+
- `UPLOAD_FAILED`: 失败
|
|
1183
|
+
|
|
1184
|
+
**压缩状态 (FileCompressionStatus):**
|
|
1185
|
+
- `COMPRESSION_UNKNOWN`: 未知状态
|
|
1186
|
+
- `COMPRESSION_NOT_APPLICABLE`: 不需要压缩(非图片/视频文件)
|
|
1187
|
+
- `COMPRESSION_PENDING`: 等待压缩
|
|
1188
|
+
- `COMPRESSION_PROCESSING`: 压缩中
|
|
1189
|
+
- `COMPRESSION_COMPLETED`: 已完成
|
|
1190
|
+
- `COMPRESSION_FAILED`: 失败
|
|
1191
|
+
- `COMPRESSION_SKIPPED`: 跳过压缩
|
|
1192
|
+
|
|
1193
|
+
**同步状态 (FileSyncStatus):**
|
|
1194
|
+
- `SYNC_UNKNOWN`: 未知状态
|
|
1195
|
+
- `SYNC_NOT_REQUIRED`: 不需要同步
|
|
1196
|
+
- `SYNC_PENDING`: 等待同步
|
|
1197
|
+
- `SYNC_PROCESSING`: 同步中
|
|
1198
|
+
- `SYNC_PARTIAL`: 部分完成
|
|
1199
|
+
- `SYNC_COMPLETED`: 全部完成
|
|
1200
|
+
- `SYNC_FAILED`: 同步失败
|
|
1201
|
+
|
|
1202
|
+
#### 使用场景
|
|
1203
|
+
|
|
1204
|
+
1. **文件处理监控**:
|
|
1205
|
+
- 实时监控文件上传、压缩、同步进度
|
|
1206
|
+
- 及时发现和处理失败的文件
|
|
1207
|
+
|
|
1208
|
+
2. **批量状态查询**:
|
|
1209
|
+
- 一次查询最多100个文件状态
|
|
1210
|
+
- 减少网络请求,提高性能
|
|
1211
|
+
|
|
1212
|
+
3. **业务流程控制**:
|
|
1213
|
+
- 根据文件状态决定后续业务逻辑
|
|
1214
|
+
- 确保文件完全准备就绪后再进行下一步操作
|
|
1215
|
+
|
|
1216
|
+
4. **性能优化**:
|
|
1217
|
+
- 利用缓存机制提高查询效率
|
|
1218
|
+
- 支持详细信息的按需获取
|
|
1219
|
+
|
|
1034
1220
|
### 文件管理操作
|
|
1035
1221
|
|
|
1036
1222
|
File Hub Client 提供了完整的文件管理功能,通过 `files` 服务访问:
|
|
@@ -2378,6 +2564,7 @@ MIT License
|
|
|
2378
2564
|
- **断点续传修复**: 解决断点续传中的HTTP头部和签名验证问题
|
|
2379
2565
|
- **AI生成文件支持**: 完善对AI生成内容(图片、视频、音频)的MIME类型处理
|
|
2380
2566
|
- **新功能**: 新增 `mime_type` 参数支持,允许用户显式指定文件MIME类型
|
|
2567
|
+
- **批量文件状态查询**: 新增 `batch_get_file_status` API,支持批量查询文件上传、压缩、同步状态
|
|
2381
2568
|
- **魔术字节检测**: 增强内容检测,支持26+种主流文件格式的自动识别
|
|
2382
2569
|
- **向下兼容**: 保持100%向下兼容,现有代码无需修改
|
|
2383
2570
|
- **核心修复**:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/enums/__init__.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/enums/export_format.py
RENAMED
|
File without changes
|
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/enums/upload_mode.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/errors/__init__.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/errors/exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/async_client.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/gen/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/interceptors.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/rpc/sync_client.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/schemas/__init__.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/schemas/context.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/schemas/folder.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/schemas/taple.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/services/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/__init__.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/converter.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/download_helper.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/file_utils.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/idempotency.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/ip_detector.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/logging.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/smart_retry.py
RENAMED
|
File without changes
|
{tamar_file_hub_client-0.1.9 → tamar_file_hub_client-0.2.1}/file_hub_client/utils/upload_helper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|