itam-assistant 0.1.9__py3-none-any.whl → 0.1.11__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.
@@ -0,0 +1,289 @@
1
+ # -*- coding: utf-8 -*-
2
+ import copy
3
+ import http.client
4
+ import json
5
+ import time
6
+ import requests
7
+ itamheaders = {
8
+ 'authorization': 'Bearer eyJhbGciOiJSUzI1NiIsImtpZCI6InYyIiwidHlwIjoiSldUIn0.eyJleHAiOjE3NDI1NDYyMTcsImp0aSI6ImJKMk9hV0dkanU5QStMMXciLCJpYXQiOjE3NDEyNTAyMTcsImlzcyI6InRhbm5hIiwic3ViIjoiMzgzMDMxOUBieXRlZGFuY2UucGVvcGxlIiwidGVuYW50X2lkIjoiYnl0ZWRhbmNlLnBlb3BsZSIsInRlbmFudF9uYW1lIjoiIiwicHJvamVjdF9rZXkiOiJjcm1TZmdIVmU1dXhIMHJyIiwidW5pdCI6ImV1X25jIiwiYXV0aF9ieSI6Mn0.eHghtX4NOnD1uD65bzqv7n1J3mtnPPXJoVKIWDwl4PMZPkqc3FisH4RMXxDqeOyDCgRHYhmam7VEenl8T0UIKpzI8ad8yMiZytvAkNhclLjCdmokLB7DdwnbO1qeDLxdqjL-S3da0KHHkOT8j-rWR94XJ0N7T_snoko4Ovsp13w',
9
+ 'Content-Type': 'application/json'
10
+
11
+ }
12
+
13
+
14
+
15
+ class webapiClient():
16
+ def __init__(self, clientin):
17
+ """
18
+ 初始化 Client 实例,tenant_access_token 会在 Client 初始化时自动获取
19
+ """
20
+ headers = {
21
+ 'cookie': clientin['cookie'],
22
+ 'x-kunlun-token': clientin['x-kunlun-token'],
23
+ 'Content-Type': "application/json"}
24
+ self.headers = headers
25
+ self.itamheaders = headers
26
+ self.conn = http.client.HTTPSConnection("apaas.feishu.cn")
27
+
28
+ def get_intent_detail_list(self, startAt, pageSize):
29
+ """
30
+ outdata:
31
+ 对话ID 技能分发 用户输入
32
+ res_ = {
33
+ 'intentID': 7485259579248705537,
34
+ 'userInput': "我要申请一个鼠标",
35
+ 'skillLabels': ["GUI 设备/配件申请"],
36
+ 'apply_day':"",
37
+ 'apply_num':"",
38
+ 'asset_name':"",
39
+ 'device_type':""
40
+ }
41
+ """
42
+ # 输入参数类型和范围检查
43
+ if not isinstance(startAt, int) or startAt < 0:
44
+ raise ValueError("startAt 必须是一个非负整数")
45
+ if not isinstance(pageSize, int) or pageSize < 0:
46
+ raise ValueError("pageSize 必须是一个非负整数")
47
+
48
+ endAt = int(time.time()) or 1748361600
49
+ payload = json.dumps({
50
+ "startAt": startAt,
51
+ "endAt": endAt,
52
+ "matchIntentID": "",
53
+ "matchStatus": [],
54
+ "pageSize": pageSize + 1000
55
+ })
56
+ try:
57
+ self.conn.request("POST","/ai/api/v1/conversational_runtime/namespaces/spring_f17d05d924__c/stats/intent_detail_list",payload, self.headers)
58
+ res = self.conn.getresponse()
59
+ # 检查响应状态码
60
+ if res.status != 200:
61
+ raise http.client.HTTPException(f"请求失败,状态码: {res.status}, 原因: {res.reason}")
62
+
63
+ data = res.read()
64
+ try:
65
+ data = json.loads(data.decode("utf-8"))
66
+ except json.JSONDecodeError:
67
+ raise ValueError("无法将响应数据解析为 JSON 格式")
68
+
69
+ # 检查响应数据结构
70
+ if 'data' not in data or 'intentDetailList' not in data['data']:
71
+ raise ValueError("响应数据缺少必要的字段 'data' 或 'intentDetailList'")
72
+
73
+ res_list = []
74
+ data_ = data['data']['intentDetailList']
75
+ for i in data_:
76
+ if i['channelType'] in ["LARK_OPEN_API"]:
77
+ res_list.append({
78
+ '对话日志/intentID': i['intentID'],
79
+ '用户输入/userInput': i['userInput'],
80
+ '数据是否有效/isdatavalid': "是",
81
+ '语言/language': "zh",
82
+ '是否 IT 问题/isITproblem': "是",
83
+ '业务场景/businessscenario': "NULL",
84
+ '分发技能/skill': i['skillLabels'],
85
+ '型号关键字词/asset_name': "NULL",
86
+ '型号类型/device_type': "NULL",
87
+ '匹配型号/AssetNamelist': "NULL",
88
+ })
89
+ return res_list
90
+ except http.client.HTTPException as http_err:
91
+ print(f"HTTP 请求错误: {http_err}")
92
+ return res_list
93
+ except ValueError as value_err:
94
+ print(f"值错误: {value_err}")
95
+ return res_list
96
+ except Exception as general_err:
97
+ print(f"发生未知错误: {general_err}")
98
+ return res_list
99
+
100
+ def get_urlintentID(self, intentID):
101
+ """
102
+ 输入:intentID
103
+ 输出:url
104
+ """
105
+ max_retries = 3
106
+ retries = 0
107
+ while retries < max_retries:
108
+ try:
109
+ payload = ''
110
+ urlintentID = f'https://apaas.feishu.cn/ai/api/v1/conversational_runtime/namespaces/spring_f17d05d924__c/intent/{intentID}?pageSize=20&statusFilter=%5B%5D&fieldFilter=_node_id&fieldFilter=status&fieldFilter=usages&fieldFilter=_node_name&fieldFilter=_node_type&fieldFilter=title_for_maker&fieldFilter=associate_id'
111
+ response = requests.request("GET", urlintentID, headers=self.headers, data=payload)
112
+ # 检查响应状态码
113
+ response.raise_for_status()
114
+ response = response.json()
115
+ # 检查特定错误状态码
116
+ if 'status_code' in response and response['status_code'] == "k_gw_ec_100033":
117
+ retries += 1
118
+ if retries < max_retries:
119
+ print(f"接口不存在,正在进行第 {retries} 次重试...")
120
+ continue
121
+ else:
122
+ print(f"接口不存在,已达到最大重试次数 {max_retries} 次")
123
+ return None
124
+ return response
125
+ except (requests.RequestException, json.JSONDecodeError) as e:
126
+ retries += 1
127
+ if retries < max_retries:
128
+ print(f"请求失败,原因: {e},正在进行第 {retries} 次重试...")
129
+ else:
130
+ print(f"请求失败,已达到最大重试次数 {max_retries} 次,原因: {e}")
131
+ return None
132
+
133
+ def get_urlnodeid(self, intentID, nodeid):
134
+ """
135
+ 输入:intentID
136
+ 输出:url
137
+ """
138
+ max_retries = 3
139
+ retries = 0
140
+ while retries < max_retries:
141
+ try:
142
+ payload = ''
143
+ urlnodeid = f'https://apaas.feishu.cn/ai/api/v1/conversational_runtime/namespaces/spring_f17d05d924__c/association/{intentID}/node/{nodeid}?intentID={intentID}'
144
+ response = requests.request("GET", urlnodeid, headers=self.headers, data=payload)
145
+ # 检查响应状态码
146
+ response.raise_for_status()
147
+ response = response.json()
148
+ # 检查特定错误状态码
149
+ if 'status_code' in response and response['status_code'] == "k_gw_ec_100033":
150
+ retries += 1
151
+ if retries < max_retries:
152
+ print(f"接口不存在,正在进行第 {retries} 次重试...")
153
+ continue
154
+ else:
155
+ print(f"接口不存在,已达到最大重试次数 {max_retries} 次")
156
+ return None
157
+ return response
158
+ except (requests.RequestException, json.JSONDecodeError) as e:
159
+ retries += 1
160
+ if retries < max_retries:
161
+ print(f"请求失败,原因: {e},正在进行第 {retries} 次重试...")
162
+ else:
163
+ print(f"请求失败,已达到最大重试次数 {max_retries} 次,原因: {e}")
164
+ return None
165
+
166
+
167
+
168
+ def get_intent_detail_llm(self, res_list):
169
+ """
170
+ 提取关键词:
171
+ 槽位提取:'apply_day': "",'apply_num': "",'asset_name': "",'device_type': ""
172
+ 表头字段:
173
+ '对话日志/intentID': 7485264011232886786,
174
+ '用户输入/userInput': "我要申请一个鼠标",
175
+ '数据是否有效/isdatavalid': "是",
176
+ '语言/language': "zh",
177
+ '是否 IT 问题/isITproblem': "是",
178
+ '业务场景/businessscenario': "NULL",
179
+ '分发技能/skill': "NULL",
180
+ '型号关键字词/asset_name': "NULL", #显示器
181
+ '型号类型/device_type': "NULL", # 设备 配件 软件
182
+ '匹配型号/AssetNamelist': "NULL",
183
+ """
184
+ ii0 = []
185
+ ii = {
186
+ '对话日志/intentID': "7485264011232886786",
187
+ '用户输入/userInput': "我要申请一个鼠标",
188
+ '数据是否有效/isdatavalid': "是",
189
+ '语言/language': "zh",
190
+ '是否 IT 问题/isITproblem': "是",
191
+ '业务场景/businessscenario': "NULL",
192
+ '分发技能/skill': "NULL",
193
+ 'llm关键词': "NULL"
194
+ }
195
+ try:
196
+ # 检查 res_list 是否为空
197
+ if not res_list:
198
+ print("输入的 res_list 为空")
199
+ return []
200
+ for i in res_list:
201
+ print("urlintentID_1:" + str(i))
202
+ ii['分发技能/skill'] = i['分发技能/skill']
203
+ ii['对话日志/intentID'] = i['对话日志/intentID']
204
+ ii['用户输入/userInput'] = i['用户输入/userInput']
205
+ intentID = str(ii['对话日志/intentID'])
206
+ res_ = self.get_urlintentID(intentID)
207
+ if res_ is None:
208
+ continue
209
+ response = res_
210
+ for j in response['data']['steps']:
211
+ if j['titleForMaker'] in ["槽位抽取", "LLM 2", "LLM"]:
212
+ nodeid = j['nodeID']
213
+ data_nodeid = self.get_urlnodeid(intentID, nodeid)
214
+ if data_nodeid is None or 'data' not in data_nodeid or 'step' not in data_nodeid['data'] or 'output' not in data_nodeid['data']['step'] or data_nodeid['data']['step']['output'] == "":
215
+ ii['llm关键词'] = "NULL"
216
+ else:
217
+ ii['llm关键词'] = json.loads(data_nodeid['data']['step']['output'])['response']
218
+ ii0.append(copy.deepcopy(ii))
219
+ return ii0
220
+ except requests.RequestException as req_err:
221
+ print(f"请求错误: {req_err}")
222
+ return ii0
223
+ except Exception as general_err:
224
+ print(f"发生未知错误: {general_err}")
225
+ return ii0
226
+
227
+ def get_bestmatchitemforreturn(self, keyword):
228
+ """
229
+ mock数据,获取最佳匹配的sku/spu
230
+ mock数据:公用配件列表、设备列表、软件列表
231
+ todo:mock数据表格为飞书文档或者其他?
232
+ """
233
+ _urlGetBestMatchItemForReturn = "https://asset-mig-pre.bytedance.net/aily/api/itservice/ai/GetBestMatchItemForReturn"
234
+
235
+ payload = json.dumps({
236
+ "SearchKey": keyword,
237
+ "AiUseType": 1,
238
+ "ListReturnableAccessoryRequest": {
239
+ "IsAll": True,
240
+ "Page": {
241
+ "PageNum": 1,
242
+ "PageSize": 30
243
+ },
244
+ "OwnerUserID": "",
245
+ "AccessoryApplyTypeList": []
246
+ },
247
+ "GetAssetListRequest": {
248
+ "Status": 6,
249
+ "Search": "",
250
+ "IsAll": True,
251
+ "SubStatusList": [
252
+ 12,
253
+ 18,
254
+ 19
255
+ ],
256
+ "Page": {
257
+ "PageNum": 1,
258
+ "PageSize": 30
259
+ },
260
+ "OrganizationalUnitID": 1
261
+ }
262
+ })
263
+ response = requests.request("GET", _urlGetBestMatchItemForReturn, headers=self.headers, data=payload)
264
+ response = json.loads(response.text)
265
+
266
+ def get_segsearchcandidates(self, res_list):
267
+ # 获取分数值
268
+ ### 读取设备&配件的信息并拼接到text里面
269
+ ### 遍历res_list中的device_name
270
+ ###判断是否在asset.json里面
271
+ ###调用算法接口获取设备&配件的分数值
272
+ pass
273
+
274
+
275
+ """"""
276
+ if __name__ == '__main__':
277
+ clientin = {
278
+ 'cookie': 'X-Kunlun-SessionId=L%3A028d306c70a340a69fe9.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2YWwiOnsidGVuYW50X2lkIjozOTAsInVzZXJfaWQiOjE3MjIxNjYwNzMxOTk2NDUsInRlbmFudF9kb21haW5fbmFtZSI6ImFwYWFzIiwic2Vzc2lvbl92ZXJzaW9uIjoidjIwMjAtMDUtMTkiLCJ3c190b2tlbiI6Ilc6ZTU3MmJlYzNmOGIzNDE0ZDk0NDYiLCJsb2dpbl90b2tlbiI6IjE3MDE3ZmFlMWJlNjVlMzc2V1VhMzA0ZjY0N2MyZmFjY2QwZ256YmNmNGVjNzAzZDgwOWYxNHJPWTY0MzY1ZjEyNWI0YmZlZDhreUciLCJzb3VyY2VfY2hhbm5lbCI6ImZlaXNodSIsInRlbmFudF9rZXkiOiI3MzY1ODhjOTI2MGYxNzVkIiwiZXh0ZXJuYWxfZG9tYWluX25hbWUiOiJieXRlZGFuY2UiLCJvcmlnaW5hbF90ZW5hbnRfaWQiOjAsIm9yaWdpbmFsX3VzZXJfaWQiOjAsImlkcF9jaGFubmVsIjoiIn0sImV4cCI6MTc2Mzg4MzY0NX0.VWyqct9gPOSXiX_72IqCRAknHsJK1aaZLIZ4gICbH5U; gd_random=eyJwZXJjZW50IjowLjY4NTgwODU2NDE4ODc2MjcsIm1hdGNoIjpmYWxzZX0=.iBiK3be8U+wA12/YghnWQbmDRz/vrBS/OQJpAvYx4XY=; trust_browser_id=3686a9b0-ce48-4e07-a0ce-e6928dc2bd6a; X-Kunlun-LoginTag=feishu; passport_trace_id=7389204030662426627; passport_web_did=7424353640858812419; QXV0aHpDb250ZXh0=9bcf0657fb6e47d497625011ffcd73e7; lark_sso_session=XN0YXJ0-488md350-54b2-433e-9eeb-b7a5c700ea26-WVuZA; X-Larkgw-Web-DID=3439857258174095984; X-Larkgw-Use-Lark-Session-119=1; __tea__ug__uid=7441424216023565850; is_anonymous_session=; fid=24c45ffc-f3d7-44f2-87ed-421f54ee78fb; lang=zh; i18n_locale=zh; locale=zh-CN; _gcl_au=1.1.2073766041.1742190427; _uetvid=44545540063311f08ed91353a6123699; _ga_7PY069DX7K=GS1.1.1742549605.1.0.1742549605.60.0.0; s_v_web_id=verify_m8cn771e_wyNgDZJ9_u4vt_4Tcr_8GHG_aoFTRqp3UEgK; _csrf_token=8d1282b097e1c2e7aea50829b47ffb77a72db55f-1745993230; help_center_session=7b5fca25-c6c5-4106-9d93-8709981a6957; _uuid_hera_ab_path_1=7502360423243071516; Hm_lvt_a79616d9322d81f12a92402ac6ae32ea=1746779408; apaas_web_did=1832530807807051; _tea_utm_cache_1229=undefined; lgw_csrf_token=c540cf747b5b41c2f749a2e1c0bd0900c3eb71b2-1747901330; _ga=GA1.2.113646166.1700115833; _gid=GA1.2.1661485038.1748331634; landing_url=https://accounts.feishu.cn/accounts/page/login?app_id=107&no_trap=1&redirect_uri=https%3A%2F%2Fapaas.feishu.cn%2Fai%2Fspring_f17d05d924__c%2Fmanagement%2Fchat-log; session=XN0YXJ0-583sf83f-7ceb-44bc-8578-0692b8383b7c-WVuZA; session_list=XN0YXJ0-583sf83f-7ceb-44bc-8578-0692b8383b7c-WVuZA; _ga_VPYRHN104D=GS2.1.s1748331633$o2$g1$t1748331645$j48$l0$h0; kunlun-session-v2=L%3A028d306c70a340a69fe9.eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ2YWwiOnsidGVuYW50X2lkIjozOTAsInVzZXJfaWQiOjE3MjIxNjYwNzMxOTk2NDUsInRlbmFudF9kb21haW5fbmFtZSI6ImFwYWFzIiwic2Vzc2lvbl92ZXJzaW9uIjoidjIwMjAtMDUtMTkiLCJ3c190b2tlbiI6Ilc6ZTU3MmJlYzNmOGIzNDE0ZDk0NDYiLCJsb2dpbl90b2tlbiI6IjE3MDE3ZmFlMWJlNjVlMzc2V1VhMzA0ZjY0N2MyZmFjY2QwZ256YmNmNGVjNzAzZDgwOWYxNHJPWTY0MzY1ZjEyNWI0YmZlZDhreUciLCJzb3VyY2VfY2hhbm5lbCI6ImZlaXNodSIsInRlbmFudF9rZXkiOiI3MzY1ODhjOTI2MGYxNzVkIiwiZXh0ZXJuYWxfZG9tYWluX25hbWUiOiJieXRlZGFuY2UiLCJvcmlnaW5hbF90ZW5hbnRfaWQiOjAsIm9yaWdpbmFsX3VzZXJfaWQiOjAsImlkcF9jaGFubmVsIjoiIn0sImV4cCI6MTc2Mzg4MzY0NX0.VWyqct9gPOSXiX_72IqCRAknHsJK1aaZLIZ4gICbH5U; kunlun-session-token=e337d885c13162ff663d9a991e6eb54f7dd3e04e539c8b817a923e225a87d3aa; msToken=su30ijthwqpaGKP8qOkL3viO1aXYouV3yjJ_EXTKoIlvgSJva8VvCSVRhhd1kKUHF6qdrLnsH6MF28bg8N3V1WVMmSA1ccqF8tPmt6YL0jVYhI6SePZBvIS6MJE2xkWY7vSYBCMoNax8pj4oITBwrtP_rG6yt25SlSFDdzu9WwYL; passport_app_access_token=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDg0MDA5NTYsInVuaXQiOiJldV9uYyIsInJhdyI6eyJtX2FjY2Vzc19pbmZvIjp7IjEwNyI6eyJpYXQiOjE3NDgzNTc3NTYsImFjY2VzcyI6dHJ1ZX19LCJzdW0iOiI3NmY5MmYyNDQ4MDczNjc1MTA3NmI5ZTgyYzYyZWJmN2M3NzE0ZWVlOTM3YTg1NDUzZjhmNzc4NjEzYzY2NTBjIn19.qCGZwBOJ0tpGfLjtnncUTmLEai6u4D5me5ga-N8Tter0Ey5L6do2FPxoOacqLj1Wj2hxyHSTfad60hSsMTkPaQ; sl_session=eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NDg0MDM1NTQsInVuaXQiOiJldV9uYyIsInJhdyI6eyJtZXRhIjoiQVdIazBuRzhRUUFDQUFBQUFBQUFBQUZuQ0pwTTZrU0FBMmNJbWt6cVJJQURaeklSUnZpQUFBRUNLZ0VBUVVGQlFVRkJRVUZCUVVKdlRsZDRPVTVvU2tGQlp6MDkiLCJzdW0iOiI3NmY5MmYyNDQ4MDczNjc1MTA3NmI5ZTgyYzYyZWJmN2M3NzE0ZWVlOTM3YTg1NDUzZjhmNzc4NjEzYzY2NTBjIiwibG9jIjoiemhfY24iLCJhcGMiOiJSZWxlYXNlIiwiaWF0IjoxNzQ4MzYwMzU0LCJzYWMiOnsiVXNlclN0YWZmU3RhdHVzIjoiMSIsIlVzZXJUeXBlIjoiNDIifSwibG9kIjpudWxsLCJjbmYiOnsiamt0IjoiRWtuRFMyTmdZVDR4Y2xZRDM4UU9KUHNkUFptLVluRHRaR3ZmX1hfSTJxTSJ9LCJucyI6ImxhcmsiLCJuc191aWQiOiI3MDUzOTk0MzAyMzAwNTUzMjE4IiwibnNfdGlkIjoiMSIsIm90IjozLCJjdCI6MTc0ODMzMTY0NSwicnQiOjE3NDgzMzE2NDV9fQ.BP9Q4Wxdq_TWB898FxFr4TlpqUN8-N1QC6fFWO57C8wiNeAcFNUfed8mGdd7kvBgbC5PjwnNJjoL0iXySUpuXQ; swp_csrf_token=dd289ebe-0ce4-42d2-aece-263b6abf2d45; t_beda37=e1445dd5c8a191cc38f34d9809eb3c5179904df5285bb079d87b96baad8ee3e5',
279
+ "x-kunlun-token": "17017fae1be65e376WUa304f647c2faccd0gnzbcf4ec703d809f14rOY64365f125b4bfed8kyG"
280
+
281
+ }
282
+ startAt = 1748410380
283
+ num = 1230
284
+ res_list = webapiClient(clientin).get_intent_detail_list(1748410380,10)
285
+ a = webapiClient(clientin).get_intent_detail_llm(res_list)
286
+
287
+
288
+
289
+
@@ -0,0 +1,159 @@
1
+ import json
2
+
3
+ import lark_oapi as lark
4
+ from lark_oapi.api.sheets.v3 import *
5
+
6
+
7
+ # SDK 使用说明: https://open.feishu.cn/document/uAjLw4CM/ukTMukTMukTM/server-side-sdk/python--sdk/preparations-before-development
8
+ # 以下示例代码默认根据文档示例值填充,如果存在代码问题,请在 API 调试台填上相关必要参数后再复制代码使用
9
+
10
+ class LarkdocsClient:
11
+ def __init__(self):
12
+ """
13
+ 初始化 Client 实例,tenant_access_token 会在 Client 初始化时自动获取
14
+ https://github.com/larksuite/oapi-sdk-python
15
+ """
16
+ self.app_id = "cli_a48be9fd54a5900d"
17
+ self.app_secret = "pfiNeWKbkfbRvUunX3TrKdCCnftlUbxl"
18
+ # 创建 Lark 客户端
19
+ self.lark_client = lark.Client.builder().app_id(self.app_id).app_secret(self.app_secret).build()
20
+
21
+ def get_the_worksheet(self, spreadsheet_token):
22
+
23
+ # 获取工作表
24
+ # 创建client
25
+ # 使用 user_access_token 需开启 token 配置, 并在 request_option 中配置 token
26
+ # 构造请求对象
27
+ try:
28
+ request: QuerySpreadsheetSheetRequest = QuerySpreadsheetSheetRequest.builder() \
29
+ .spreadsheet_token(spreadsheet_token) \
30
+ .build()
31
+
32
+ # 发起请求
33
+ # option = self.lark_client.RequestOption.builder().user_access_token(
34
+ # "u-hQ.Vthwt5blbznh92YFKhflkkfsAl5R3hW20l5cy07ag").build()
35
+ response: QuerySpreadsheetSheetResponse = self.lark_client.sheets.v3.spreadsheet_sheet.query(request)
36
+
37
+ # 处理失败返回
38
+ if not response.success():
39
+ lark.logger.error(
40
+ f"client.sheets.v3.spreadsheet_sheet.query failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}")
41
+ return
42
+ return response.data
43
+ # 处理业务结果
44
+ lark.logger.info(lark.JSON.marshal(response.data, indent=4))
45
+ except Exception as e:
46
+ lark.logger.error(f"[lark]get user id by email failed, err: {e}")
47
+ return None, e
48
+
49
+ def get_plaintextcontent(self, ranges, spreadsheet_token, sheet_id):
50
+ # 创建client
51
+ # 使用 user_access_token 需开启 token 配置, 并在 request_option 中配置 token
52
+ # 构造请求对象
53
+ # 构造请求对象
54
+ # json_str = "{\"ranges\":[\"459f7e!A1:A1\"]}"
55
+ body = ranges
56
+ request: lark.BaseRequest = lark.BaseRequest.builder() \
57
+ .http_method(lark.HttpMethod.POST) \
58
+ .uri(f"/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{str(sheet_id)}/values/batch_get_plain") \
59
+ .token_types({lark.AccessTokenType.TENANT}) \
60
+ .body(body) \
61
+ .build()
62
+
63
+ # 发起请求
64
+ response: lark.BaseResponse = self.lark_client.request(request)
65
+
66
+ # 处理失败返回
67
+ if not response.success():
68
+ lark.logger.error(
69
+ f"client.request failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}")
70
+ return
71
+
72
+ # 处理业务结果
73
+ lark.logger.info(str(response.raw.content, lark.UTF_8))
74
+ return str(response.raw.content, lark.UTF_8)
75
+
76
+
77
+ def createsheets(self, spreadsheet_token, title):
78
+ # 创建工作表
79
+ # json_str = "{\"index\":0,\"title\":\"abc\"}"
80
+ # 构造请求对象
81
+ body = title
82
+ request: lark.BaseRequest = lark.BaseRequest.builder() \
83
+ .http_method(lark.HttpMethod.POST) \
84
+ .uri(f"/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets") \
85
+ .token_types({lark.AccessTokenType.TENANT}) \
86
+ .body(body) \
87
+ .build()
88
+
89
+ # 发起请求
90
+ response: lark.BaseResponse = self.lark_client.request(request)
91
+
92
+ # 处理失败返回
93
+ if not response.success():
94
+ lark.logger.error(
95
+ f"client.request failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}")
96
+ return
97
+
98
+ # 处理业务结果
99
+ lark.logger.info(str(response.raw.content, lark.UTF_8))
100
+ return json.loads(response.raw.content)['data']['sheet']
101
+
102
+
103
+ def writesheets(self, spreadsheet_token, sheet_id, data):
104
+ # 创建client
105
+ # 使用 user_access_token 需开启 token 配置, 并在 request_option 中配置 token
106
+ # 构造请求对象
107
+ # 构造请求对象
108
+ json_str = "{\"value_ranges\":[{\"range\":\"HEJb8z!C1:C1\",\"values\":[[[{\"text\":{\"text\":\"abc\"},\"type\":\"text\"}]]]}]}"
109
+ body = json.loads(json_str)
110
+ body = data
111
+ request: lark.BaseRequest = lark.BaseRequest.builder() \
112
+ .http_method(lark.HttpMethod.POST) \
113
+ .uri(
114
+ f"/open-apis/sheets/v3/spreadsheets/{spreadsheet_token}/sheets/{sheet_id}/values/batch_update?user_id_type=open_id") \
115
+ .token_types({lark.AccessTokenType.TENANT}) \
116
+ .body(body) \
117
+ .build()
118
+
119
+ # 发起请求
120
+ response: lark.BaseResponse = self.lark_client.request(request)
121
+
122
+ # 处理失败返回
123
+ if not response.success():
124
+ lark.logger.error(
125
+ f"client.request failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}")
126
+ return
127
+
128
+ # 处理业务结果
129
+ lark.logger.info(str(response.raw.content, lark.UTF_8))
130
+
131
+
132
+ if __name__ == '__main__':
133
+ spreadsheet_token = ""
134
+ sheets = LarkdocsClient().get_the_worksheet(spreadsheet_token)
135
+ for i in sheets.sheets:
136
+
137
+ column_count = i.grid_properties.column_count
138
+ row_count = i.grid_properties.row_count
139
+ sheet_id = i.sheet_id
140
+ title = i.title
141
+
142
+ #print(column_count, row_count, sheet_id, title)
143
+ json_str = {"ranges": ["459f7e!A1:A1"]}
144
+ json_str = {"ranges": [sheet_id + "!A1:A" + str(row_count)]}
145
+ test = LarkdocsClient().get_plaintextcontent(json_str, spreadsheet_token, sheet_id)
146
+ test = json.loads(test)
147
+ userinput = test['data']['value_ranges'][0]['values']
148
+ print(f"表头为{userinput[0]}")
149
+ i = 0
150
+ for i in range(1,row_count):
151
+ if userinput[i][0]:
152
+ print(userinput[i][0])
153
+ else:
154
+ break
155
+
156
+
157
+
158
+
159
+
it_assistant/logger.py ADDED
@@ -0,0 +1,53 @@
1
+ import os
2
+ import logging.config
3
+
4
+ config = {
5
+ 'version': 1,
6
+ 'disable_existing_loggers': False,
7
+ 'formatters': {
8
+ 'default': {
9
+ 'format': '%(asctime)s %(levelname)s %(message)s'
10
+ }
11
+ },
12
+ 'loggers': {
13
+ 'playground': {
14
+ 'handlers': ['log_agent', 'console', 'kafka_agent'],
15
+ 'propagate': False,
16
+ 'level': 'INFO',
17
+ },
18
+ 'root': {
19
+ 'handlers': ['log_agent', 'console'],
20
+ 'level': 'INFO'
21
+ }
22
+ },
23
+ 'handlers': {
24
+ 'log_agent': {
25
+ 'level': 'INFO',
26
+ 'class': 'bytedlogger.StreamLogHandler',
27
+ 'tags': {
28
+ 'customtag': 'devops_boe',
29
+ }
30
+ },
31
+ 'kafka_agent': {
32
+ 'level': 'INFO',
33
+ 'class': 'kafkalogger.handlers.KafkaLogHandler',
34
+ 'formatter': 'default',
35
+ },
36
+ 'console': {
37
+ 'level': 'INFO',
38
+ 'class': 'logging.StreamHandler',
39
+ }
40
+ },
41
+
42
+ }
43
+ if os.getenv("DEBUG") == "true":
44
+ config["handlers"].pop("kafka_agent")
45
+ config["handlers"].pop("log_agent")
46
+ config["loggers"]["playground"]["handlers"].remove("kafka_agent")
47
+ config["loggers"]["playground"]["handlers"].remove("log_agent")
48
+ config['loggers']['root']['handlers'].remove("log_agent")
49
+ logging.config.dictConfig(config)
50
+ logger = logging.getLogger('playground')
51
+ logging.getLogger("kafka").setLevel(logging.CRITICAL)
52
+ logging.getLogger("bytedkafka.common.config").setLevel(logging.ERROR)
53
+ logging.getLogger("kafka.producer.kafka").setLevel(logging.ERROR)