tamar-file-hub-client 0.0.12__tar.gz → 0.1.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.
Files changed (62) hide show
  1. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/PKG-INFO +21 -6
  2. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/README.md +20 -5
  3. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/gen/file_service_pb2.py +33 -15
  4. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/gen/file_service_pb2_grpc.py +132 -3
  5. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/protos/file_service.proto +47 -1
  6. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/schemas/__init__.py +10 -0
  7. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/schemas/file.py +30 -0
  8. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/file/async_blob_service.py +121 -2
  9. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/file/async_file_service.py +14 -3
  10. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/file/sync_blob_service.py +121 -2
  11. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/file/sync_file_service.py +14 -3
  12. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/setup.py +1 -1
  13. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/tamar_file_hub_client.egg-info/PKG-INFO +21 -6
  14. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/MANIFEST.in +0 -0
  15. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/__init__.py +0 -0
  16. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/client.py +0 -0
  17. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/enums/__init__.py +0 -0
  18. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/enums/export_format.py +0 -0
  19. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/enums/role.py +0 -0
  20. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/enums/upload_mode.py +0 -0
  21. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/errors/__init__.py +0 -0
  22. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/errors/exceptions.py +0 -0
  23. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/py.typed +0 -0
  24. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/__init__.py +0 -0
  25. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/async_client.py +0 -0
  26. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/gen/__init__.py +0 -0
  27. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/gen/folder_service_pb2.py +0 -0
  28. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/gen/folder_service_pb2_grpc.py +0 -0
  29. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/gen/taple_service_pb2.py +0 -0
  30. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/gen/taple_service_pb2_grpc.py +0 -0
  31. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/interceptors.py +0 -0
  32. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/protos/folder_service.proto +0 -0
  33. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/protos/taple_service.proto +0 -0
  34. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/rpc/sync_client.py +0 -0
  35. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/schemas/context.py +0 -0
  36. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/schemas/folder.py +0 -0
  37. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/schemas/taple.py +0 -0
  38. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/__init__.py +0 -0
  39. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/file/__init__.py +0 -0
  40. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/file/base_file_service.py +0 -0
  41. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/folder/__init__.py +0 -0
  42. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/folder/async_folder_service.py +0 -0
  43. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/folder/sync_folder_service.py +0 -0
  44. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/taple/__init__.py +0 -0
  45. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/taple/async_taple_service.py +0 -0
  46. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/taple/base_taple_service.py +0 -0
  47. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/taple/idempotent_taple_mixin.py +0 -0
  48. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/services/taple/sync_taple_service.py +0 -0
  49. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/utils/__init__.py +0 -0
  50. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/utils/converter.py +0 -0
  51. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/utils/download_helper.py +0 -0
  52. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/utils/file_utils.py +0 -0
  53. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/utils/idempotency.py +0 -0
  54. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/utils/logging.py +0 -0
  55. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/utils/retry.py +0 -0
  56. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/utils/smart_retry.py +0 -0
  57. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/file_hub_client/utils/upload_helper.py +0 -0
  58. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/setup.cfg +0 -0
  59. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/tamar_file_hub_client.egg-info/SOURCES.txt +0 -0
  60. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/tamar_file_hub_client.egg-info/dependency_links.txt +0 -0
  61. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/tamar_file_hub_client.egg-info/requires.txt +0 -0
  62. {tamar_file_hub_client-0.0.12 → tamar_file_hub_client-0.1.1}/tamar_file_hub_client.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tamar-file-hub-client
3
- Version: 0.0.12
3
+ Version: 0.1.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
@@ -695,11 +695,23 @@ async with AsyncTamarFileHubClient() as client:
695
695
  # 设置用户上下文
696
696
  client.set_user_context(org_id="123", user_id="456")
697
697
 
698
- # 获取文件详细信息
699
- file_info = await client.files.get_file(file_id="file-001")
698
+ # 获取文件详细信息(返回 GetFileResponse 对象)
699
+ response = await client.files.get_file(file_id="file-001")
700
+
701
+ # 访问文件基本信息
702
+ file_info = response.file
703
+ print(f"文件ID: {file_info.id}")
700
704
  print(f"文件名: {file_info.file_name}")
701
- print(f"文件大小: {file_info.file_size} bytes")
705
+ print(f"文件类型: {file_info.file_type}")
702
706
  print(f"创建时间: {file_info.created_at}")
707
+
708
+ # 访问上传文件详细信息(如果存在)
709
+ if response.upload_file:
710
+ upload_info = response.upload_file
711
+ print(f"文件大小: {upload_info.file_size} bytes")
712
+ print(f"MIME类型: {upload_info.mime_type}")
713
+ print(f"存储类型: {upload_info.storage_type}")
714
+ print(f"存储路径: {upload_info.stored_path}")
703
715
  ```
704
716
 
705
717
  #### 重命名文件
@@ -1622,10 +1634,12 @@ folder = await client.folders.create_folder(
1622
1634
 
1623
1635
  # 同步客户端同样支持
1624
1636
  sync_client = TamarFileHubClient(user_context=user_context)
1625
- file_info = sync_client.files.get_file(
1637
+ response = sync_client.files.get_file(
1626
1638
  file_id="file-123",
1627
1639
  request_id="debug-get-file-001"
1628
1640
  )
1641
+ # response.file 包含文件基本信息
1642
+ # response.upload_file 包含上传文件详细信息(可能为None)
1629
1643
  ```
1630
1644
 
1631
1645
  #### 请求ID优先级
@@ -1679,7 +1693,8 @@ await minimal_client.taples.create_table(name="auto_generated")
1679
1693
  - 所有批量操作方法
1680
1694
 
1681
1695
  **文件服务**:
