tamar-file-hub-client 0.1.2__py3-none-any.whl → 0.1.4__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.
file_hub_client/client.py CHANGED
@@ -157,7 +157,7 @@ class AsyncTamarFileHubClient:
157
157
  self._taple_service = AsyncTapleService(self._client)
158
158
  return self._taple_service
159
159
 
160
- def set_user_context(self, org_id: str, user_id: str, role: Role = Role.ACCOUNT, actor_id: Optional[str] = None):
160
+ def set_user_context(self, org_id: str, user_id: str, role: Role = Role.ACCOUNT, actor_id: Optional[str] = None, user_ip: Optional[str] = None):
161
161
  """
162
162
  设置用户上下文信息
163
163
 
@@ -166,8 +166,18 @@ class AsyncTamarFileHubClient:
166
166
  user_id: 用户ID
167
167
  role: 用户角色(默认为 ACCOUNT)
168
168
  actor_id: 操作者ID(如果不同于 user_id)
169
+ user_ip: 用户IP地址(实际请求用户的IP,如前端用户的IP)
169
170
  """
170
- self._client.set_user_context(org_id, user_id, role, actor_id)
171
+ self._client.set_user_context(org_id, user_id, role, actor_id, user_ip)
172
+
173
+ def set_user_ip(self, user_ip: Optional[str]):
174
+ """
175
+ 设置或更新用户IP地址
176
+
177
+ Args:
178
+ user_ip: 用户IP地址(实际请求用户的IP,如前端用户的IP)
179
+ """
180
+ self._client.set_user_ip(user_ip)
171
181
 
172
182
  def get_user_context(self) -> Optional[UserContext]:
173
183
  """获取当前用户上下文"""
@@ -364,7 +374,7 @@ class TamarFileHubClient:
364
374
  self._taple_service = SyncTapleService(self._client)
365
375
  return self._taple_service
366
376
 
367
- def set_user_context(self, org_id: str, user_id: str, role: Role = Role.ACCOUNT, actor_id: Optional[str] = None):
377
+ def set_user_context(self, org_id: str, user_id: str, role: Role = Role.ACCOUNT, actor_id: Optional[str] = None, user_ip: Optional[str] = None):
368
378
  """
369
379
  设置用户上下文信息
370
380
 
@@ -373,8 +383,18 @@ class TamarFileHubClient:
373
383
  user_id: 用户ID
374
384
  role: 用户角色(默认为 ACCOUNT)
375
385
  actor_id: 操作者ID(如果不同于 user_id)
386
+ user_ip: 用户IP地址(实际请求用户的IP,如前端用户的IP)
387
+ """
388
+ self._client.set_user_context(org_id, user_id, role, actor_id, user_ip)
389
+
390
+ def set_user_ip(self, user_ip: Optional[str]):
391
+ """
392
+ 设置或更新用户IP地址
393
+
394
+ Args:
395
+ user_ip: 用户IP地址(实际请求用户的IP,如前端用户的IP)
376
396
  """
377
- self._client.set_user_context(org_id, user_id, role, actor_id)
397
+ self._client.set_user_ip(user_ip)
378
398
 
379
399
  def get_user_context(self) -> Optional[UserContext]:
380
400
  """获取当前用户上下文"""
@@ -281,8 +281,17 @@ class AsyncGrpcClient:
281
281
  # 添加默认元数据
282
282
  metadata.update(self.default_metadata)
283
283
 
284
- # 添加/覆盖传入的元数据
285
- metadata.update(kwargs)
284
+ # 自动检测用户真实IP
285
+ from ..utils.ip_detector import get_current_user_ip
286
+ auto_detected_ip = get_current_user_ip()
287
+ if auto_detected_ip and 'x-user-ip' not in metadata:
288
+ # 只有在没有设置过user_ip的情况下才使用自动检测的IP
289
+ metadata['x-user-ip'] = auto_detected_ip
290
+
291
+ # 添加/覆盖传入的元数据,但跳过None值以避免覆盖有效的默认值
292
+ for k, v in kwargs.items():
293
+ if v is not None:
294
+ metadata[k] = v
286
295
 
287
296
  # 处理 request_id(优先级:显式传入 > metadata中的x-request-id > RequestContext > 自动生成)
288
297
  if request_id is not None:
@@ -314,7 +323,7 @@ class AsyncGrpcClient:
314
323
  """
315
324
  self.default_metadata.update(kwargs)
316
325
 
317
- def set_user_context(self, org_id: str, user_id: str, role: Role = Role.ACCOUNT, actor_id: Optional[str] = None):
326
+ def set_user_context(self, org_id: str, user_id: str, role: Role = Role.ACCOUNT, actor_id: Optional[str] = None, user_ip: Optional[str] = None):
318
327
  """
319
328
  设置用户上下文信息
320
329
 
@@ -323,16 +332,34 @@ class AsyncGrpcClient:
323
332
  user_id: 用户ID
324
333
  role: 用户角色(默认为 ACCOUNT)
325
334
  actor_id: 操作者ID(如果不同于 user_id)
335
+ user_ip: 用户IP地址(实际请求用户的IP,如前端用户的IP)
326
336
  """
327
337
  self._user_context = UserContext(
328
338
  org_id=org_id,
329
339
  user_id=user_id,
330
340
  role=role,
331
- actor_id=actor_id
341
+ actor_id=actor_id,
342
+ user_ip=user_ip
332
343
  )
333
344
  # 更新到默认元数据
334
345
  self.update_default_metadata(**self._user_context.to_metadata())
335
346
 
347
+ def set_user_ip(self, user_ip: Optional[str]):
348
+ """
349
+ 设置或更新用户IP地址
350
+
351
+ Args:
352
+ user_ip: 用户IP地址(实际请求用户的IP,如前端用户的IP)
353
+ """
354
+ if self._user_context:
355
+ self._user_context.user_ip = user_ip
356
+ # 先移除旧的x-user-ip(如果存在)
357
+ self.default_metadata.pop('x-user-ip', None)
358
+ # 更新到默认元数据(只有非None值会被添加)
359
+ self.update_default_metadata(**self._user_context.to_metadata())
360
+ else:
361
+ raise ValueError("必须先调用 set_user_context 设置用户上下文,然后才能设置用户IP")
362
+
336
363
  def get_user_context(self) -> Optional[UserContext]:
337
364
  """获取当前用户上下文"""
338
365
  return self._user_context
@@ -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\"{\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\"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\"\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')
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\"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\"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\"\x07\n\x05\x45mpty2\x87\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.VariantDownloadUrlResponseb\x06proto3')
30
30
 
31
31
  _globals = globals()
32
32
  _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
@@ -38,55 +38,73 @@ if not _descriptor._USE_C_DESCRIPTORS:
38
38
  _globals['_UPLOADFILE']._serialized_start=266
39
39
  _globals['_UPLOADFILE']._serialized_end=577
40
40
  _globals['_UPLOADFILEREQUEST']._serialized_start=580
41
- _globals['_UPLOADFILEREQUEST']._serialized_end=803
42
- _globals['_UPLOADURLREQUEST']._serialized_start=806
43
- _globals['_UPLOADURLREQUEST']._serialized_end=1049
44
- _globals['_UPLOADCOMPLETEDREQUEST']._serialized_start=1051
45
- _globals['_UPLOADCOMPLETEDREQUEST']._serialized_end=1092
46
- _globals['_DOWNLOADURLREQUEST']._serialized_start=1094
47
- _globals['_DOWNLOADURLREQUEST']._serialized_end=1211
48
- _globals['_SHARELINKREQUEST']._serialized_start=1214
49
- _globals['_SHARELINKREQUEST']._serialized_end=1426
50
- _globals['_FILEVISITREQUEST']._serialized_start=1429
51
- _globals['_FILEVISITREQUEST']._serialized_end=1559
52
- _globals['_GETFILEREQUEST']._serialized_start=1561
53
- _globals['_GETFILEREQUEST']._serialized_end=1594
54
- _globals['_RENAMEFILEREQUEST']._serialized_start=1596
55
- _globals['_RENAMEFILEREQUEST']._serialized_end=1650
56
- _globals['_DELETEFILEREQUEST']._serialized_start=1652
57
- _globals['_DELETEFILEREQUEST']._serialized_end=1688
58
- _globals['_LISTFILESREQUEST']._serialized_start=1691
59
- _globals['_LISTFILESREQUEST']._serialized_end=1960
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=2793
84
- _globals['_BATCHGETGCSURLRESPONSE']._serialized_start=2795
85
- _globals['_BATCHGETGCSURLRESPONSE']._serialized_end=2855
86
- _globals['_GCSURLINFO']._serialized_start=2857
87
- _globals['_GCSURLINFO']._serialized_end=2952
88
- _globals['_EMPTY']._serialized_start=2954
89
- _globals['_EMPTY']._serialized_end=2961
90
- _globals['_FILESERVICE']._serialized_start=2964
91
- _globals['_FILESERVICE']._serialized_end=3906
41
+ _globals['_UPLOADFILEREQUEST']._serialized_end=867
42
+ _globals['_UPLOADURLREQUEST']._serialized_start=870
43
+ _globals['_UPLOADURLREQUEST']._serialized_end=1177
44
+ _globals['_UPLOADCOMPLETEDREQUEST']._serialized_start=1179
45
+ _globals['_UPLOADCOMPLETEDREQUEST']._serialized_end=1220
46
+ _globals['_DOWNLOADURLREQUEST']._serialized_start=1222
47
+ _globals['_DOWNLOADURLREQUEST']._serialized_end=1339
48
+ _globals['_SHARELINKREQUEST']._serialized_start=1342
49
+ _globals['_SHARELINKREQUEST']._serialized_end=1554
50
+ _globals['_FILEVISITREQUEST']._serialized_start=1557
51
+ _globals['_FILEVISITREQUEST']._serialized_end=1687
52
+ _globals['_GETFILEREQUEST']._serialized_start=1689
53
+ _globals['_GETFILEREQUEST']._serialized_end=1722
54
+ _globals['_RENAMEFILEREQUEST']._serialized_start=1724
55
+ _globals['_RENAMEFILEREQUEST']._serialized_end=1778
56
+ _globals['_DELETEFILEREQUEST']._serialized_start=1780
57
+ _globals['_DELETEFILEREQUEST']._serialized_end=1816
58
+ _globals['_LISTFILESREQUEST']._serialized_start=1819
59
+ _globals['_LISTFILESREQUEST']._serialized_end=2088
60
+ _globals['_BATCHDOWNLOADURLREQUEST']._serialized_start=2090
61
+ _globals['_BATCHDOWNLOADURLREQUEST']._serialized_end=2213
62
+ _globals['_GETGCSURLREQUEST']._serialized_start=2215
63
+ _globals['_GETGCSURLREQUEST']._serialized_end=2250
64
+ _globals['_BATCHGETGCSURLREQUEST']._serialized_start=2252
65
+ _globals['_BATCHGETGCSURLREQUEST']._serialized_end=2293
66
+ _globals['_UPLOADFILERESPONSE']._serialized_start=2295
67
+ _globals['_UPLOADFILERESPONSE']._serialized_end=2380
68
+ _globals['_UPLOADURLRESPONSE']._serialized_start=2382
69
+ _globals['_UPLOADURLRESPONSE']._serialized_end=2479
70
+ _globals['_DOWNLOADURLRESPONSE']._serialized_start=2481
71
+ _globals['_DOWNLOADURLRESPONSE']._serialized_end=2515
72
+ _globals['_SHARELINKRESPONSE']._serialized_start=2517
73
+ _globals['_SHARELINKRESPONSE']._serialized_end=2559
74
+ _globals['_FILELISTRESPONSE']._serialized_start=2561
75
+ _globals['_FILELISTRESPONSE']._serialized_end=2606
76
+ _globals['_GETFILERESPONSE']._serialized_start=2608
77
+ _globals['_GETFILERESPONSE']._serialized_end=2711
78
+ _globals['_BATCHDOWNLOADURLRESPONSE']._serialized_start=2713
79
+ _globals['_BATCHDOWNLOADURLRESPONSE']._serialized_end=2785
80
+ _globals['_DOWNLOADURLINFO']._serialized_start=2787
81
+ _globals['_DOWNLOADURLINFO']._serialized_end=2864
82
+ _globals['_GETGCSURLRESPONSE']._serialized_start=2866
83
+ _globals['_GETGCSURLRESPONSE']._serialized_end=2921
84
+ _globals['_BATCHGETGCSURLRESPONSE']._serialized_start=2923
85
+ _globals['_BATCHGETGCSURLRESPONSE']._serialized_end=2983
86
+ _globals['_GCSURLINFO']._serialized_start=2985
87
+ _globals['_GCSURLINFO']._serialized_end=3080
88
+ _globals['_COMPRESSIONSTATUSREQUEST']._serialized_start=3082
89
+ _globals['_COMPRESSIONSTATUSREQUEST']._serialized_end=3125
90
+ _globals['_COMPRESSIONSTATUSRESPONSE']._serialized_start=3128
91
+ _globals['_COMPRESSIONSTATUSRESPONSE']._serialized_end=3260
92
+ _globals['_GETVARIANTSREQUEST']._serialized_start=3262
93
+ _globals['_GETVARIANTSREQUEST']._serialized_end=3343
94
+ _globals['_GETVARIANTSRESPONSE']._serialized_start=3345
95
+ _globals['_GETVARIANTSRESPONSE']._serialized_end=3409
96
+ _globals['_COMPRESSEDVARIANT']._serialized_start=3412
97
+ _globals['_COMPRESSEDVARIANT']._serialized_end=3739
98
+ _globals['_RECOMPRESSIONREQUEST']._serialized_start=3741
99
+ _globals['_RECOMPRESSIONREQUEST']._serialized_end=3830
100
+ _globals['_RECOMPRESSIONRESPONSE']._serialized_start=3832
101
+ _globals['_RECOMPRESSIONRESPONSE']._serialized_end=3888
102
+ _globals['_VARIANTDOWNLOADURLREQUEST']._serialized_start=3891
103
+ _globals['_VARIANTDOWNLOADURLREQUEST']._serialized_end=4037
104
+ _globals['_VARIANTDOWNLOADURLRESPONSE']._serialized_start=4040
105
+ _globals['_VARIANTDOWNLOADURLRESPONSE']._serialized_end=4180
106
+ _globals['_EMPTY']._serialized_start=4182
107
+ _globals['_EMPTY']._serialized_end=4189
108
+ _globals['_FILESERVICE']._serialized_start=4192
109
+ _globals['_FILESERVICE']._serialized_end=5479
92
110
  # @@protoc_insertion_point(module_scope)
@@ -106,6 +106,26 @@ class FileServiceStub(object):
106
106
  request_serializer=file__service__pb2.ListFilesRequest.SerializeToString,
107
107
  response_deserializer=file__service__pb2.FileListResponse.FromString,
108
108
  _registered_method=True)
109
+ self.GetCompressionStatus = channel.unary_unary(
110
+ '/file.FileService/GetCompressionStatus',
111
+ request_serializer=file__service__pb2.CompressionStatusRequest.SerializeToString,
112
+ response_deserializer=file__service__pb2.CompressionStatusResponse.FromString,
113
+ _registered_method=True)
114
+ self.GetCompressedVariants = channel.unary_unary(
115
+ '/file.FileService/GetCompressedVariants',
116
+ request_serializer=file__service__pb2.GetVariantsRequest.SerializeToString,
117
+ response_deserializer=file__service__pb2.GetVariantsResponse.FromString,
118
+ _registered_method=True)
119
+ self.TriggerRecompression = channel.unary_unary(
120
+ '/file.FileService/TriggerRecompression',
121
+ request_serializer=file__service__pb2.RecompressionRequest.SerializeToString,
122
+ response_deserializer=file__service__pb2.RecompressionResponse.FromString,
123
+ _registered_method=True)
124
+ self.GenerateVariantDownloadUrl = channel.unary_unary(
125
+ '/file.FileService/GenerateVariantDownloadUrl',
126
+ request_serializer=file__service__pb2.VariantDownloadUrlRequest.SerializeToString,
127
+ response_deserializer=file__service__pb2.VariantDownloadUrlResponse.FromString,
128
+ _registered_method=True)
109
129
 
110
130
 
111
131
  class FileServiceServicer(object):
@@ -197,6 +217,31 @@ class FileServiceServicer(object):
197
217
  context.set_details('Method not implemented!')
198
218
  raise NotImplementedError('Method not implemented!')
199
219
 
220
+ def GetCompressionStatus(self, request, context):
221
+ """压缩服务相关API
222
+ """
223
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
224
+ context.set_details('Method not implemented!')
225
+ raise NotImplementedError('Method not implemented!')
226
+
227
+ def GetCompressedVariants(self, request, context):
228
+ """Missing associated documentation comment in .proto file."""
229
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
230
+ context.set_details('Method not implemented!')
231
+ raise NotImplementedError('Method not implemented!')
232
+
233
+ def TriggerRecompression(self, request, context):
234
+ """Missing associated documentation comment in .proto file."""
235
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
236
+ context.set_details('Method not implemented!')
237
+ raise NotImplementedError('Method not implemented!')
238
+
239
+ def GenerateVariantDownloadUrl(self, request, context):
240
+ """Missing associated documentation comment in .proto file."""
241
+ context.set_code(grpc.StatusCode.UNIMPLEMENTED)
242
+ context.set_details('Method not implemented!')
243
+ raise NotImplementedError('Method not implemented!')
244
+
200
245
 
201
246
  def add_FileServiceServicer_to_server(servicer, server):
202
247
  rpc_method_handlers = {
@@ -270,6 +315,26 @@ def add_FileServiceServicer_to_server(servicer, server):
270
315
  request_deserializer=file__service__pb2.ListFilesRequest.FromString,
271
316
  response_serializer=file__service__pb2.FileListResponse.SerializeToString,
272
317
  ),
318
+ 'GetCompressionStatus': grpc.unary_unary_rpc_method_handler(
319
+ servicer.GetCompressionStatus,
320
+ request_deserializer=file__service__pb2.CompressionStatusRequest.FromString,
321
+ response_serializer=file__service__pb2.CompressionStatusResponse.SerializeToString,
322
+ ),
323
+ 'GetCompressedVariants': grpc.unary_unary_rpc_method_handler(
324
+ servicer.GetCompressedVariants,
325
+ request_deserializer=file__service__pb2.GetVariantsRequest.FromString,
326
+ response_serializer=file__service__pb2.GetVariantsResponse.SerializeToString,
327
+ ),
328
+ 'TriggerRecompression': grpc.unary_unary_rpc_method_handler(
329
+ servicer.TriggerRecompression,
330
+ request_deserializer=file__service__pb2.RecompressionRequest.FromString,
331
+ response_serializer=file__service__pb2.RecompressionResponse.SerializeToString,
332
+ ),
333
+ 'GenerateVariantDownloadUrl': grpc.unary_unary_rpc_method_handler(
334
+ servicer.GenerateVariantDownloadUrl,
335
+ request_deserializer=file__service__pb2.VariantDownloadUrlRequest.FromString,
336
+ response_serializer=file__service__pb2.VariantDownloadUrlResponse.SerializeToString,
337
+ ),
273
338
  }
274
339
  generic_handler = grpc.method_handlers_generic_handler(
275
340
  'file.FileService', rpc_method_handlers)
@@ -660,3 +725,111 @@ class FileService(object):
660
725
  timeout,
661
726
  metadata,
662
727
  _registered_method=True)
728
+
729
+ @staticmethod
730
+ def GetCompressionStatus(request,
731
+ target,
732
+ options=(),
733
+ channel_credentials=None,
734
+ call_credentials=None,
735
+ insecure=False,
736
+ compression=None,
737
+ wait_for_ready=None,
738
+ timeout=None,
739
+ metadata=None):
740
+ return grpc.experimental.unary_unary(
741
+ request,
742
+ target,
743
+ '/file.FileService/GetCompressionStatus',
744
+ file__service__pb2.CompressionStatusRequest.SerializeToString,
745
+ file__service__pb2.CompressionStatusResponse.FromString,
746
+ options,
747
+ channel_credentials,
748
+ insecure,
749
+ call_credentials,
750
+ compression,
751
+ wait_for_ready,
752
+ timeout,
753
+ metadata,
754
+ _registered_method=True)
755
+
756
+ @staticmethod
757
+ def GetCompressedVariants(request,
758
+ target,
759
+ options=(),
760
+ channel_credentials=None,
761
+ call_credentials=None,
762
+ insecure=False,
763
+ compression=None,
764
+ wait_for_ready=None,
765
+ timeout=None,
766
+ metadata=None):
767
+ return grpc.experimental.unary_unary(
768
+ request,
769
+ target,
770
+ '/file.FileService/GetCompressedVariants',
771
+ file__service__pb2.GetVariantsRequest.SerializeToString,
772
+ file__service__pb2.GetVariantsResponse.FromString,
773
+ options,
774
+ channel_credentials,
775
+ insecure,
776
+ call_credentials,
777
+ compression,
778
+ wait_for_ready,
779
+ timeout,
780
+ metadata,
781
+ _registered_method=True)
782
+
783
+ @staticmethod
784
+ def TriggerRecompression(request,
785
+ target,
786
+ options=(),
787
+ channel_credentials=None,
788
+ call_credentials=None,
789
+ insecure=False,
790
+ compression=None,
791
+ wait_for_ready=None,
792
+ timeout=None,
793
+ metadata=None):
794
+ return grpc.experimental.unary_unary(
795
+ request,
796
+ target,
797
+ '/file.FileService/TriggerRecompression',
798
+ file__service__pb2.RecompressionRequest.SerializeToString,
799
+ file__service__pb2.RecompressionResponse.FromString,
800
+ options,
801
+ channel_credentials,
802
+ insecure,
803
+ call_credentials,
804
+ compression,
805
+ wait_for_ready,
806
+ timeout,
807
+ metadata,
808
+ _registered_method=True)
809
+
810
+ @staticmethod
811
+ def GenerateVariantDownloadUrl(request,
812
+ target,
813
+ options=(),
814
+ channel_credentials=None,
815
+ call_credentials=None,
816
+ insecure=False,
817
+ compression=None,
818
+ wait_for_ready=None,
819
+ timeout=None,
820
+ metadata=None):
821
+ return grpc.experimental.unary_unary(
822
+ request,
823
+ target,
824
+ '/file.FileService/GenerateVariantDownloadUrl',
825
+ file__service__pb2.VariantDownloadUrlRequest.SerializeToString,
826
+ file__service__pb2.VariantDownloadUrlResponse.FromString,
827
+ options,
828
+ channel_credentials,
829
+ insecure,
830
+ call_credentials,
831
+ compression,
832
+ wait_for_ready,
833
+ timeout,
834
+ metadata,
835
+ _registered_method=True)
@@ -22,6 +22,12 @@ service FileService {
22
22
  rpc RenameFile (RenameFileRequest) returns (File);
23
23
  rpc DeleteFile (DeleteFileRequest) returns (Empty);
24
24
  rpc ListFiles (ListFilesRequest) returns (FileListResponse);
25
+
26
+ // 压缩服务相关API
27
+ rpc GetCompressionStatus (CompressionStatusRequest) returns (CompressionStatusResponse);
28
+ rpc GetCompressedVariants (GetVariantsRequest) returns (GetVariantsResponse);
29
+ rpc TriggerRecompression (RecompressionRequest) returns (RecompressionResponse);
30
+ rpc GenerateVariantDownloadUrl (VariantDownloadUrlRequest) returns (VariantDownloadUrlResponse);
25
31
  }
26
32
 
27
33
  // ========= 数据结构定义 =========
@@ -61,6 +67,7 @@ message UploadFileRequest {
61
67
  string mime_type = 5;
62
68
  optional bool is_temporary = 6;
63
69
  optional int32 expire_seconds = 7;
70
+ optional bool keep_original_filename = 8; // 保留原始文件名,默认false
64
71
  }
65
72
 
66
73
  message UploadUrlRequest {
@@ -72,6 +79,7 @@ message UploadUrlRequest {
72
79
  string file_hash = 6;
73
80
  optional bool is_temporary = 7;
74
81
  optional int32 expire_seconds = 8;
82
+ optional bool keep_original_filename = 9; // 保留原始文件名,默认false
75
83
  }
76
84
 
77
85
  message UploadCompletedRequest {
@@ -193,4 +201,64 @@ message GcsUrlInfo {
193
201
  optional string error = 4;
194
202
  }
195
203
 
204
+ // ========= 压缩服务相关结构 =========
205
+
206
+ message CompressionStatusRequest {
207
+ string file_id = 1;
208
+ }
209
+
210
+ message CompressionStatusResponse {
211
+ string status = 1; // pending, processing, completed, failed
212
+ optional string error_message = 2;
213
+ repeated CompressedVariant variants = 3;
214
+ }
215
+
216
+ message GetVariantsRequest {
217
+ string file_id = 1;
218
+ optional string variant_type = 2; // image, video, thumbnail
219
+ }
220
+
221
+ message GetVariantsResponse {
222
+ repeated CompressedVariant variants = 1;
223
+ }
224
+
225
+ message CompressedVariant {
226
+ string variant_name = 1;
227
+ string variant_type = 2;
228
+ string media_type = 3;
229
+ int32 width = 4;
230
+ int32 height = 5;
231
+ int64 file_size = 6;
232
+ string format = 7;
233
+ optional int32 quality = 8;
234
+ optional double duration = 9;
235
+ optional int64 bitrate = 10;
236
+ optional int32 fps = 11;
237
+ double compression_ratio = 12;
238
+ string stored_path = 13;
239
+ }
240
+
241
+ message RecompressionRequest {
242
+ string file_id = 1;
243
+ optional bool force_reprocess = 2;
244
+ }
245
+
246
+ message RecompressionResponse {
247
+ string task_id = 1;
248
+ string status = 2;
249
+ }
250
+
251
+ message VariantDownloadUrlRequest {
252
+ string file_id = 1;
253
+ string variant_name = 2; // large/medium/small/thumbnail
254
+ optional int32 expire_seconds = 3;
255
+ optional bool is_cdn = 4;
256
+ }
257
+
258
+ message VariantDownloadUrlResponse {
259
+ string url = 1;
260
+ optional string error = 2;
261
+ optional CompressedVariant variant_info = 3; // 返回变体详细信息
262
+ }
263
+
196
264
  message Empty {}
@@ -284,8 +284,17 @@ class SyncGrpcClient:
284
284
  # 添加默认元数据
285
285
  metadata.update(self.default_metadata)
286
286
 
287
- # 添加/覆盖传入的元数据
288
- metadata.update(kwargs)
287
+ # 自动检测用户真实IP
288
+ from ..utils.ip_detector import get_current_user_ip
289
+ auto_detected_ip = get_current_user_ip()
290
+ if auto_detected_ip and 'x-user-ip' not in metadata:
291
+ # 只有在没有设置过user_ip的情况下才使用自动检测的IP
292
+ metadata['x-user-ip'] = auto_detected_ip
293
+
294
+ # 添加/覆盖传入的元数据,但跳过None值以避免覆盖有效的默认值
295
+ for k, v in kwargs.items():
296
+ if v is not None:
297
+ metadata[k] = v
289
298
 
290
299
  # 处理 request_id(优先级:显式传入 > metadata中的x-request-id > RequestContext > 自动生成)
291
300
  if request_id is not None:
@@ -317,7 +326,7 @@ class SyncGrpcClient:
317
326
  """
