tamar-file-hub-client 0.0.1__py3-none-any.whl → 0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. file_hub_client/__init__.py +39 -0
  2. file_hub_client/client.py +43 -6
  3. file_hub_client/rpc/async_client.py +91 -11
  4. file_hub_client/rpc/gen/taple_service_pb2.py +225 -0
  5. file_hub_client/rpc/gen/taple_service_pb2_grpc.py +1626 -0
  6. file_hub_client/rpc/generate_grpc.py +2 -2
  7. file_hub_client/rpc/interceptors.py +550 -0
  8. file_hub_client/rpc/protos/taple_service.proto +874 -0
  9. file_hub_client/rpc/sync_client.py +91 -9
  10. file_hub_client/schemas/__init__.py +60 -0
  11. file_hub_client/schemas/taple.py +413 -0
  12. file_hub_client/services/__init__.py +5 -0
  13. file_hub_client/services/file/async_blob_service.py +558 -482
  14. file_hub_client/services/file/async_file_service.py +18 -9
  15. file_hub_client/services/file/base_file_service.py +19 -6
  16. file_hub_client/services/file/sync_blob_service.py +554 -478
  17. file_hub_client/services/file/sync_file_service.py +18 -9
  18. file_hub_client/services/folder/async_folder_service.py +20 -11
  19. file_hub_client/services/folder/sync_folder_service.py +20 -11
  20. file_hub_client/services/taple/__init__.py +10 -0
  21. file_hub_client/services/taple/async_taple_service.py +2281 -0
  22. file_hub_client/services/taple/base_taple_service.py +353 -0
  23. file_hub_client/services/taple/idempotent_taple_mixin.py +142 -0
  24. file_hub_client/services/taple/sync_taple_service.py +2256 -0
  25. file_hub_client/utils/__init__.py +43 -1
  26. file_hub_client/utils/file_utils.py +59 -11
  27. file_hub_client/utils/idempotency.py +196 -0
  28. file_hub_client/utils/logging.py +315 -0
  29. file_hub_client/utils/retry.py +241 -2
  30. file_hub_client/utils/smart_retry.py +403 -0
  31. tamar_file_hub_client-0.0.2.dist-info/METADATA +2050 -0
  32. tamar_file_hub_client-0.0.2.dist-info/RECORD +57 -0
  33. tamar_file_hub_client-0.0.1.dist-info/METADATA +0 -874
  34. tamar_file_hub_client-0.0.1.dist-info/RECORD +0 -44
  35. {tamar_file_hub_client-0.0.1.dist-info → tamar_file_hub_client-0.0.2.dist-info}/WHEEL +0 -0
  36. {tamar_file_hub_client-0.0.1.dist-info → tamar_file_hub_client-0.0.2.dist-info}/top_level.txt +0 -0
@@ -1,874 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: tamar-file-hub-client
3
- Version: 0.0.1
4
- Summary: A Python SDK for gRPC-based file management system
5
- Home-page: https://github.com/Tamar-Edge-AI/file-hub-client
6
- Author: Oscar Ou
7
- Author-email: oscar.ou@tamaredge.ai
8
- License: MIT
9
- Classifier: Development Status :: 4 - Beta
10
- Classifier: Intended Audience :: Developers
11
- Classifier: License :: OSI Approved :: MIT License
12
- Classifier: Operating System :: OS Independent
13
- Classifier: Programming Language :: Python :: 3
14
- Classifier: Programming Language :: Python :: 3.8
15
- Classifier: Programming Language :: Python :: 3.9
16
- Classifier: Programming Language :: Python :: 3.10
17
- Classifier: Programming Language :: Python :: 3.11
18
- Classifier: Programming Language :: Python :: 3.12
19
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
20
- Classifier: Topic :: Internet :: WWW/HTTP
21
- Classifier: Topic :: Communications :: File Sharing
22
- Classifier: Framework :: AsyncIO
23
- Classifier: Typing :: Typed
24
- Requires-Python: >=3.8
25
- Description-Content-Type: text/markdown
26
- Requires-Dist: grpcio>=1.67.1
27
- Requires-Dist: grpcio-tools>=1.67.1
28
- Requires-Dist: protobuf>=4.21.0
29
- Requires-Dist: pydantic>=2.0.0
30
- Requires-Dist: typing-extensions>=4.0.0; python_version < "3.10"
31
- Requires-Dist: requests>=2.28.0
32
- Requires-Dist: aiohttp>=3.8.0
33
- Requires-Dist: aiofiles>=23.0.0
34
- Dynamic: author
35
- Dynamic: author-email
36
- Dynamic: classifier
37
- Dynamic: description
38
- Dynamic: description-content-type
39
- Dynamic: home-page
40
- Dynamic: license
41
- Dynamic: requires-dist
42
- Dynamic: requires-python
43
- Dynamic: summary
44
-
45
- # File Hub Client
46
-
47
- 一个基于 gRPC 的文件管理系统 Python SDK,提供异步和同步两种客户端实现。
48
-
49
- ## 功能特性
50
-
51
- - 🚀 **双模式支持**:提供异步(AsyncIO)和同步两种客户端实现
52
- - 📁 **完整的文件管理**:支持文件上传、下载、重命名、删除等操作
53
- - 📂 **文件夹管理**:支持文件夹的创建、重命名、移动、删除
54
- - 🔗 **文件分享**:支持生成分享链接,设置访问权限和密码
55
- - 🔄 **多种上传方式**:支持直传、断点续传、客户端直传到对象存储
56
- - 🛡️ **错误处理**:完善的异常体系和错误重试机制
57
- - 🔒 **TLS/SSL 支持**:支持安全的加密连接,保护数据传输
58
- - 🔁 **自动重试**:连接失败时自动重试,提高可靠性
59
- - 📝 **类型注解**:完整的类型提示支持
60
- - 🧩 **模块化设计**:清晰的代码结构,易于扩展
61
- - 🏗️ **分层服务架构**:文件服务分为传统文件(blob)和自定义类型(结构化数据),每种类型独立服务,语义清晰
62
- - 🔧 **环境变量配置**:支持通过环境变量配置所有参数
63
- - 👤 **用户上下文管理**:支持区分资源所有权(ownership)和操作者(operator)
64
- - 📊 **请求上下文追踪**:自动收集客户端信息,支持请求追踪和审计
65
-
66
- ## 项目结构
67
-
68
- ```
69
- file-hub-client/
70
- ├── file_hub_client/ # 主包目录
71
- │ ├── __init__.py # 包初始化,导出版本信息和主要类
72
- │ ├── client.py # 客户端入口(AsyncTamarFileHubClient, TamarFileHubClient)
73
- │ ├── py.typed # PEP 561 类型标记文件
74
- │ │
75
- │ ├── rpc/ # gRPC 相关
76
- │ │ ├── __init__.py # RPC 模块初始化
77
- │ │ ├── async_client.py # 异步 gRPC 客户端基类
78
- │ │ ├── sync_client.py # 同步 gRPC 客户端基类
79
- │ │ ├── generate_grpc.py # Proto 文件代码生成脚本
80
- │ │ ├── protos/ # Protocol Buffer 定义
81
- │ │ │ ├── file_service.proto # 文件服务定义
82
- │ │ │ └── folder_service.proto # 文件夹服务定义
83
- │ │ └── gen/ # 生成的 gRPC 代码(自动生成)
84
- │ │ ├── __init__.py
85
- │ │ ├── file_service_pb2.py
86
- │ │ ├── file_service_pb2_grpc.py
87
- │ │ ├── folder_service_pb2.py
88
- │ │ └── folder_service_pb2_grpc.py
89
- │ │
90
- │ ├── services/ # 服务层(分层架构:传统文件用blob_service,自定义类型独立service)
91
- │ │ ├── __init__.py # 服务模块导出
92
- │ │ ├── file/ # 文件服务(统一入口,按类型分层)
93
- │ │ │ ├── __init__.py
94
- │ │ │ ├── base_file_service.py # 文件服务基类
95
- │ │ │ ├── async_blob_service.py # 异步二进制大对象服务(传统文件上传下载)
96
- │ │ │ ├── sync_blob_service.py # 同步二进制大对象服务(传统文件上传下载)
97
- │ │ │ ├── async_file_service.py # 异步文件元数据服务(所有类型通用)
98
- │ │ │ └── sync_file_service.py # 同步文件元数据服务(所有类型通用)
99
- │ │ │ # 未来扩展:spreadsheet_service, document_service, canvas_service等
100
- │ │ └── folder/ # 文件夹服务
101
- │ │ ├── __init__.py
102
- │ │ ├── async_folder_service.py # 异步文件夹服务实现
103
- │ │ └── sync_folder_service.py # 同步文件夹服务实现
104
- │ │
105
- │ ├── schemas/ # 数据模型(Pydantic)
106
- │ │ ├── __init__.py # 模型导出
107
- │ │ ├── file.py # 文件相关模型
108
- │ │ ├── folder.py # 文件夹相关模型
109
- │ │ └── context.py # 上下文相关模型(用户和请求上下文)
110
- │ │
111
- │ ├── enums/ # 枚举定义
112
- │ │ ├── __init__.py # 枚举导出
113
- │ │ ├── role.py # 角色枚举(ACCOUNT, AGENT, SYSTEM)
114
- │ │ ├── upload_mode.py # 上传模式枚举
115
- │ │ └── export_format.py # 导出格式枚举
116
- │ │
117
- │ ├── errors/ # 异常定义
118
- │ │ ├── __init__.py # 异常导出
119
- │ │ └── exceptions.py # 自定义异常类
120
- │ │
121
- │ └── utils/ # 工具函数
122
- │ ├── __init__.py # 工具函数导出
123
- │ ├── file_utils.py # 文件操作工具
124
- │ ├── converter.py # 数据转换工具
125
- │ ├── retry.py # 重试装饰器
126
- │ ├── upload_helper.py # 上传辅助工具(HTTP上传器)
127
- │ └── download_helper.py # 下载辅助工具(HTTP下载器)
128
-
129
- ├── .gitignore # Git 忽略文件配置
130
- ├── .env.example # 环境变量配置示例
131
- ├── README.md # 项目说明文档(本文件)
132
- ├── setup.py # 安装配置文件
133
- ├── pyproject.toml # 项目配置文件(PEP 518)
134
- └── MANIFEST.in # 打包配置文件
135
- ```
136
-
137
- ## 模块说明
138
-
139
- ### 核心模块
140
-
141
- - **client.py**: 提供 `AsyncTamarFileHubClient` 和 `TamarFileHubClient` 两个客户端类,是使用 SDK 的入口点
142
- - 提供了预配置的单例客户端 `tamar_client` 和 `async_tamar_client`
143
- - 支持分层服务访问:
144
- - `blobs`(传统文件内容:上传/下载)
145
- - `files`(文件元数据:所有类型通用的管理操作)
146
- - `folders`(文件夹管理)
147
- - 未来扩展:`spreadsheets`、`documents`、`canvases` 等自定义类型服务
148
-
149
- ### RPC 模块 (`rpc/`)
150
-
151
- - **async_client.py/sync_client.py**: gRPC 客户端基类,处理连接管理、元数据构建、stub 缓存
152
- - **generate_grpc.py**: 从 proto 文件生成 Python 代码的脚本
153
- - **protos/**: 存放 Protocol Buffer 定义文件
154
- - `file_service.proto`: 定义文件相关的 RPC 服务
155
- - `folder_service.proto`: 定义文件夹相关的 RPC 服务
156
-
157
- ### 服务模块 (`services/`)
158
-
159
- #### 分层服务架构设计
160
-
161
- File Hub Client 采用分层服务架构,将文件服务按类型和语义进行清晰分离:
162
-
163
- **📁 统一文件入口**:所有文件类型都通过统一的 `files` 接口进行元数据管理(获取、重命名、删除、列表等)
164
-
165
- **🔄 按类型分层服务**:
166
- - **传统文件类型**(PDF、图片、视频等)→ `blob_service` 处理
167
- - 核心操作:**上传** 和 **下载**
168
- - 特点:二进制数据,重点是存储和传输
169
-
170
- - **自定义文件类型**(在线表格、文档、画布等)→ 每种类型独立 `service`
171
- - 核心操作:**新增** 和 **导出**
172
- - 特点:结构化数据,重点是数据操作和格式转换
173
-
174
- **🎯 设计优势**:
175
- - **语义清晰**:不同类型的文件使用不同的操作语义,更符合实际使用场景
176
- - **易于扩展**:新增自定义文件类型时,只需添加对应的独立服务
177
- - **职责分离**:每个服务专注于特定类型的操作,代码更易维护
178
- - **SDK 友好**:为 SDK 使用者提供更直观的 API 设计,而非通用的 REST API
179
-
180
- #### 具体实现
181
-
182
- - **file/**: 文件服务实现
183
- - **blob_service**: 处理传统文件(二进制大对象)
184
- - 支持多种上传模式(普通上传、流式上传、断点续传)
185
- - 智能选择上传模式(根据文件大小)
186
- - 生成上传/下载 URL
187
- - 支持临时文件上传
188
- - 适用类型:PDF、图片、视频、音频、压缩包等
189
- - **file_service**: 处理文件元数据操作(所有类型通用)
190
- - 获取、重命名、删除文件
191
- - 列出文件
192
- - 生成分享链接
193
- - 记录文件访问
194
- - **[future] spreadsheet_service**: 在线表格服务(规划中)
195
- - 创建表格、编辑单元格、插入行列
196
- - 导出为 Excel、CSV 等格式
197
- - **[future] document_service**: 在线文档服务(规划中)
198
- - 创建文档、编辑内容、插入元素
199
- - 导出为 Word、PDF、HTML 等格式
200
- - **[future] canvas_service**: 画布服务(规划中)
201
- - 创建画布、绘制图形、添加元素
202
- - 导出为 PNG、SVG、PDF 等格式
203
-
204
- - **folder/**: 文件夹服务实现
205
- - 创建、重命名、移动、删除文件夹
206
- - 列出文件夹内容
207
-
208
- ### 数据模型 (`schemas/`)
209
-
210
- - **file.py**: 文件相关的数据模型
211
- - `File`: 文件信息
212
- - `FileUploadResponse`: 文件上传响应
213
- - `UploadUrlResponse`: URL上传响应
214
- - `ShareLinkRequest`: 分享链接请求
215
- - `FileListResponse`: 文件列表响应
216
-
217
- - **folder.py**: 文件夹相关的数据模型
218
- - `FolderInfo`: 文件夹信息
219
- - `FolderListResponse`: 文件夹列表响应
220
-
221
- - **context.py**: 上下文相关的数据模型
222
- - `UserContext`: 用户上下文(组织、用户、角色、操作者)
223
- - `RequestContext`: 请求上下文(请求ID、客户端信息、追踪信息)
224
- - `FullContext`: 完整上下文
225
-
226
- ### 枚举定义 (`enums/`)
227
-
228
- - **role.py**: 用户角色枚举(ACCOUNT、AGENT、SYSTEM)
229
- - **upload_mode.py**: 上传模式枚举(NORMAL、STREAM、RESUMABLE)
230
- - **export_format.py**: 导出格式枚举(PDF、DOCX、HTML、MARKDOWN、JSON)
231
-
232
- ### 工具模块 (`utils/`)
233
-
234
- - **file_utils.py**: 文件操作相关工具函数
235
- - `get_file_mime_type`: 获取文件 MIME 类型
236
- - `split_file_chunks`: 文件分块
237
- - `calculate_file_hash`: 计算文件哈希
238
-
239
- - **converter.py**: 数据转换工具
240
- - `timestamp_to_datetime`: 时间戳转换
241
- - `convert_proto_to_model`: Proto 消息转模型
242
-
243
- - **retry.py**: 提供重试装饰器 `retry_with_backoff`
244
-
245
- - **upload_helper.py**: HTTP 上传辅助工具
246
- - `AsyncHttpUploader`: 异步 HTTP 上传器
247
- - `SyncHttpUploader`: 同步 HTTP 上传器
248
- - 支持普通上传和断点续传
249
-
250
- - **download_helper.py**: HTTP 下载辅助工具
251
- - `AsyncHttpDownloader`: 异步 HTTP 下载器
252
- - `SyncHttpDownloader`: 同步 HTTP 下载器
253
- - 支持流式下载和断点续传
254
-
255
- ### 错误处理 (`errors/`)
256
-
257
- - **exceptions.py**: 定义了完整的异常体系
258
- - `FileHubError`: 基础异常类
259
- - `FileNotFoundError`: 文件不存在
260
- - `FolderNotFoundError`: 文件夹不存在
261
- - `UploadError`: 上传错误
262
- - `DownloadError`: 下载错误
263
- - `ValidationError`: 验证错误
264
- - 等等...
265
-
266
- ## 安装
267
-
268
- ```bash
269
- pip install tamar-file-hub-client
270
- ```
271
-
272
- ## 配置
273
-
274
- ### 环境变量配置
275
-
276
- File Hub Client 支持通过环境变量配置连接参数,这在生产环境中特别有用。
277
-
278
- 1. **创建 `.env` 文件**:
279
- ```bash
280
- # 在项目根目录创建 .env 文件
281
- touch .env
282
- ```
283
-
284
- 2. **编辑 `.env` 文件**:
285
- ```env
286
- # gRPC 服务器配置
287
- FILE_HUB_HOST=your-server-host.com
288
- FILE_HUB_PORT=50051
289
- FILE_HUB_SECURE=true
290
- FILE_HUB_API_KEY=your-api-key
291
-
292
- # 连接重试配置
293
- FILE_HUB_RETRY_COUNT=5
294
- FILE_HUB_RETRY_DELAY=2.0
295
- ```
296
-
297
- 3. **支持的环境变量**:
298
-
299
- | 环境变量 | 说明 | 默认值 |
300
- |---------|------|--------|
301
- | `FILE_HUB_HOST` | gRPC 服务器地址 | `localhost` |
302
- | `FILE_HUB_PORT` | gRPC 服务器端口 | `50051` |
303
- | `FILE_HUB_SECURE` | 是否启用 TLS/SSL | `false` |
304
- | `FILE_HUB_API_KEY` | API 认证密钥(可选) | 无 |
305
- | `FILE_HUB_RETRY_COUNT` | 连接重试次数 | `3` |
306
- | `FILE_HUB_RETRY_DELAY` | 重试延迟(秒) | `1.0` |
307
-
308
- ### TLS/SSL 配置
309
-
310
- 当 `FILE_HUB_SECURE` 设置为 `true` 时,客户端会使用 TLS 加密连接:
311
-
312
- - 默认使用系统的根证书
313
- - 如果提供了 `FILE_HUB_API_KEY`,会自动添加到请求头中进行认证
314
-
315
- ```python
316
- # 通过代码配置 TLS
317
- from file_hub_client import TamarFileHubClient
318
-
319
- client = TamarFileHubClient(
320
- host="secure-server.com",
321
- port=443,
322
- secure=True,
323
- credentials={"api_key": "your-api-key"}
324
- )
325
- ```
326
-
327
- ### 连接重试
328
-
329
- 客户端支持自动重试连接,对于不稳定的网络环境特别有用:
330
-
331
- ```python
332
- # 通过代码配置重试
333
- from file_hub_client import TamarFileHubClient
334
-
335
- client = TamarFileHubClient(
336
- host="server.com",
337
- retry_count=5, # 重试5次
338
- retry_delay=2.0 # 每次重试间隔2秒
339
- )
340
- ```
341
-
342
- ### 加载环境变量
343
-
344
- 使用 `python-dotenv` 加载 `.env` 文件(需要额外安装):
345
-
346
- ```bash
347
- pip install python-dotenv
348
- ```
349
-
350
- ```python
351
- from dotenv import load_dotenv
352
- import os
353
-
354
- # 加载 .env 文件
355
- load_dotenv()
356
-
357
- # 现在可以直接使用客户端,它会自动读取环境变量
358
- from file_hub_client import AsyncTamarFileHubClient
359
-
360
- async with AsyncTamarFileHubClient() as client:
361
- # 客户端会自动使用环境变量中的配置
362
- pass
363
- ```
364
-
365
- ### 配置优先级
366
-
367
- 客户端配置的优先级如下(从高到低):
368
-
369
- 1. 直接传入的参数
370
- 2. 环境变量
371
- 3. 默认值
372
-
373
- ```python
374
- # 示例:参数会覆盖环境变量
375
- from file_hub_client import AsyncTamarFileHubClient
376
-
377
- client = AsyncTamarFileHubClient(
378
- host="override-host.com", # 这会覆盖 FILE_HUB_HOST
379
- # port 将使用环境变量 FILE_HUB_PORT 或默认值
380
- )
381
- ```
382
-
383
- ## 快速开始
384
-
385
- ### 文件上传
386
-
387
- File Hub Client 提供了统一的上传接口,支持多种上传模式:
388
-
389
- #### 上传模式
390
-
391
- - **NORMAL(普通模式)**:适用于小文件,通过 gRPC 直接上传
392
- - **STREAM(流式上传)**:适用于流式数据上传
393
- - **RESUMABLE(断点续传)**:支持断点续传,适用于大文件和不稳定网络
394
-
395
- #### 最简单的上传
396
-
397
- ```python
398
- from file_hub_client import AsyncTamarFileHubClient
399
-
400
- async with AsyncTamarFileHubClient() as client:
401
- # 设置用户上下文
402
- client.set_user_context(org_id="123", user_id="456")
403
-
404
- # 最简单的用法 - 只需要文件路径
405
- file_info = await client.blobs.upload(
406
- "path/to/document.pdf",
407
- folder_id="1dee0f7b-2e4f-45cd-a462-4e1d82df9bdd" # 上传到指定文件夹,不传则默认文件夹
408
- )
409
- print(f"上传成功: {file_info.file.id}")
410
- print(f"文件类型: {file_info.file.file_type}") # 自动识别为 "pdf"
411
- ```
412
-
413
- #### 上传不同类型的内容
414
-
415
- ```python
416
- from file_hub_client import AsyncTamarFileHubClient
417
- from pathlib import Path
418
-
419
- async with AsyncTamarFileHubClient() as client:
420
- # 1. 上传文件路径(字符串或Path对象)
421
- file_info = await client.blobs.upload("path/to/file.pdf")
422
- file_info = await client.blobs.upload(Path("path/to/file.pdf"))
423
-
424
- # 2. 上传字节数据(需要指定文件名)
425
- content = b"This is file content"
426
- file_info = await client.blobs.upload(
427
- content,
428
- file_name="document.txt"
429
- )
430
-
431
- # 3. 上传文件对象
432
- with open("image.png", "rb") as f:
433
- file_info = await client.blobs.upload(f)
434
- ```
435
-
436
- #### 大文件上传(流式上传和断点续传)
437
-
438
- ```python
439
- from file_hub_client import AsyncTamarFileHubClient, UploadMode
440
-
441
- async with AsyncTamarFileHubClient() as client:
442
- # 设置用户上下文
443
- client.set_user_context(org_id="123", user_id="456")
444
-
445
- # 自动根据文件大小来选择是流式上传还是断点续传
446
- file_info = await client.blobs.upload(
447
- "large_video.mp4",
448
- # mode=UploadMode.RESUMABLE # 也可以手动指定上传的模式
449
- )
450
- ```
451
-
452
- #### 临时文件上传
453
-
454
- ```python
455
- from file_hub_client import AsyncTamarFileHubClient, UploadMode
456
-
457
- async with AsyncTamarFileHubClient() as client:
458
- # 设置用户上下文
459
- client.set_user_context(org_id="123", user_id="456")
460
-
461
- # 自动根据文件大小来选择是流式上传还是断点续传
462
- file_info = await client.blobs.upload(
463
- "large_video.mp4",
464
- # mode=UploadMode.RESUMABLE, # 也可以手动指定上传的模式
465
- is_temporary=True, # 由这个参数指定是否临时文件,是则不会纳入整个文件体系,即用户查询不到这个文件
466
- # expire_seconds, # 过期秒数,默认30天
467
- )
468
- ```
469
-
470
- ### 文件下载
471
-
472
- File Hub Client 提供了统一的下载接口,支持两种结构返回:
473
-
474
- #### 下载返回结构
475
-
476
- - **保存到本地(本地路径)**:适用于各种文件,直接下载到本地,分块流式下载,支持重试和断点续传
477
- - **保存到内存(bytes)**:适用于小文件,直接下载到内存,分块流式下载,支持重试
478
-
479
- #### 下载到内存(适用于小文件)
480
-
481
- ```python
482
- from file_hub_client import AsyncTamarFileHubClient
483
-
484
- async with AsyncTamarFileHubClient() as client:
485
- # 设置用户上下文
486
- client.set_user_context(org_id="123", user_id="456")
487
-
488
- # 下载文件到内存(适用于小文件)
489
- content = await client.blobs.download(file_id="file-001")
490
- print(f"下载完成,文件大小: {len(content)} bytes")
491
- ```
492
-
493
- #### 下载到本地文件
494
-
495
- ```python
496
- from file_hub_client import AsyncTamarFileHubClient
497
- from pathlib import Path
498
-
499
- async with AsyncTamarFileHubClient() as client:
500
- # 设置用户上下文
501
- client.set_user_context(org_id="123", user_id="456")
502
-
503
- # 下载文件到本地
504
- save_path = await client.blobs.download(
505
- file_id="file-001",
506
- save_path="downloads/document.pdf" # 或 Path 对象
507
- )
508
- print(f"文件已保存到: {save_path}")
509
- ```
510
-
511
- ### 文件管理操作
512
-
513
- File Hub Client 提供了完整的文件管理功能,通过 `files` 服务访问:
514
-
515
- #### 获取文件信息
516
-
517
- ```python
518
- from file_hub_client import AsyncTamarFileHubClient
519
-
520
- async with AsyncTamarFileHubClient() as client:
521
- # 设置用户上下文
522
- client.set_user_context(org_id="123", user_id="456")
523
-
524
- # 获取文件详细信息
525
- file_info = await client.files.get_file(file_id="file-001")
526
- print(f"文件名: {file_info.file_name}")
527
- print(f"文件大小: {file_info.file_size} bytes")
528
- print(f"创建时间: {file_info.created_at}")
529
- ```
530
-
531
- #### 重命名文件
532
-
533
- ```python
534
- # 重命名文件
535
- updated_file = await client.files.rename_file(
536
- file_id="file-001",
537
- new_name="新文档名称.pdf"
538
- )
539
- print(f"文件已重命名为: {updated_file.file_name}")
540
- ```
541
-
542
- #### 删除文件
543
-
544
- ```python
545
- # 删除文件
546
- await client.files.delete_file(file_id="file-001")
547
- print("文件已删除")
548
- ```
549
-
550
- #### 列出文件
551
-
552
- ```python
553
- # 列出文件夹中的文件
554
- file_list = await client.files.list_files(
555
- folder_id="folder-001", # 可选,不指定则列出根目录
556
- file_name="report", # 可选,按名称过滤
557
- file_type=["pdf", "docx"], # 可选,按类型过滤
558
- page_size=20,
559
- page=1
560
- )
561
-
562
- for file in file_list.files:
563
- print(f"- {file.file_name} ({file.file_size} bytes)")
564
- ```
565
-
566
- #### 生成分享链接
567
-
568
- ```python
569
- # 生成文件分享链接
570
- share_id = await client.files.generate_share_link(
571
- file_id="file-001",
572
- is_public=True, # 是否公开
573
- access_scope="view", # 访问权限:view, download
574
- expire_seconds=86400, # 24小时后过期
575
- share_password="secret" # 可选,设置访问密码
576
- )
577
- print(f"分享ID: {share_id}")
578
- ```
579
-
580
- ### 文件夹操作
581
-
582
- File Hub Client 提供了完整的文件夹管理功能,通过 `folders` 服务访问:
583
-
584
- #### 创建文件夹
585
-
586
- ```python
587
- from file_hub_client import AsyncTamarFileHubClient
588
-
589
- async with AsyncTamarFileHubClient() as client:
590
- # 设置用户上下文
591
- client.set_user_context(org_id="123", user_id="456")
592
-
593
- # 在根目录创建文件夹
594
- folder = await client.folders.create_folder(
595
- folder_name="我的文档"
596
- )
597
- print(f"创建文件夹: {folder.id}")
598
-
599
- # 在指定文件夹下创建子文件夹
600
- sub_folder = await client.folders.create_folder(
601
- folder_name="项目资料",
602
- parent_id=folder.id
603
- )
604
- print(f"创建子文件夹: {sub_folder.id}")
605
- ```
606
-
607
- #### 重命名文件夹
608
-
609
- ```python
610
- # 重命名文件夹
611
- updated_folder = await client.folders.rename_folder(
612
- folder_id="folder-001",
613
- new_name="新文件夹名称"
614
- )
615
- print(f"文件夹已重命名为: {updated_folder.folder_name}")
616
- ```
617
-
618
- #### 移动文件夹
619
-
620
- ```python
621
- # 移动文件夹到另一个文件夹下
622
- moved_folder = await client.folders.move_folder(
623
- folder_id="folder-001",
624
- new_parent_id="folder-002" # 目标父文件夹ID
625
- )
626
- print(f"文件夹已移动到: {moved_folder.parent_id}")
627
- ```
628
-
629
- #### 删除文件夹
630
-
631
- ```python
632
- # 删除文件夹(包括其中的所有内容)
633
- await client.folders.delete_folder(folder_id="folder-001")
634
- print("文件夹已删除")
635
- ```
636
- #### 列出文件夹
637
-
638
- ```python
639
- # 列出根目录下的文件夹
640
- folder_list = await client.folders.list_folders()
641
-
642
- # 列出指定文件夹下的子文件夹
643
- sub_folders = await client.folders.list_folders(
644
- parent_id="folder-001",
645
- folder_name="项目", # 可选,按名称过滤
646
- )
647
-
648
- for folder in folder_list.items:
649
- print(f"- {folder.folder_name} (ID: {folder.id})")
650
- print(f" 创建者: {folder.created_by}")
651
- print(f" 创建时间: {folder.created_at}")
652
- ```
653
-
654
- #### 完整示例:组织文件结构
655
-
656
- ```python
657
- from file_hub_client import AsyncTamarFileHubClient
658
-
659
- async with AsyncTamarFileHubClient() as client:
660
- # 设置用户上下文
661
- client.set_user_context(org_id="123", user_id="456")
662
-
663
- # 创建项目文件夹结构
664
- project_folder = await client.folders.create_folder("我的项目")
665
- docs_folder = await client.folders.create_folder("文档", parent_id=project_folder.id)
666
- images_folder = await client.folders.create_folder("图片", parent_id=project_folder.id)
667
-
668
- # 上传文件到对应文件夹
669
- doc_file = await client.blobs.upload(
670
- "project_plan.pdf",
671
- folder_id=docs_folder.id
672
- )
673
-
674
- image_file = await client.blobs.upload(
675
- "logo.png",
676
- folder_id=images_folder.id
677
- )
678
-
679
- # 列出项目文件夹的内容
680
- print("项目结构:")
681
-
682
- # 列出子文件夹
683
- folders = await client.folders.list_folders(parent_id=project_folder.id)
684
- for folder in folders.items:
685
- print(f"📁 {folder.folder_name}/")
686
-
687
- # 列出每个文件夹中的文件
688
- files = await client.files.list_files(folder_id=folder.id)
689
- for file in files.files:
690
- print(f" 📄 {file.file_name}")
691
- ```
692
-
693
- ### 最简单的使用方式(推荐)
694
-
695
- File Hub Client 提供了预配置的单例客户端,可以直接导入使用:
696
-
697
- ```python
698
- # 同步客户端
699
- import os
700
- from file_hub_client import tamar_client as client
701
-
702
- # 直接使用,无需 with 语句
703
- client.set_user_context(org_id="123", user_id="456")
704
- file_path = os.path.abspath("1.jpg")
705
- file_info = client.blobs.upload(file_path)
706
- ```
707
-
708
- ```python
709
- # 异步客户端
710
- import asyncio
711
- import os
712
- from file_hub_client import async_tamar_client as async_client
713
-
714
-
715
- async def main():
716
- # 直接使用,无需 with 语句
717
- await async_client._ensure_connected() # 需要手动连接
718
- async_client.set_user_context(org_id="123", user_id="456")
719
- file_path = os.path.abspath("1.jpg")
720
- file_info = await async_client.blobs.upload(file_path)
721
- print(f"上传成功: {file_info.file.id}")
722
-
723
-
724
- asyncio.run(main())
725
- ```
726
-
727
- ### 自定义配置的单例
728
-
729
- 如果需要自定义配置,可以使用 `get_client()` 或 `get_async_client()`:
730
-
731
- ```python
732
- from file_hub_client import get_client
733
-
734
- # 获取自定义配置的客户端(单例)
735
- client = get_client(
736
- host="custom-server.com",
737
- port=50051,
738
- secure=True
739
- )
740
- ```
741
-
742
- ### 使用上下文管理器(可选)
743
-
744
- 如果您希望明确控制连接的生命周期,仍然可以使用上下文管理器:
745
-
746
- ```python
747
- import os
748
- from file_hub_client import TamarFileHubClient
749
-
750
- # 使用 with 语句
751
- with TamarFileHubClient(host="localhost", port=50051) as client:
752
- file_path = os.path.abspath("1.jpg")
753
- file_info = client.blobs.upload(file_path)
754
- ```
755
-
756
- ### 异步客户端示例
757
-
758
- ```python
759
- import asyncio
760
- import os
761
- from file_hub_client import AsyncTamarFileHubClient
762
-
763
-
764
- async def main():
765
- # 创建客户端
766
- async with AsyncTamarFileHubClient(host="localhost", port=50051) as client:
767
- # 上传文件
768
- file_path = os.path.abspath("1.jpg")
769
- file_info = await client.blobs.upload(file_path)
770
- print(f"上传成功: {file_info.file.id}")
771
-
772
-
773
- asyncio.run(main())
774
- ```
775
-
776
- ### 同步客户端示例
777
-
778
- ```python
779
- import os
780
- from file_hub_client import TamarFileHubClient
781
-
782
- # 创建客户端
783
- with TamarFileHubClient(host="localhost", port=50051) as client:
784
- # 上传文件
785
- file_path = os.path.abspath("1.jpg")
786
- file_info = client.blobs.upload(file_path)
787
- print(f"上传成功: {file_info.file.id}")
788
- ```
789
-
790
- ### 使用用户上下文
791
-
792
- File Hub Client 支持精细的用户上下文管理,区分资源所有权和实际操作者:
793
-
794
- ```python
795
- import os
796
- from file_hub_client import AsyncTamarFileHubClient, UserContext, RequestContext, Role
797
-
798
- # 创建用户上下文
799
- user_context = UserContext(
800
- org_id="org-123", # 组织ID
801
- user_id="user-456", # 用户ID(资源所有者)
802
- role=Role.ACCOUNT, # 角色:ACCOUNT, AGENT, SYSTEM
803
- actor_id="agent-789" # 实际操作者ID(可选,默认为user_id)
804
- )
805
-
806
- # 创建请求上下文(自动收集客户端信息)
807
- request_context = RequestContext(
808
- client_ip="192.168.1.100", # 客户端IP(可选)
809
- client_type="web", # 客户端类型:web, mobile, desktop, cli
810
- client_version="2.0.0", # 客户端版本
811
- extra={"session_id": "xyz"} # 额外的元数据
812
- )
813
-
814
- # 使用上下文创建客户端
815
- async with AsyncTamarFileHubClient(
816
- user_context=user_context,
817
- request_context=request_context
818
- ) as client:
819
- # 所有操作都会包含上下文信息
820
- file_path = os.path.abspath("1.jpg")
821
- await client.blobs.upload(file_path)
822
- ```
823
-
824
- ### 动态切换用户上下文
825
-
826
- ```python
827
- from file_hub_client import tamar_client as client, Role
828
-
829
- # 初始用户
830
- client.set_user_context(
831
- org_id="123",
832
- user_id="456",
833
- role=Role.ACCOUNT
834
- )
835
- ```
836
-
837
- ### 请求追踪
838
-
839
- 客户端会自动生成请求ID并收集环境信息:
840
-
841
- ```python
842
- from file_hub_client import tamar_client as client
843
-
844
- # 获取当前上下文信息
845
- user_ctx = client.get_user_context()
846
- request_ctx = client.get_request_context()
847
-
848
- print(f"请求ID: {request_ctx.request_id}")
849
- print(f"客户端信息: {request_ctx.client_type} v{request_ctx.client_version}")
850
- print(f"操作者: {user_ctx.actor_id} (角色: {user_ctx.role})")
851
- ```
852
-
853
- ## 开发
854
-
855
- ### 生成 gRPC 代码
856
-
857
- 当 proto 文件更新后,需要重新生成代码:
858
-
859
- ```bash
860
- # 使用命令行工具
861
- file-hub-gen-proto
862
-
863
- # 或直接运行脚本
864
- cd file_hub_client/rpc
865
- python generate_grpc.py
866
- ```
867
-
868
- ## 许可证
869
-
870
- MIT License
871
-
872
- ## 贡献
873
-
874
- 欢迎提交 Issue 和 Pull Request!