#!/usr/bin/env python3 """Fill QSID=000001 P1 record with complete content""" import requests, json APP_TOKEN='CMHSbUUjka3TrUsaxxEc297ongf' APP_ID='cli_a931175d41799cc7' APP_SECRET='Iw2vEfbjT6GtV0GhbxbZqfQ4nAPtbR14' TABLE='tbliZAhcc9C43B23' RID='recuUjgbwn3Lkm' QSID='000001' r = requests.post('https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal', json={'app_id':APP_ID,'app_secret':APP_SECRET}, timeout=10) token = r.json()['tenant_access_token'] jd = { "first": { "category": "listening", "type": "listening_choicePic", "questionSetID": QSID, "textDesc": "听录音,选择正确的图片。", "questionSet": [ { "question": "This is a blue box.", "questionAudio": "", "optionsImage": None, "answer": [0], "ability": ["显性事实理解|单句信息点抓取"], "explanation": "听力中 Lily 说 'This is a blue box.'(这是一个蓝色的盒子),与图A蓝色方形卡通盒子相符,故选A。" }, { "question": "He is a police officer.", "questionAudio": "", "optionsImage": None, "answer": [0], "ability": ["显性事实理解|单句信息点抓取"], "explanation": "听力中 Tom 说 'He is a police officer.'(他是一名警察),与图A穿制服戴警帽的男警察相符,故选A。" }, { "question": "I want to drink milk.", "questionAudio": "", "optionsImage": None, "answer": [0], "ability": ["显性事实理解|单句信息点抓取"], "explanation": "听力中 Anna 说 'I want to drink milk.'(我想喝牛奶),与图A一杯热牛奶相符,故选A。" }, { "question": "I eat a sandwich for breakfast.", "questionAudio": "", "optionsImage": None, "answer": [0], "ability": ["显性事实理解|单句信息点抓取"], "explanation": "听力中 Bob 说 'I eat a sandwich for breakfast.'(我早餐吃三明治),与图A夹生菜火腿的三明治相符,故选A。" }, { "question": "This is my red suitcase.", "questionAudio": "", "optionsImage": None, "answer": [0], "ability": ["显性事实理解|单句信息点抓取"], "explanation": "听力中 Cindy 说 'This is my red suitcase.'(这是我的红色手提箱),与图A装满衣物的红色拉杆手提箱相符,故选A。" } ] }, "second": { "category": "listening", "type": "listening_choicePic", "questionSetID": QSID, "textDesc": "听录音,选择正确的图片。", "questionSet": [ { "question": "Look at my new clothes.", "questionAudio": "", "optionsImage": None, "answer": [0], "ability": ["显性细节理解|物品特征辨识"], "explanation": "听力中 Emma 说 'Look at my new clothes.'(看看我的新衣服)。卫衣属于衣物,图B为运动鞋、图C为棒球帽,均不属于衣物范畴,故选A蓝色连帽卫衣。" }, { "question": "My dad works at the airport.", "questionAudio": "", "optionsImage": None, "answer": [0], "ability": ["显性细节理解|数字/时间/地点"], "explanation": "听力中 Jack 说 'My dad works at the airport.'(我爸爸在机场工作),与图A停着飞机的机场航站楼场景相符,故选A。" }, { "question": "The pirate has a black eye patch.", "questionAudio": "", "optionsImage": None, "answer": [0], "ability": ["显性事实理解|单句信息点抓取"], "explanation": "听力中 Mike 说 'The pirate has a black eye patch.'(海盗戴着一个黑色的眼罩),图A戴眼罩的海盗与此描述完全匹配,故选A。" }, { "question": "I need my passport to go abroad.", "questionAudio": "", "optionsImage": None, "answer": [0], "ability": ["显性细节理解|物品功能辨识"], "explanation": "听力中 Lisa 说 'I need my passport to go abroad.'(我需要护照出国),图A为护照、图B为身份证、图C为银行卡,对应出国所需的证件是护照,故选A。" }, { "question": "I like eating cheese very much.", "questionAudio": "", "optionsImage": None, "answer": [0], "ability": ["显性细节理解|物品特征辨识"], "explanation": "听力中 Peter 说 'I like eating cheese very much.'(我非常喜欢吃芝士),与图A切成块的黄色芝士相符。图B是全麦面包、图C是黄油,均不是cheese,故选A。" } ] } } TEXT1 = """【题目描述】 听录音,选择正确的图片。 【听力文本】 1. Lily: This is a blue box. 2. Tom: He is a police officer. 3. Anna: I want to drink milk. 4. Bob: I eat a sandwich for breakfast. 5. Cindy: This is my red suitcase.""" TEXT2 = """【题目描述】 听录音,选择正确的图片。 【听力文本】 1. Emma: Look at my new clothes. 2. Jack: My dad works at the airport. 3. Mike: The pirate has a black eye patch. 4. Lisa: I need my passport to go abroad. 5. Peter: I like eating cheese very much.""" fields = { "题目集合 ID": QSID, "jsonData": json.dumps(jd, ensure_ascii=False), "题目1": TEXT1, "题目2": TEXT2, "dataStatus": "0", "审校结果": "✅ 已补全:10道题 content/explanation/ability 全部填充完成(2026-05-14)" } r = requests.put( f'https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE}/records/{RID}', headers={'Authorization': f'Bearer {token}', 'Content-Type': 'application/json'}, json={'fields': fields}, timeout=15) code = r.json().get('code') if code == 0: print('✅ 更新成功') # Verify r2 = requests.get(f'https://open.feishu.cn/open-apis/bitable/v1/apps/{APP_TOKEN}/tables/{TABLE}/records/{RID}', headers={'Authorization': f'Bearer {token}'}, timeout=10) jd2 = json.loads(r2.json()['data']['record']['fields']['jsonData']) f_qs = jd2['first']['questionSet'] s_qs = jd2['second']['questionSet'] print(f'\n验证:') for i, q in enumerate(f_qs): ok = len(q.get('question',''))>0 and len(q.get('explanation',''))>20 and len(q.get('ability',[]))>0 print(f' first Q{i+1}: {"✅" if ok else "❌"} q="{q["question"]}" answer={q["answer"]} ability={q["ability"]}') for i, q in enumerate(s_qs): ok = len(q.get('question',''))>0 and len(q.get('explanation',''))>20 and len(q.get('ability',[]))>0 print(f' second Q{i+1}: {"✅" if ok else "❌"} q="{q["question"]}" answer={q["answer"]} ability={q["ability"]}') f2 = r2.json()['data']['record']['fields'] print(f'\n题目1: {len(f2.get("题目1",""))}chars, 题目2: {len(f2.get("题目2",""))}chars') print(f'审校结果: {f2.get("审校结果","")}') else: print(f'❌ 失败: {r.json().get("msg")}')