fei_shu.py 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import os
  2. import uuid
  3. from typing import Any, Dict, Optional
  4. import lark_oapi as lark
  5. from lark_oapi.core.enum import LogLevel
  6. class FeiShu(object):
  7. _instance = None
  8. def __new__(cls, *args, **kwargs):
  9. if cls._instance is None:
  10. cls._instance = super().__new__(cls, *args, **kwargs)
  11. return cls._instance
  12. def __init__(self):
  13. app_id = os.getenv('FEISHU_APP_ID')
  14. app_secret = os.getenv('FEISHU_APP_SECRET')
  15. self.file_token = os.getenv('FEISHU_FILE_TOKEN')
  16. self.client = (lark.client.Client().builder()
  17. .app_id(app_id)
  18. .app_secret(app_secret)
  19. .log_level(LogLevel.INFO)
  20. .build())
  21. def create_table(self, name: str) -> str:
  22. request = (lark.bitable.v1.CreateAppTableRequest.builder()
  23. .app_token(self.file_token)
  24. .request_body(lark.bitable.v1.CreateAppTableRequestBody.builder()
  25. .table(lark.bitable.v1.ReqTable.builder()
  26. .name(name)
  27. .fields([
  28. lark.bitable.v1.AppTableCreateHeader.builder().field_name('原文链接').type(15).build(),
  29. lark.bitable.v1.AppTableCreateHeader.builder().field_name('抓取结果').type(1).build(),
  30. lark.bitable.v1.AppTableCreateHeader.builder().field_name('识别结果').type(1).build(),
  31. lark.bitable.v1.AppTableCreateHeader.builder().field_name('初步理解').type(1).build(),
  32. ])
  33. .build())
  34. .build())
  35. .build())
  36. response = self.client.bitable.v1.app_table.create(request)
  37. if not response.success():
  38. raise RuntimeError(f'多维表格创建新数据表失败: {lark.JSON.marshal(response.error)}')
  39. return response.data.table_id
  40. def get_all_records(self, table_id: str, page_token: Optional[str] = None):
  41. request = (lark.bitable.v1.SearchAppTableRecordRequest.builder()
  42. .app_token(self.file_token)
  43. .table_id(table_id)
  44. .user_id_type('open_id')
  45. .page_size(500)
  46. .request_body(lark.bitable.v1.SearchAppTableRecordRequestBody.builder()
  47. .automatic_fields(True)
  48. .build()))
  49. if page_token:
  50. request = request.page_token(page_token)
  51. request = request.build()
  52. response = self.client.bitable.v1.app_table_record.search(request)
  53. if not response.success():
  54. raise RuntimeError(f'获取多维表格记录失败: {lark.JSON.marshal(response.error)}')
  55. return response.data
  56. def get_record(self, table_id: str, *record_ids: str):
  57. request = (lark.bitable.v1.BatchGetAppTableRecordRequest.builder()
  58. .app_token(self.file_token)
  59. .table_id(table_id)
  60. .request_body(lark.bitable.v1.BatchGetAppTableRecordRequestBody.builder()
  61. .record_ids(list(record_ids))
  62. .user_id_type('open_id')
  63. .with_shared_url(True)
  64. .automatic_fields(True)
  65. .build())
  66. .build())
  67. response = self.client.bitable.v1.app_table_record.batch_get(request)
  68. if not response.success():
  69. raise RuntimeError(f'获取多维表格指定记录失败: {lark.JSON.marshal(response.error)}')
  70. return response.data
  71. def create_record(self, table_id: str, *fields: Dict[str, Any]):
  72. request = (lark.bitable.v1.BatchCreateAppTableRecordRequest.builder()
  73. .app_token(self.file_token)
  74. .table_id(table_id)
  75. .user_id_type('open_id')
  76. .client_token(str(uuid.uuid4()))
  77. .ignore_consistency_check(False)
  78. .request_body(lark.bitable.v1.BatchCreateAppTableRecordRequestBody.builder()
  79. .records([lark.bitable.v1.AppTableRecord.builder()
  80. .fields(item)
  81. .build() for item in fields])
  82. .build())
  83. .build())
  84. response = self.client.bitable.v1.app_table_record.batch_create(request)
  85. if not response.success():
  86. raise RuntimeError(f'向多维表格添加记录失败: {lark.JSON.marshal(response.error)}')
  87. return response.data
  88. def update_record(self, table_id: str, *records: lark.bitable.v1.AppTableRecord):
  89. request = (lark.bitable.v1.BatchUpdateAppTableRecordRequest.builder()
  90. .app_token(self.file_token)
  91. .table_id(table_id)
  92. .user_id_type('open_id')
  93. .ignore_consistency_check(False)
  94. .request_body(lark.bitable.v1.BatchUpdateAppTableRecordRequestBody.builder()
  95. .records(list(records))
  96. .build())
  97. .build())
  98. response = self.client.bitable.v1.app_table_record.batch_update(request)
  99. if not response.success():
  100. raise RuntimeError(f'更新多维表格指定记录失败: {lark.JSON.marshal(response.error)}')
  101. return response.data
  102. def delete_record(self, table_id: str, *record_ids: str):
  103. request = (lark.bitable.v1.BatchDeleteAppTableRecordRequest.builder()
  104. .app_token(self.file_token)
  105. .table_id(table_id)
  106. .request_body(lark.bitable.v1.BatchDeleteAppTableRecordRequestBody.builder()
  107. .records(list(record_ids))
  108. .build())
  109. .build())
  110. response = self.client.bitable.v1.app_table_record.batch_delete(request)
  111. if not response.success():
  112. raise RuntimeError(f'删除多维表格指定记录失败: {lark.JSON.marshal(response.error)}')
  113. return response.data
  114. if __name__ == '__main__':
  115. feishu = FeiShu()
  116. # 创建数据表
  117. new_table_id = feishu.create_table('测试数据表')
  118. # 新增记录
  119. new_fields = [
  120. {
  121. '原文链接': {
  122. 'link': 'https://www.baidu.com',
  123. 'text': 'https://www.baidu.com',
  124. },
  125. '抓取结果': '这是抓取结果1',
  126. },
  127. {
  128. '原文链接': {
  129. 'link': 'https://www.qq.com',
  130. 'text': 'https://www.qq.com',
  131. },
  132. '抓取结果': '这是抓取结果2',
  133. }
  134. ]
  135. feishu.create_record(new_table_id, *new_fields)
  136. # 获取全部记录
  137. get_result = feishu.get_all_records(new_table_id)
  138. has_more = get_result.has_more # 是否有下一页
  139. next_page_token = get_result.page_token # 下一页token
  140. new_record_ids = []
  141. for record in get_result.items:
  142. new_record_ids.append(record.record_id)
  143. print(record.fields)
  144. # 更新记录
  145. new_record = (lark.bitable.v1.AppTableRecord.builder()
  146. .record_id(new_record_ids[0])
  147. .fields({'识别结果': '这是识别结果'})
  148. .build())
  149. feishu.update_record(new_table_id, new_record)
  150. # 获取指定ID记录
  151. get_result = feishu.get_record(new_table_id, *new_record_ids)
  152. for record in get_result.records:
  153. new_record_ids.append(record.record_id)
  154. print(record.fields)
  155. # 删除指定ID记录
  156. feishu.delete_record(new_table_id, new_record_ids[1])