1682
- - `get_file()`, `rename_file()`, `delete_file()`, `list_files()`
1696
+ - `get_file()` - 返回 `GetFileResponse` 对象,包含 `file` `upload_file` 信息
1697
+ - `rename_file()`, `delete_file()`, `list_files()`
1683
1698
  - `generate_share_link()`, `visit_file()`
1684
1699
 
1685
1700
  **文件夹服务**:
@@ -649,11 +649,23 @@ async with AsyncTamarFileHubClient() as client:
649
649
  # 设置用户上下文
650
650
  client.set_user_context(org_id="123", user_id="456")
651
651
 
652
- # 获取文件详细信息
653
- file_info = await client.files.get_file(file_id="file-001")
652
+ # 获取文件详细信息(返回 GetFileResponse 对象)
653
+ response = await client.files.get_file(file_id="file-001")
654
+
655
+ # 访问文件基本信息
656
+ file_info = response.file
657
+ print(f"文件ID: {file_info.id}")
654
658
  print(f"文件名: {file_info.file_name}")
655
- print(f"文件大小: {file_info.file_size} bytes")
659
+ print(f"文件类型: {file_info.file_type}")
656
660
  print(f"创建时间: {file_info.created_at}")
661
+
662
+ # 访问上传文件详细信息(如果存在)
663
+ if response.upload_file:
664
+ upload_info = response.upload_file
665
+ print(f"文件大小: {upload_info.file_size} bytes")
666
+ print(f"MIME类型: {upload_info.mime_type}")
667
+ print(f"存储类型: {upload_info.storage_type}")
668
+ print(f"存储路径: {upload_info.stored_path}")
657
669
  ```
658
670
 
659
671
  #### 重命名文件
@@ -1576,10 +1588,12 @@ folder = await client.folders.create_folder(
1576
1588
 
1577
1589
  # 同步客户端同样支持
1578
1590
  sync_client = TamarFileHubClient(user_context=user_context)
1579
- file_info = sync_client.files.get_file(
1591
+ response = sync_client.files.get_file(
1580
1592
  file_id="file-123",
1581
1593
  request_id="debug-get-file-001"
1582
1594
  )
1595
+ # response.file 包含文件基本信息
1596
+ # response.upload_file 包含上传文件详细信息(可能为None)
1583
1597
  ```
1584
1598
 
1585
1599
  #### 请求ID优先级
@@ -1633,7 +1647,8 @@ await minimal_client.taples.create_table(name="auto_generated")
1633
1647
  - 所有批量操作方法
1634
1648
 
1635
1649
  **文件服务**:
1636
- - `get_file()`, `rename_file()`, `delete_file()`, `list_files()`
1650
+ - `get_file()` - 返回 `GetFileResponse` 对象,包含 `file` `upload_file` 信息
1651
+ - `rename_file()`, `delete_file()`, `list_files()`
1637
1652
  - `generate_share_link()`, `visit_file()`
1638
1653
 
1639
1654
  **文件夹服务**:
@@ -26,7 +26,7 @@ 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\"\xdf\x01\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\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_seconds\"\xf3\x01\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\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_seconds\")\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\"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\"\x07\n\x05\x45mpty2\xbd\x05\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\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+\n\x07GetFile\x12\x14.file.GetFileRequest\x1a\n.file.File\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.FileListResponseb\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\"\xdf\x01\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\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_seconds\"\xf3\x01\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\x42\x0c\n\n_folder_idB\x0f\n\r_is_temporaryB\x11\n\x0f_expire_seconds\")\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\"M\n\x0f\x44ownloadUrlInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x0b\n\x03url\x18\x02 \x01(\t\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"$\n\x11GetGcsUrlResponse\x12\x0f\n\x07gcs_url\x18\x01 \x01(\t\"<\n\x16\x42\x61tchGetGcsUrlResponse\x12\"\n\x08gcs_urls\x18\x01 \x03(\x0b\x32\x10.file.GcsUrlInfo\"L\n\nGcsUrlInfo\x12\x0f\n\x07\x66ile_id\x18\x01 \x01(\t\x12\x0f\n\x07gcs_url\x18\x02 \x01(\t\x12\x12\n\x05\x65rror\x18\x03 \x01(\tH\x00\x88\x01\x01\x42\x08\n\x06_error\"\x07\n\x05\x45mpty2\xae\x07\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.FileListResponseb\x06proto3')
30
30
 
31
31
  _globals = globals()
32
32
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -57,18 +57,36 @@ if not _descriptor._USE_C_DESCRIPTORS:
57
57
  _globals['_DELETEFILEREQUEST']._serialized_end=1688
58
58
  _globals['_LISTFILESREQUEST']._serialized_start=1691
59
59
  _globals['_LISTFILESREQUEST']._serialized_end=1960
60
- _globals['_UPLOADFILERESPONSE']._serialized_start=1962
61
- _globals['_UPLOADFILERESPONSE']._serialized_end=2047
62
- _globals['_UPLOADURLRESPONSE']._serialized_start=2049
63
- _globals['_UPLOADURLRESPONSE']._serialized_end=2146
64
- _globals['_DOWNLOADURLRESPONSE']._serialized_start=2148
65
- _globals['_DOWNLOADURLRESPONSE']._serialized_end=2182
66
- _globals['_SHARELINKRESPONSE']._serialized_start=2184
67
- _globals['_SHARELINKRESPONSE']._serialized_end=2226
68
- _globals['_FILELISTRESPONSE']._serialized_start=2228
69
- _globals['_FILELISTRESPONSE']._serialized_end=2273
70
- _globals['_EMPTY']._serialized_start=2275
71
- _globals['_EMPTY']._serialized_end=2282
72
- _globals['_FILESERVICE']._serialized_start=2285
73
- _globals['_FILESERVICE']._serialized_end=2986
60
+ _globals['_BATCHDOWNLOADURLREQUEST']._serialized_start=1962
61
+ _globals['_BATCHDOWNLOADURLREQUEST']._serialized_end=2085
62
+ _globals['_GETGCSURLREQUEST']._serialized_start=2087
63
+ _globals['_GETGCSURLREQUEST']._serialized_end=2122
64
+ _globals['_BATCHGETGCSURLREQUEST']._serialized_start=2124
65
+ _globals['_BATCHGETGCSURLREQUEST']._serialized_end=2165
66
+ _globals['_UPLOADFILERESPONSE']._serialized_start=2167
67
+ _globals['_UPLOADFILERESPONSE']._serialized_end=2252
68
+ _globals['_UPLOADURLRESPONSE']._serialized_start=2254
69
+ _globals['_UPLOADURLRESPONSE']._serialized_end=2351
70
+ _globals['_DOWNLOADURLRESPONSE']._serialized_start=2353
71
+ _globals['_DOWNLOADURLRESPONSE']._serialized_end=2387
72
+ _globals['_SHARELINKRESPONSE']._serialized_start=2389
73
+ _globals['_SHARELINKRESPONSE']._serialized_end=2431
74
+ _globals['_FILELISTRESPONSE']._serialized_start=2433
75
+ _globals['_FILELISTRESPONSE']._serialized_end=2478
76
+ _globals['_GETFILERESPONSE']._serialized_start=2480
77
+ _globals['_GETFILERESPONSE']._serialized_end=2583
78
+ _globals['_BATCHDOWNLOADURLRESPONSE']._serialized_start=2585
79
+ _globals['_BATCHDOWNLOADURLRESPONSE']._serialized_end=2657
80
+ _globals['_DOWNLOADURLINFO']._serialized_start=2659
81
+ _globals['_DOWNLOADURLINFO']._serialized_end=2736
82
+ _globals['_GETGCSURLRESPONSE']._serialized_start=2738
83
+ _globals['_GETGCSURLRESPONSE']._serialized_end=2774
84
+ _globals['_BATCHGETGCSURLRESPONSE']._serialized_start=2776
85
+ _globals['_BATCHGETGCSURLRESPONSE']._serialized_end=2836
86
+ _globals['_GCSURLINFO']._serialized_start=2838
87
+ _globals['_GCSURLINFO']._serialized_end=2914
88
+ _globals['_EMPTY']._serialized_start=2916
89
+ _globals['_EMPTY']._serialized_end=2923
90
+ _globals['_FILESERVICE']._serialized_start=2926
91
+ _globals['_FILESERVICE']._serialized_end=3868
74
92
  # @@protoc_insertion_point(module_scope)
@@ -61,6 +61,21 @@ class FileServiceStub(object):
61
61
  request_serializer=file__service__pb2.DownloadUrlRequest.SerializeToString,
62
62
  response_deserializer=file__service__pb2.DownloadUrlResponse.FromString,
63
63
  _registered_method=True)