318
327
  self.default_metadata.update(kwargs)
319
328
 
320
- def set_user_context(self, org_id: str, user_id: str, role: Role = Role.ACCOUNT, actor_id: Optional[str] = None):
329
+ def set_user_context(self, org_id: str, user_id: str, role: Role = Role.ACCOUNT, actor_id: Optional[str] = None, user_ip: Optional[str] = None):
321
330
  """
322
331
  设置用户上下文信息
323
332
 
@@ -326,16 +335,34 @@ class SyncGrpcClient:
326
335
  user_id: 用户ID
327
336
  role: 用户角色(默认为 ACCOUNT)
328
337
  actor_id: 操作者ID(如果不同于 user_id)
338
+ user_ip: 用户IP地址(实际请求用户的IP,如前端用户的IP)
329
339
  """
330
340
  self._user_context = UserContext(
331
341
  org_id=org_id,
332
342
  user_id=user_id,
333
343
  role=role,
334
- actor_id=actor_id
344
+ actor_id=actor_id,
345
+ user_ip=user_ip
335
346
  )
336
347
  # 更新到默认元数据
337
348
  self.update_default_metadata(**self._user_context.to_metadata())
338
349
 
350
+ def set_user_ip(self, user_ip: Optional[str]):
351
+ """
352
+ 设置或更新用户IP地址
353
+
354
+ Args:
355
+ user_ip: 用户IP地址(实际请求用户的IP,如前端用户的IP)
356
+ """
357
+ if self._user_context:
358
+ self._user_context.user_ip = user_ip
359
+ # 先移除旧的x-user-ip(如果存在)
360
+ self.default_metadata.pop('x-user-ip', None)
361
+ # 更新到默认元数据(只有非None值会被添加)
362
+ self.update_default_metadata(**self._user_context.to_metadata())
363
+ else:
364
+ raise ValueError("必须先调用 set_user_context 设置用户上下文,然后才能设置用户IP")
365
+
339
366
  def get_user_context(self) -> Optional[UserContext]:
340
367
  """获取当前用户上下文"""
341
368
  return self._user_context