64
+ self.BatchGenerateDownloadUrl = channel.unary_unary(
65
+ '/file.FileService/BatchGenerateDownloadUrl',
66
+ request_serializer=file__service__pb2.BatchDownloadUrlRequest.SerializeToString,
67
+ response_deserializer=file__service__pb2.BatchDownloadUrlResponse.FromString,
68
+ _registered_method=True)
69
+ self.GetGcsUrl = channel.unary_unary(
70
+ '/file.FileService/GetGcsUrl',
71
+ request_serializer=file__service__pb2.GetGcsUrlRequest.SerializeToString,
72
+ response_deserializer=file__service__pb2.GetGcsUrlResponse.FromString,
73
+ _registered_method=True)
74
+ self.BatchGetGcsUrl = channel.unary_unary(
75
+ '/file.FileService/BatchGetGcsUrl',
76
+ request_serializer=file__service__pb2.BatchGetGcsUrlRequest.SerializeToString,
77
+ response_deserializer=file__service__pb2.BatchGetGcsUrlResponse.FromString,
78
+ _registered_method=True)
64
79
  self.GenerateShareLink = channel.unary_unary(
65
80
  '/file.FileService/GenerateShareLink',
66
81
  request_serializer=file__service__pb2.ShareLinkRequest.SerializeToString,
@@ -74,7 +89,7 @@ class FileServiceStub(object):
74
89
  self.GetFile = channel.unary_unary(
75
90
  '/file.FileService/GetFile',
76
91
  request_serializer=file__service__pb2.GetFileRequest.SerializeToString,
77
- response_deserializer=file__service__pb2.File.FromString,
92
+ response_deserializer=file__service__pb2.GetFileResponse.FromString,
78
93
  _registered_method=True)
79
94
  self.RenameFile = channel.unary_unary(
80
95
  '/file.FileService/RenameFile',
@@ -128,6 +143,24 @@ class FileServiceServicer(object):
128
143
  context.set_details('Method not implemented!')
129
144
  raise NotImplementedError('Method not implemented!')
130
145
 
146
+ def BatchGenerateDownloadUrl(self, request, context):
147
+ """Missing associated documentation comment in .proto file."""
148
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
149
+ context.set_details('Method not implemented!')
150
+ raise NotImplementedError('Method not implemented!')
151
+
152
+ def GetGcsUrl(self, request, context):
153
+ """Missing associated documentation comment in .proto file."""
154
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
155
+ context.set_details('Method not implemented!')
156
+ raise NotImplementedError('Method not implemented!')
157
+
158
+ def BatchGetGcsUrl(self, request, context):
159
+ """Missing associated documentation comment in .proto file."""
160
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
161
+ context.set_details('Method not implemented!')
162
+ raise NotImplementedError('Method not implemented!')
163
+
131
164
  def GenerateShareLink(self, request, context):
132
165
  """Missing associated documentation comment in .proto file."""
133
166
  context.set_code(grpc.StatusCode.UNIMPLEMENTED)
@@ -192,6 +225,21 @@ def add_FileServiceServicer_to_server(servicer, server):
192
225
  request_deserializer=file__service__pb2.DownloadUrlRequest.FromString,
193
226
  response_serializer=file__service__pb2.DownloadUrlResponse.SerializeToString,
194
227
  ),
228
+ 'BatchGenerateDownloadUrl': grpc.unary_unary_rpc_method_handler(
229
+ servicer.BatchGenerateDownloadUrl,
230
+ request_deserializer=file__service__pb2.BatchDownloadUrlRequest.FromString,
231
+ response_serializer=file__service__pb2.BatchDownloadUrlResponse.SerializeToString,
232
+ ),
233
+ 'GetGcsUrl': grpc.unary_unary_rpc_method_handler(
234
+ servicer.GetGcsUrl,
235
+ request_deserializer=file__service__pb2.GetGcsUrlRequest.FromString,
236
+ response_serializer=file__service__pb2.GetGcsUrlResponse.SerializeToString,
237
+ ),
238
+ 'BatchGetGcsUrl': grpc.unary_unary_rpc_method_handler(
239
+ servicer.BatchGetGcsUrl,
240
+ request_deserializer=file__service__pb2.BatchGetGcsUrlRequest.FromString,
241
+ response_serializer=file__service__pb2.BatchGetGcsUrlResponse.SerializeToString,
242
+ ),
195
243
  'GenerateShareLink': grpc.unary_unary_rpc_method_handler(
196
244
  servicer.GenerateShareLink,
197
245
  request_deserializer=file__service__pb2.ShareLinkRequest.FromString,
@@ -205,7 +253,7 @@ def add_FileServiceServicer_to_server(servicer, server):
205
253
  'GetFile': grpc.unary_unary_rpc_method_handler(
206
254
  servicer.GetFile,
207
255
  request_deserializer=file__service__pb2.GetFileRequest.FromString,
208
- response_serializer=file__service__pb2.File.SerializeToString,
256
+ response_serializer=file__service__pb2.GetFileResponse.SerializeToString,
209
257
  ),
210
258
  'RenameFile': grpc.unary_unary_rpc_method_handler(
211
259
  servicer.RenameFile,
@@ -370,6 +418,87 @@ class FileService(object):
370
418
  metadata,
371
419
  _registered_method=True)
372
420
 
421
+ @staticmethod
422
+ def BatchGenerateDownloadUrl(request,
423
+ target,
424
+ options=(),
425
+ channel_credentials=None,
426
+ call_credentials=None,
427
+ insecure=False,
428
+ compression=None,
429
+ wait_for_ready=None,
430
+ timeout=None,
431
+ metadata=None):
432
+ return grpc.experimental.unary_unary(
433
+ request,
434
+ target,
435
+ '/file.FileService/BatchGenerateDownloadUrl',
436
+ file__service__pb2.BatchDownloadUrlRequest.SerializeToString,
437
+ file__service__pb2.BatchDownloadUrlResponse.FromString,
438
+ options,
439
+ channel_credentials,
440
+ insecure,
441
+ call_credentials,
442
+ compression,
443
+ wait_for_ready,
444
+ timeout,
445
+ metadata,
446
+ _registered_method=True)
447
+
448
+ @staticmethod
449
+ def GetGcsUrl(request,
450
+ target,
451
+ options=(),
452
+ channel_credentials=None,
453
+ call_credentials=None,
454
+ insecure=False,
455
+ compression=None,
456
+ wait_for_ready=None,
457
+ timeout=None,
458
+ metadata=None):
459
+ return grpc.experimental.unary_unary(
460
+ request,
461
+ target,
462
+ '/file.FileService/GetGcsUrl',
463
+ file__service__pb2.GetGcsUrlRequest.SerializeToString,
464
+ file__service__pb2.GetGcsUrlResponse.FromString,
465
+ options,
466
+ channel_credentials,
467
+ insecure,
468
+ call_credentials,
469
+ compression,
470
+ wait_for_ready,
471
+ timeout,
472
+ metadata,
473
+ _registered_method=True)
474
+
475
+ @staticmethod
476
+ def BatchGetGcsUrl(request,
477
+ target,
478
+ options=(),
479
+ channel_credentials=None,
480
+ call_credentials=None,
481
+ insecure=False,
482
+ compression=None,
483
+ wait_for_ready=None,
484
+ timeout=None,
485
+ metadata=None):
486
+ return grpc.experimental.unary_unary(
487
+ request,
488
+ target,
489
+ '/file.FileService/BatchGetGcsUrl',
490
+ file__service__pb2.BatchGetGcsUrlRequest.SerializeToString,
491
+ file__service__pb2.BatchGetGcsUrlResponse.FromString,
492
+ options,
493
+ channel_credentials,
494
+ insecure,
495
+ call_credentials,
496
+ compression,
497
+ wait_for_ready,
498
+ timeout,
499
+ metadata,
500
+ _registered_method=True)
501
+
373
502
  @staticmethod
374
503
  def GenerateShareLink(request,
375
504
  target,
@@ -440,7 +569,7 @@ class FileService(object):
440
569
  target,
441
570
  '/file.FileService/GetFile',
442
571
  file__service__pb2.GetFileRequest.SerializeToString,
443
- file__service__pb2.File.FromString,
572
+ file__service__pb2.GetFileResponse.FromString,
444
573
  options,
445
574
  channel_credentials,
446
575
  insecure,
@@ -13,9 +13,12 @@ service FileService {
13
13
  rpc GenerateResumableUploadUrl (UploadUrlRequest) returns (UploadUrlResponse);
14
14
  rpc ConfirmUploadCompleted (UploadCompletedRequest) returns (Empty);
15
15
  rpc GenerateDownloadUrl (DownloadUrlRequest) returns (DownloadUrlResponse);
16
+ rpc BatchGenerateDownloadUrl (BatchDownloadUrlRequest) returns (BatchDownloadUrlResponse);
17
+ rpc GetGcsUrl (GetGcsUrlRequest) returns (GetGcsUrlResponse);
18
+ rpc BatchGetGcsUrl (BatchGetGcsUrlRequest) returns (BatchGetGcsUrlResponse);
16
19
  rpc GenerateShareLink (ShareLinkRequest) returns (ShareLinkResponse);
17
20
  rpc VisitFile (FileVisitRequest) returns (Empty);
18
- rpc GetFile (GetFileRequest) returns (File);
21
+ rpc GetFile (GetFileRequest) returns (GetFileResponse);
19
22
  rpc RenameFile (RenameFileRequest) returns (File);
20
23
  rpc DeleteFile (DeleteFileRequest) returns (Empty);
21
24
  rpc ListFiles (ListFilesRequest) returns (FileListResponse);
@@ -120,6 +123,20 @@ message ListFilesRequest {
120
123
  optional int32 page = 7;
121
124
  }
122
125
 
126
+ message BatchDownloadUrlRequest {
127
+ repeated string file_ids = 1;
128
+ optional bool is_cdn = 2;
129
+ optional int32 expire_seconds = 3;
130
+ }
131
+
132
+ message GetGcsUrlRequest {
133
+ string file_id = 1;
134
+ }
135
+
136
+ message BatchGetGcsUrlRequest {
137
+ repeated string file_ids = 1;
138
+ }
139
+
123
140
  // ========= 响应结构 =========
124
141
 
125
142
  message UploadFileResponse {
@@ -145,4 +162,33 @@ message FileListResponse {
145
162
  repeated File files = 1;
146
163
  }
147
164
 
165
+ message GetFileResponse {
166
+ File file = 1;
167
+ optional UploadFile upload_file = 2;
168
+ }
169
+
170
+ message BatchDownloadUrlResponse {
171
+ repeated DownloadUrlInfo download_urls = 1;
172
+ }
173
+
174
+ message DownloadUrlInfo {
175
+ string file_id = 1;
176
+ string url = 2;
177
+ optional string error = 3;
178
+ }
179
+
180
+ message GetGcsUrlResponse {
181
+ string gcs_url = 1;
182
+ }
183
+
184
+ message BatchGetGcsUrlResponse {
185
+ repeated GcsUrlInfo gcs_urls = 1;
186
+ }
187
+
188
+ message GcsUrlInfo {
189
+ string file_id = 1;
190
+ string gcs_url = 2;
191
+ optional string error = 3;
192
+ }
193
+
148
194
  message Empty {}
@@ -10,6 +10,11 @@ from .file import (
10
10
  FileVisitRequest,
11
11
  FileListRequest,
12
12
  FileListResponse,
13
+ GetFileResponse,
14
+ DownloadUrlInfo,
15
+ BatchDownloadUrlResponse,
16
+ GcsUrlInfo,
17
+ BatchGcsUrlResponse,
13
18
  )
14
19
  from .folder import (
15
20
  FolderInfo,
@@ -61,6 +66,11 @@ __all__ = [
61
66
  "FileVisitRequest",
62
67
  "FileListRequest",
63
68
  "FileListResponse",
69
+ "GetFileResponse",
70
+ "DownloadUrlInfo",
71
+ "BatchDownloadUrlResponse",
72
+ "GcsUrlInfo",
73
+ "BatchGcsUrlResponse",
64
74
 
65
75
  # 文件夹相关
66
76
  "FolderInfo",
@@ -87,3 +87,33 @@ class FileListRequest(BaseModel):
87
87
  class FileListResponse(BaseModel):
88
88
  """文件列表响应"""
89
89
  files: List[File] = Field(default_factory=list, description="文件列表")
90
+
91
+
92
+ class GetFileResponse(BaseModel):
93
+ """获取文件响应"""
94
+ file: File = Field(..., description="文件信息")
95
+ upload_file: Optional[UploadFile] = Field(None, description="上传文件信息")
96
+
97
+
98
+ class DownloadUrlInfo(BaseModel):
99
+ """下载URL信息"""
100
+ file_id: str = Field(..., description="文件ID")
101
+ url: str = Field(..., description="下载URL")
102
+ error: Optional[str] = Field(None, description="错误信息")
103
+
104
+
105
+ class BatchDownloadUrlResponse(BaseModel):
106
+ """批量下载URL响应"""
107
+ download_urls: List[DownloadUrlInfo] = Field(default_factory=list, description="下载URL列表")
108
+
109
+
110
+ class GcsUrlInfo(BaseModel):
111
+ """GCS URL信息"""
112
+ file_id: str = Field(..., description="文件ID")
113
+ gcs_url: str = Field(..., description="GCS URL")
114
+ error: Optional[str] = Field(None, description="错误信息")
115
+
116
+
117
+ class BatchGcsUrlResponse(BaseModel):
118
+ """批量GCS URL响应"""
119
+ gcs_urls: List[GcsUrlInfo] = Field(default_factory=list, description="GCS URL列表")
@@ -5,13 +5,13 @@ import asyncio
5
5
  import hashlib
6
6
 
7
7
  from pathlib import Path
8
- from typing import Optional, Union, BinaryIO, AsyncIterator
8
+ from typing import Optional, Union, BinaryIO, AsyncIterator, List
9
9
 
10
10
  from .base_file_service import BaseFileService
11
11
  from ...enums import UploadMode
12
12
  from ...errors import ValidationError
13
13
  from ...rpc import AsyncGrpcClient
14
- from ...schemas import FileUploadResponse, UploadUrlResponse
14
+ from ...schemas import FileUploadResponse, UploadUrlResponse, BatchDownloadUrlResponse, DownloadUrlInfo, GcsUrlInfo, BatchGcsUrlResponse
15
15
  from ...utils import AsyncHttpUploader, AsyncHttpDownloader, retry_with_backoff, get_file_mime_type
16
16
 
17
17
 
@@ -568,3 +568,122 @@ class AsyncBlobService(BaseFileService):
568
568
  save_path=save_path,
569
569
  chunk_size=chunk_size,
570
570
  )
571
+
572
+ async def batch_generate_download_url(
573
+ self,
574
+ file_ids: List[str],
575
+ *,
576
+ is_cdn: Optional[bool] = True,
577
+ expire_seconds: Optional[int] = None,
578
+ request_id: Optional[str] = None,
579
+ **metadata
580
+ ) -> BatchDownloadUrlResponse:
581
+ """
582
+ 批量生成下载URL
583
+
584
+ Args:
585
+ file_ids: 文件ID列表
586
+ is_cdn: 是否返回CDN的URL
587
+ expire_seconds: 过期时间(秒)
588
+ request_id: 请求ID(可选,如果不提供则自动生成)
589
+ **metadata: 额外的元数据(如 x-org-id, x-user-id 等)
590
+
591
+ Returns:
592
+ 批量下载URL响应
593
+ """
594
+ from ...rpc.gen import file_service_pb2, file_service_pb2_grpc
595
+
596
+ stub = await self.client.get_stub(file_service_pb2_grpc.FileServiceStub)
597
+
598
+ request = file_service_pb2.BatchDownloadUrlRequest(
599
+ file_ids=file_ids,
600
+ is_cdn=is_cdn,
601
+ expire_seconds=expire_seconds if expire_seconds else None
602
+ )
603
+
604
+ # 构建元数据
605
+ grpc_metadata = self.client.build_metadata(request_id=request_id, **metadata)
606
+
607
+ response = await stub.BatchGenerateDownloadUrl(request, metadata=grpc_metadata)
608
+
609
+ # 转换响应
610
+ download_urls = []
611
+ for url_info in response.download_urls:
612
+ download_urls.append(DownloadUrlInfo(
613
+ file_id=url_info.file_id,
614
+ url=url_info.url,
615
+ error=url_info.error if url_info.HasField('error') else None
616
+ ))
617
+
618
+ return BatchDownloadUrlResponse(download_urls=download_urls)
619
+
620
+ async def get_gcs_url(
621
+ self,
622
+ file_id: str,
623
+ *,
624
+ request_id: Optional[str] = None,
625
+ **metadata
626
+ ) -> str:
627
+ """
628
+ 获取文件的GCS URL
629
+
630
+ Args:
631
+ file_id: 文件ID
632
+ request_id: 请求ID(可选,如果不提供则自动生成)
633
+ **metadata: 额外的元数据(如 x-org-id, x-user-id 等)
634
+
635
+ Returns:
636
+ GCS URL
637
+ """
638
+ from ...rpc.gen import file_service_pb2, file_service_pb2_grpc
639
+
640
+ stub = await self.client.get_stub(file_service_pb2_grpc.FileServiceStub)
641
+
642
+ request = file_service_pb2.GetGcsUrlRequest(file_id=file_id)
643
+
644
+ # 构建元数据
645
+ grpc_metadata = self.client.build_metadata(request_id=request_id, **metadata)
646
+
647
+ response = await stub.GetGcsUrl(request, metadata=grpc_metadata)
648
+
649
+ return response.gcs_url
650
+
651
+ async def batch_get_gcs_url(
652
+ self,
653
+ file_ids: List[str],
654
+ *,
655
+ request_id: Optional[str] = None,
656
+ **metadata
657
+ ) -> BatchGcsUrlResponse:
658
+ """
659
+ 批量获取文件的GCS URL
660
+
661
+ Args:
662
+ file_ids: 文件ID列表
663
+ request_id: 请求ID(可选,如果不提供则自动生成)
664
+ **metadata: 额外的元数据(如 x-org-id, x-user-id 等)
665
+
666
+ Returns:
667
+ 批量GCS URL响应
668
+ """
669
+ from ...rpc.gen import file_service_pb2, file_service_pb2_grpc
670
+
671
+ stub = await self.client.get_stub(file_service_pb2_grpc.FileServiceStub)
672
+
673
+ request = file_service_pb2.BatchGetGcsUrlRequest(file_ids=file_ids)
674
+
675
+ # 构建元数据
676
+ grpc_metadata = self.client.build_metadata(request_id=request_id, **metadata)
677
+
678
+ response = await stub.BatchGetGcsUrl(request, metadata=grpc_metadata)
679
+
680
+ # 转换响应
681
+ gcs_urls = []
682
+ for url_info in response.gcs_urls:
683
+ gcs_urls.append(GcsUrlInfo(
684
+ file_id=url_info.file_id,
685
+ gcs_url=url_info.gcs_url,
686
+ error=url_info.error if url_info.HasField('error') else None
687
+ ))
688
+
689
+ return BatchGcsUrlResponse(gcs_urls=gcs_urls)
@@ -11,6 +11,7 @@ from ...rpc.async_client import AsyncGrpcClient
11
11
  from ...schemas import (
12
12
  File,
13
13
  FileListResponse,
14
+ GetFileResponse,
14
15
  )
15
16
  from ...errors import FileNotFoundError
16
17
 
@@ -120,7 +121,7 @@ class AsyncFileService(BaseFileService):
120
121
  await stub.VisitFile(request, metadata=grpc_metadata)
121
122
 
122
123
  async def get_file(self, file_id: str, request_id: Optional[str] = None,
123
- **metadata) -> File:
124
+ **metadata) -> GetFileResponse:
124
125
  """
125
126
  获取文件信息
126
127
 
@@ -129,9 +130,10 @@ class AsyncFileService(BaseFileService):
129
130
  **metadata: 额外的元数据(如 x-org-id, x-user-id 等)
130
131
 
131
132
  Returns:
132
- 文件信息
133
+ 文件信息响应,包含文件信息和上传文件信息
133
134
  """
134
135
  from ...rpc.gen import file_service_pb2, file_service_pb2_grpc
136
+ from ...schemas.file import GetFileResponse
135
137
 
136
138
  stub = await self.client.get_stub(file_service_pb2_grpc.FileServiceStub)
137
139
 
@@ -142,7 +144,16 @@ class AsyncFileService(BaseFileService):
142
144
 
143
145
  try:
144
146
  response = await stub.GetFile(request, metadata=grpc_metadata)
145
- return self._convert_file_info(response)
147
+
148
+ # 转换文件信息
149
+ file_info = self._convert_file_info(response.file)
150
+
151
+ # 转换上传文件信息(如果存在)
152
+ upload_file_info = None
153
+ if response.HasField('upload_file'):
154
+ upload_file_info = self._convert_upload_file_info(response.upload_file)
155
+
156
+ return GetFileResponse(file=file_info, upload_file=upload_file_info)
146
157
  except grpc.RpcError as e:
147
158
  if e.code() == grpc.StatusCode.NOT_FOUND:
148
159
  raise FileNotFoundError(file_id)
@@ -3,13 +3,13 @@
3
3
  """
4
4
  import hashlib
5
5
  from pathlib import Path
6
- from typing import Optional, Union, BinaryIO, Iterator
6
+ from typing import Optional, Union, BinaryIO, Iterator, List
7
7
 
8
8
  from .base_file_service import BaseFileService
9
9
  from ...enums import UploadMode
10
10
  from ...errors import ValidationError
11
11
  from ...rpc import SyncGrpcClient
12
- from ...schemas import FileUploadResponse, UploadUrlResponse
12
+ from ...schemas import FileUploadResponse, UploadUrlResponse, BatchDownloadUrlResponse, DownloadUrlInfo, GcsUrlInfo, BatchGcsUrlResponse
13
13
  from ...utils import HttpUploader, HttpDownloader, retry_with_backoff, get_file_mime_type
14
14
 
15
15
 
@@ -565,3 +565,122 @@ class SyncBlobService(BaseFileService):
565
565
  save_path=save_path,
566
566
  chunk_size=chunk_size,
567
567
  )
568
+
569
+ def batch_generate_download_url(
570
+ self,
571
+ file_ids: List[str],
572
+ *,
573
+ is_cdn: Optional[bool] = True,
574
+ expire_seconds: Optional[int] = None,
575
+ request_id: Optional[str] = None,
576
+ **metadata
577
+ ) -> BatchDownloadUrlResponse:
578
+ """
579
+ 批量生成下载URL
580
+
581
+ Args:
582
+ file_ids: 文件ID列表
583
+ is_cdn: 是否返回CDN的URL
584
+ expire_seconds: 过期时间(秒)
585
+ request_id: 请求ID(可选,如果不提供则自动生成)
586
+ **metadata: 额外的元数据(如 x-org-id, x-user-id 等)
587
+
588
+ Returns:
589
+ 批量下载URL响应
590
+ """
591
+ from ...rpc.gen import file_service_pb2, file_service_pb2_grpc
592
+
593
+ stub = self.client.get_stub(file_service_pb2_grpc.FileServiceStub)
594
+
595
+ request = file_service_pb2.BatchDownloadUrlRequest(
596
+ file_ids=file_ids,
597
+ is_cdn=is_cdn,
598
+ expire_seconds=expire_seconds if expire_seconds else None
599
+ )
600
+
601
+ # 构建元数据
602
+ grpc_metadata = self.client.build_metadata(request_id=request_id, **metadata)
603
+
604
+ response = stub.BatchGenerateDownloadUrl(request, metadata=grpc_metadata)
605
+
606
+ # 转换响应
607
+ download_urls = []
608
+ for url_info in response.download_urls:
609
+ download_urls.append(DownloadUrlInfo(
610
+ file_id=url_info.file_id,
611
+ url=url_info.url,
612
+ error=url_info.error if url_info.HasField('error') else None
613
+ ))
614
+
615
+ return BatchDownloadUrlResponse(download_urls=download_urls)
616
+
617
+ def get_gcs_url(
618
+ self,
619
+ file_id: str,
620
+ *,
621
+ request_id: Optional[str] = None,
622
+ **metadata
623
+ ) -> str:
624
+ """
625
+ 获取文件的GCS URL
626
+
627
+ Args:
628
+ file_id: 文件ID
629
+ request_id: 请求ID(可选,如果不提供则自动生成)
630
+ **metadata: 额外的元数据(如 x-org-id, x-user-id 等)
631
+
632
+ Returns:
633
+ GCS URL
634
+ """
635
+ from ...rpc.gen import file_service_pb2, file_service_pb2_grpc
636
+
637
+ stub = self.client.get_stub(file_service_pb2_grpc.FileServiceStub)
638
+
639
+ request = file_service_pb2.GetGcsUrlRequest(file_id=file_id)
640
+
641
+ # 构建元数据
642
+ grpc_metadata = self.client.build_metadata(request_id=request_id, **metadata)
643
+
644
+ response = stub.GetGcsUrl(request, metadata=grpc_metadata)
645
+
646
+ return response.gcs_url
647
+
648
+ def batch_get_gcs_url(
649
+ self,
650
+ file_ids: List[str],
651
+ *,
652
+ request_id: Optional[str] = None,
653
+ **metadata
654
+ ) -> BatchGcsUrlResponse:
655
+ """
656
+ 批量获取文件的GCS URL
657
+
658
+ Args:
659
+ file_ids: 文件ID列表
660
+ request_id: 请求ID(可选,如果不提供则自动生成)
661
+ **metadata: 额外的元数据(如 x-org-id, x-user-id 等)
662
+
663
+ Returns:
664
+ 批量GCS URL响应
665
+ """
666
+ from ...rpc.gen import file_service_pb2, file_service_pb2_grpc
667
+
668
+ stub = self.client.get_stub(file_service_pb2_grpc.FileServiceStub)
669
+
670
+ request = file_service_pb2.BatchGetGcsUrlRequest(file_ids=file_ids)
671
+
672
+ # 构建元数据
673
+ grpc_metadata = self.client.build_metadata(request_id=request_id, **metadata)
674
+
675
+ response = stub.BatchGetGcsUrl(request, metadata=grpc_metadata)
676
+
677
+ # 转换响应
678
+ gcs_urls = []
679
+ for url_info in response.gcs_urls:
680
+ gcs_urls.append(GcsUrlInfo(
681
+ file_id=url_info.file_id,
682
+ gcs_url=url_info.gcs_url,
683
+ error=url_info.error if url_info.HasField('error') else None
684
+ ))
685
+
686
+ return BatchGcsUrlResponse(gcs_urls=gcs_urls)
@@ -9,6 +9,7 @@ from ...rpc.sync_client import SyncGrpcClient
9
9
  from ...schemas import (
10
10
  File,
11
11
  FileListResponse,
12
+ GetFileResponse,
12
13
  )
13
14
  from ...errors import FileNotFoundError
14
15
 
@@ -118,7 +119,7 @@ class SyncFileService(BaseFileService):
118
119
  stub.VisitFile(request, metadata=grpc_metadata)
119
120
 
120
121
  def get_file(self, file_id: str, request_id: Optional[str] = None,
121
- **metadata) -> File:
122
+ **metadata) -> GetFileResponse:
122
123
  """
123
124
  获取文件信息
124
125
 
@@ -127,9 +128,10 @@ class SyncFileService(BaseFileService):
127
128
  **metadata: 额外的元数据(如 x-org-id, x-user-id 等)
128
129
 
129
130
  Returns:
130
- 文件信息
131
+ 文件信息响应,包含文件信息和上传文件信息
131
132
  """
132
133
  from ...rpc.gen import file_service_pb2, file_service_pb2_grpc
134
+ from ...schemas.file import GetFileResponse
133
135
 
134
136
  stub = self.client.get_stub(file_service_pb2_grpc.FileServiceStub)
135
137
 
@@ -140,7 +142,16 @@ class SyncFileService(BaseFileService):
140
142
 
141
143
  try:
142
144
  response = stub.GetFile(request, metadata=grpc_metadata)
143
- return self._convert_file_info(response)
145
+
146
+ # 转换文件信息
147
+ file_info = self._convert_file_info(response.file)
148
+
149
+ # 转换上传文件信息(如果存在)
150
+ upload_file_info = None
151
+ if response.HasField('upload_file'):
152
+ upload_file_info = self._convert_upload_file_info(response.upload_file)
153
+
154
+ return GetFileResponse(file=file_info, upload_file=upload_file_info)
144
155
  except grpc.RpcError as e:
145
156
  if e.code() == grpc.StatusCode.NOT_FOUND:
146
157
  raise FileNotFoundError(file_id)
@@ -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.0.12",
5
+ version="0.1.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",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tamar-file-hub-client
3
- Version: 0.0.12
3
+ Version: 0.1.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
@@ -695,11 +695,23 @@ async with AsyncTamarFileHubClient() as client:
695
695
  # 设置用户上下文
696
696
  client.set_user_context(org_id="123", user_id="456")
697
697
 
698
- # 获取文件详细信息
699
- file_info = await client.files.get_file(file_id="file-001")
698
+ # 获取文件详细信息(返回 GetFileResponse 对象)
699
+ response = await client.files.get_file(file_id="file-001")
700
+
701
+ # 访问文件基本信息
702
+ file_info = response.file
703
+ print(f"文件ID: {file_info.id}")
700
704
  print(f"文件名: {file_info.file_name}")
701
- print(f"文件大小: {file_info.file_size} bytes")
705
+ print(f"文件类型: {file_info.file_type}")
702
706
  print(f"创建时间: {file_info.created_at}")
707
+
708
+ # 访问上传文件详细信息(如果存在)
709
+ if response.upload_file:
710
+ upload_info = response.upload_file
711
+ print(f"文件大小: {upload_info.file_size} bytes")
712
+ print(f"MIME类型: {upload_info.mime_type}")
713
+ print(f"存储类型: {upload_info.storage_type}")
714
+ print(f"存储路径: {upload_info.stored_path}")
703
715
  ```
704
716
 
705
717
  #### 重命名文件
@@ -1622,10 +1634,12 @@ folder = await client.folders.create_folder(
1622
1634
 
1623
1635
  # 同步客户端同样支持
1624
1636
  sync_client = TamarFileHubClient(user_context=user_context)
1625
- file_info = sync_client.files.get_file(
1637
+ response = sync_client.files.get_file(
1626
1638
  file_id="file-123",
1627
1639
  request_id="debug-get-file-001"
1628
1640
  )
1641
+ # response.file 包含文件基本信息
1642
+ # response.upload_file 包含上传文件详细信息(可能为None)
1629
1643
  ```
1630
1644
 
1631
1645
  #### 请求ID优先级
@@ -1679,7 +1693,8 @@ await minimal_client.taples.create_table(name="auto_generated")
1679
1693
  - 所有批量操作方法
1680
1694
 
1681
1695
  **文件服务**:
1682
- - `get_file()`, `rename_file()`, `delete_file()`, `list_files()`
1696
+ - `get_file()` - 返回 `GetFileResponse` 对象,包含 `file` `upload_file` 信息
1697
+ - `rename_file()`, `delete_file()`, `list_files()`
1683
1698
  - `generate_share_link()`, `visit_file()`
1684
1699
 
1685
1700
  **文件夹服务**: