WebsocketTest 1.0.0__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.
@@ -0,0 +1,72 @@
1
+ Metadata-Version: 2.1
2
+ Name: WebsocketTest
3
+ Version: 1.0.0
4
+ Summary: websocket api autotest
5
+ Author: chencheng
6
+ Requires-Python: >=3.7
7
+ Description-Content-Type: text/markdown
8
+
9
+ # WebSocket 接口自动化测试工具 (WS_API_TEST)
10
+
11
+ #### 介绍
12
+
13
+ 这是一个基于 WebSocket 协议的接口自动化测试工具。它可以用于自动化测试 WebSocket 接口,确保接口的稳定性和可靠性。
14
+
15
+ #### 系统要求
16
+
17
+ **Python 3.10+**:确保你的系统上已经安装了 Python 3.10(推荐使用最新稳定版)。
18
+ **项目依赖**:项目需要一些第三方库,可以通过 requirements.txt 文件安装。
19
+
20
+ #### 安装步骤
21
+
22
+ **1.安装 Python:**
23
+ 确保你的系统上已经安装了 Python 3.10 或更高版本。你可以从 [Python 官方网站 ](https://www.python.org/downloads/?spm=5176.28103460.0.0.40f75d27PnqPkU)下载并安装。
24
+ **2.克隆项目:**
25
+ 使用 Git 克隆项目到你的本地机器。
26
+
27
+ ```
28
+ git clone https://code.iflytek.com/ZNQC_AUTO_AI/python_scripts.git
29
+ cd python_scripts
30
+ git checkout WS_API_TEST
31
+ ```
32
+
33
+ **3.安装项目依赖:**
34
+ 使用 pip 安装项目所需的依赖库。
35
+
36
+ ```
37
+ pip install -r requirements.txt
38
+ ```
39
+ **4.运行项目:**
40
+ 你可以通过以下两种方式之一来运行项目:
41
+
42
+ * **使用命令行**:
43
+ 在命令行中运行以下命令:
44
+
45
+ ```
46
+ python run_tests.py --env uat --app 3d7d3ea4 --service gateway_5.4 --project vwa
47
+ ```
48
+
49
+ * **使用批处理脚本**:
50
+ 双击 run_tests.bat 文件来运行项目。
51
+
52
+ #### 项目结构
53
+ ├─allure_report
54
+ ├─allure_results
55
+ ├─build
56
+ ├─common
57
+ ├─config
58
+ ├─data
59
+ ├─dist
60
+ ├─logs
61
+ ├─testcase
62
+
63
+ * **文件说明**:
64
+ **allure_report**:存放 Allure 生成的 HTML 报告,用于展示测试结果。
65
+ **allure_results**:存放 Allure 生成的测试结果数据文件,如 result-12345.xml。
66
+ **build**:存放构建过程中生成的临时文件
67
+ **common**:存放通用的工具类
68
+ **config**:存放环境配置文件
69
+ **data**:存放测试数据文件
70
+ **dist**:存放最终发布的测试包
71
+ **logs**:存放运行日志文件
72
+ **testcase**:存放测试用例脚本
@@ -0,0 +1,64 @@
1
+ # WebSocket 接口自动化测试工具 (WS_API_TEST)
2
+
3
+ #### 介绍
4
+
5
+ 这是一个基于 WebSocket 协议的接口自动化测试工具。它可以用于自动化测试 WebSocket 接口,确保接口的稳定性和可靠性。
6
+
7
+ #### 系统要求
8
+
9
+ **Python 3.10+**:确保你的系统上已经安装了 Python 3.10(推荐使用最新稳定版)。
10
+ **项目依赖**:项目需要一些第三方库,可以通过 requirements.txt 文件安装。
11
+
12
+ #### 安装步骤
13
+
14
+ **1.安装 Python:**
15
+ 确保你的系统上已经安装了 Python 3.10 或更高版本。你可以从 [Python 官方网站 ](https://www.python.org/downloads/?spm=5176.28103460.0.0.40f75d27PnqPkU)下载并安装。
16
+ **2.克隆项目:**
17
+ 使用 Git 克隆项目到你的本地机器。
18
+
19
+ ```
20
+ git clone https://code.iflytek.com/ZNQC_AUTO_AI/python_scripts.git
21
+ cd python_scripts
22
+ git checkout WS_API_TEST
23
+ ```
24
+
25
+ **3.安装项目依赖:**
26
+ 使用 pip 安装项目所需的依赖库。
27
+
28
+ ```
29
+ pip install -r requirements.txt
30
+ ```
31
+ **4.运行项目:**
32
+ 你可以通过以下两种方式之一来运行项目:
33
+
34
+ * **使用命令行**:
35
+ 在命令行中运行以下命令:
36
+
37
+ ```
38
+ python run_tests.py --env uat --app 3d7d3ea4 --service gateway_5.4 --project vwa
39
+ ```
40
+
41
+ * **使用批处理脚本**:
42
+ 双击 run_tests.bat 文件来运行项目。
43
+
44
+ #### 项目结构
45
+ ├─allure_report
46
+ ├─allure_results
47
+ ├─build
48
+ ├─common
49
+ ├─config
50
+ ├─data
51
+ ├─dist
52
+ ├─logs
53
+ ├─testcase
54
+
55
+ * **文件说明**:
56
+ **allure_report**:存放 Allure 生成的 HTML 报告,用于展示测试结果。
57
+ **allure_results**:存放 Allure 生成的测试结果数据文件,如 result-12345.xml。
58
+ **build**:存放构建过程中生成的临时文件
59
+ **common**:存放通用的工具类
60
+ **config**:存放环境配置文件
61
+ **data**:存放测试数据文件
62
+ **dist**:存放最终发布的测试包
63
+ **logs**:存放运行日志文件
64
+ **testcase**:存放测试用例脚本
@@ -0,0 +1,72 @@
1
+ Metadata-Version: 2.1
2
+ Name: WebsocketTest
3
+ Version: 1.0.0
4
+ Summary: websocket api autotest
5
+ Author: chencheng
6
+ Requires-Python: >=3.7
7
+ Description-Content-Type: text/markdown
8
+
9
+ # WebSocket 接口自动化测试工具 (WS_API_TEST)
10
+
11
+ #### 介绍
12
+
13
+ 这是一个基于 WebSocket 协议的接口自动化测试工具。它可以用于自动化测试 WebSocket 接口,确保接口的稳定性和可靠性。
14
+
15
+ #### 系统要求
16
+
17
+ **Python 3.10+**:确保你的系统上已经安装了 Python 3.10(推荐使用最新稳定版)。
18
+ **项目依赖**:项目需要一些第三方库,可以通过 requirements.txt 文件安装。
19
+
20
+ #### 安装步骤
21
+
22
+ **1.安装 Python:**
23
+ 确保你的系统上已经安装了 Python 3.10 或更高版本。你可以从 [Python 官方网站 ](https://www.python.org/downloads/?spm=5176.28103460.0.0.40f75d27PnqPkU)下载并安装。
24
+ **2.克隆项目:**
25
+ 使用 Git 克隆项目到你的本地机器。
26
+
27
+ ```
28
+ git clone https://code.iflytek.com/ZNQC_AUTO_AI/python_scripts.git
29
+ cd python_scripts
30
+ git checkout WS_API_TEST
31
+ ```
32
+
33
+ **3.安装项目依赖:**
34
+ 使用 pip 安装项目所需的依赖库。
35
+
36
+ ```
37
+ pip install -r requirements.txt
38
+ ```
39
+ **4.运行项目:**
40
+ 你可以通过以下两种方式之一来运行项目:
41
+
42
+ * **使用命令行**:
43
+ 在命令行中运行以下命令:
44
+
45
+ ```
46
+ python run_tests.py --env uat --app 3d7d3ea4 --service gateway_5.4 --project vwa
47
+ ```
48
+
49
+ * **使用批处理脚本**:
50
+ 双击 run_tests.bat 文件来运行项目。
51
+
52
+ #### 项目结构
53
+ ├─allure_report
54
+ ├─allure_results
55
+ ├─build
56
+ ├─common
57
+ ├─config
58
+ ├─data
59
+ ├─dist
60
+ ├─logs
61
+ ├─testcase
62
+
63
+ * **文件说明**:
64
+ **allure_report**:存放 Allure 生成的 HTML 报告,用于展示测试结果。
65
+ **allure_results**:存放 Allure 生成的测试结果数据文件,如 result-12345.xml。
66
+ **build**:存放构建过程中生成的临时文件
67
+ **common**:存放通用的工具类
68
+ **config**:存放环境配置文件
69
+ **data**:存放测试数据文件
70
+ **dist**:存放最终发布的测试包
71
+ **logs**:存放运行日志文件
72
+ **testcase**:存放测试用例脚本
@@ -0,0 +1,21 @@
1
+ README.md
2
+ setup.cfg
3
+ setup.py
4
+ WebsocketTest.egg-info/PKG-INFO
5
+ WebsocketTest.egg-info/SOURCES.txt
6
+ WebsocketTest.egg-info/dependency_links.txt
7
+ WebsocketTest.egg-info/entry_points.txt
8
+ WebsocketTest.egg-info/requires.txt
9
+ WebsocketTest.egg-info/top_level.txt
10
+ caseScript/Aqua.py
11
+ caseScript/Gateway.py
12
+ caseScript/__init__.py
13
+ common/Assertion.py
14
+ common/WSBaseApi.py
15
+ common/WebSocketApi.py
16
+ common/__init__.py
17
+ common/assertUtils.py
18
+ common/logger.py
19
+ common/utils.py
20
+ testcase/__init__.py
21
+ testcase/test_all.py
@@ -0,0 +1,6 @@
1
+ [console_scripts]
2
+ har2case = pastor.cli:main_har2case_alias
3
+ locusts = pastor.ext.locust:main_locusts
4
+ pastor = pastor.cli:main
5
+ pmake = pastor.cli:main_make_alias
6
+ prun = pastor.cli:main_prun_alias
@@ -0,0 +1,6 @@
1
+ allure_python_commons==2.13.5
2
+ numpy==2.2.4
3
+ pandas==2.2.3
4
+ pytest==8.2.2
5
+ PyYAML==6.0.2
6
+ websockets==12.0
@@ -0,0 +1,3 @@
1
+ caseScript
2
+ common
3
+ testcase
@@ -0,0 +1,165 @@
1
+
2
+ from common.utils import *
3
+ from urllib.parse import quote_plus
4
+ from common import WSBaseApi
5
+ from common.WSBaseApi import WSBaseApi
6
+
7
+
8
+
9
+
10
+ class ApiTestRunner(WSBaseApi):
11
+ def __init__(self, **kwargs):
12
+ super().__init__(**kwargs)
13
+ self.answer_text = ""
14
+ def build_params(self):
15
+ """准备请求参数"""
16
+ return {
17
+ "header": {
18
+ "appid": self.appId,
19
+ "scene": self.scene,
20
+ "sid": self.sid or generate_random_string(), # 奥迪sid为空时,不会自生成
21
+ "uid": self.uid,
22
+ "usrid": ""
23
+ },
24
+ "parameter": {
25
+ "custom": {
26
+ "custom_data": {
27
+ "SessionParams": {
28
+ "isLog": "true",
29
+ "app_id": "",
30
+ "attachparams": {
31
+ "iat_params": {
32
+ "compress": "raw",
33
+ "da": "0",
34
+ "domain": "aiui-automotiveknife",
35
+ "dwa": "wpgs",
36
+ "encoding": "utf8",
37
+ "eos": "600",
38
+ "format": "json",
39
+ "isFar": "0",
40
+ "opt": "2",
41
+ "ufsa": "1",
42
+ "vgap": "200",
43
+ "accent": self.accent,
44
+ "language": self.language
45
+ },
46
+ "nlp_params": {
47
+ "llmEnv": "test",
48
+ "ovs_cluster":"AUDI",
49
+ "city": "合肥",
50
+ "compress": "raw",
51
+ "encoding": "utf8",
52
+ "format": "json",
53
+ "devid": "",
54
+ "news": {
55
+ "pageNo": 1,
56
+ "pageSize": 20
57
+ },
58
+ "flight": {
59
+ "pageNo": 1,
60
+ "pageSize": 20
61
+ },
62
+ "ovs_version": {
63
+ "weather": "3.5"
64
+ },
65
+ "user_defined_params": {},
66
+ "weather_airquality": "true",
67
+ "mapU": {
68
+ "pageNo": 1,
69
+ "pageSize": 20
70
+ },
71
+ "deviceId": self.deviceId,
72
+ "userId": self.userId,
73
+ "asp_did": self.asp_did,
74
+ "vWtoken": self.token,
75
+ "car_identity": self.car_identity,
76
+ "theme": "standard",
77
+ "vin": self.vin,
78
+ "interactive_mode": "fullDuplex",
79
+ "did": self.did,
80
+ "smarthome": {
81
+ "jd": {
82
+ "newSession": "true",
83
+ "sessionId": "123456789",
84
+ "userId": "9adbd42d-618f-4752-ad6d-9cb382079e25"
85
+ }
86
+ },
87
+ "train": {
88
+ "pageNo": 1,
89
+ "pageSize": 20
90
+ }
91
+ },
92
+ "tts_params": {
93
+ "bit_depth": "16",
94
+ "channels": "1",
95
+ "encoding": "speex-wb",
96
+ "frame_size": "0",
97
+ "sample_rate": "16000"
98
+ }
99
+ },
100
+ "aue": "speex-wb",
101
+ "bit_depth": "16",
102
+ "channels": "1",
103
+ "city_pd": "",
104
+ "client_ip": "112.132.223.243",
105
+ "dtype": "text",
106
+ "frame_size": "0",
107
+ "msc.lat": "31.837463",
108
+ "msc.lng": "117.17",
109
+ "pers_param": self.pers_param,
110
+ "sample_rate": "16000",
111
+ "scene": self.scene,
112
+ "stmid": "0",
113
+ "uid": self.uid,
114
+ "debug": self.debug,
115
+ "debugx": self.debugx,
116
+ "category": self.category
117
+ },
118
+ "UserParams": encode_base64(self.UserParams),
119
+ "UserData": quote_plus(self.UserData)
120
+ }
121
+ }
122
+ },
123
+ "payload": {
124
+ "text": {
125
+ "compress": "raw",
126
+ "encoding": "utf8",
127
+ "format": "plain",
128
+ "plainText": self.plainText,
129
+ "status": 3
130
+ }
131
+ }
132
+ }
133
+ async def handle_v1_chain(self, ws):
134
+ """
135
+ 处理5.0链路逻辑:
136
+ - 根据接收到的消息执行不同的操作
137
+ - 当'action'为'started'时,读取文件并发送数据块
138
+ - 发送结束标识
139
+ - 当'action'为'result'且'sub'为'stream_tpp'时,返回内容
140
+ """
141
+ while True:
142
+ _msg = await ws.recv()
143
+ # print(_msg)
144
+ try:
145
+ msg = json.loads(_msg)
146
+ code = safe_get(msg, ["header","code"])
147
+ if code != 0:
148
+ logging.error(f'请求错误: {code}, {msg}')
149
+ break
150
+ else:
151
+ answer = safe_get(msg, ["payload","results","text","intent","answer"])
152
+ answerText = safe_get(answer, ["text"])
153
+ if answerText:
154
+ self.answer_text += answerText
155
+ if msg['header']['status']=="2" or msg['header']['status']=="3": # 返回结果接收完成
156
+ if self.answer_text:
157
+ answer["text"] = self.answer_text
158
+ self.response = msg
159
+ return
160
+
161
+ except Exception as e:
162
+ logging.error(f"error in handle_v1_chain :{e}")
163
+ break
164
+
165
+
@@ -0,0 +1,264 @@
1
+
2
+ from wsgiref.handlers import format_date_time
3
+ import asyncio
4
+ from time import mktime
5
+ import hashlib
6
+ import hmac,time
7
+ from urllib.parse import urlencode, urlparse
8
+ import uuid
9
+ from common.utils import *
10
+ from common.WSBaseApi import WSBaseApi
11
+ from pathlib import Path
12
+
13
+ class ApiTestRunner(WSBaseApi):
14
+ def __init__(self, **kwargs):
15
+ super().__init__(**kwargs)
16
+ self.text_path = Path.cwd().resolve().joinpath("data/audio",f"{self.text}.pcm")
17
+ def generate_v2_auth_headers(self):
18
+ """为v2 5.4链路生成授权头"""
19
+ url_host = urlparse(self.url).netloc
20
+ date = format_date_time(mktime(datetime.now().timetuple()))
21
+ authorization_headers = f"host: {url_host}\ndate: {date}\nGET /v2/autoCar HTTP/1.1"
22
+ signature_sha = hmac.new(self.apiSecret.encode('utf-8'), authorization_headers.encode('utf-8'),
23
+ digestmod=hashlib.sha256).digest()
24
+ authorization_signature = encode_base64(signature_sha,input_encoding='bytes')
25
+ authorization = f'api_key="{self.apiKey}", algorithm="hmac-sha256", headers="host date request-line", signature="{authorization_signature}"'
26
+ return {
27
+ "host": url_host,
28
+ "date": date,
29
+ "authorization": encode_base64(authorization),
30
+ "appid": self.appId
31
+ }
32
+ def generate_v1_auth_headers(self):
33
+
34
+ """为5.0链路生成参数"""
35
+ param_iat = self.build_params()
36
+ cur_time = int(time.time())
37
+ param = json.dumps(param_iat, ensure_ascii=False)
38
+ param_base64 = encode_base64(param)
39
+ check_sum_pre = self.apiKey + str(cur_time) + param_base64
40
+ checksum = hashlib.md5(check_sum_pre.encode("utf-8")).hexdigest()
41
+ return {
42
+ "appid": self.appId,
43
+ "checksum": checksum,
44
+ "param": param_base64,
45
+ "curtime": str(cur_time),
46
+ "signtype": "md5"
47
+ }
48
+ def assemble_ws_auth_url(self, chain=None):
49
+ if chain:
50
+ # v2 5.4链路
51
+ params = self.generate_v2_auth_headers()
52
+ else:
53
+ # 默认5.0链路
54
+ params = self.generate_v1_auth_headers()
55
+
56
+ return f"{self.url}?{urlencode(params)}"
57
+ # @exception_decorator
58
+ async def handle_v2_chain(self, ws):
59
+ """
60
+ 处理v2 5.4链路逻辑:
61
+ - 接收消息并解析
62
+ - 检查返回码是否为0(成功)
63
+ - 如果状态为1,则解码并返回特定的文本内容
64
+ - 如果状态为2,则结束循环
65
+ """
66
+ while True:
67
+ try:
68
+ msg = await ws.recv()
69
+ # print(msg)
70
+ response_data = json.loads(msg)
71
+ # code 返回码,0表示成功,其它表示异常
72
+ if response_data["header"]["code"] == 0:
73
+ # status 整个结果的状态,0-会话起始结果,1-中间结果,2-最终结果
74
+ if "status" in response_data["header"]:
75
+ status = response_data["header"]["status"]
76
+ if status == 1 and "cbm_semantic" in response_data["payload"]:
77
+ semantic_bs64 = response_data["payload"]["cbm_semantic"]["text"]
78
+ semantic_str = base64.b64decode(semantic_bs64.encode('utf-8')).decode('utf-8')
79
+ self.response = json.loads(semantic_str)
80
+ return
81
+ elif status == 2:
82
+ break
83
+ else:
84
+ logging.error(f"返回结果错误:{response_data['header']['message']}")
85
+ break
86
+ except Exception as e:
87
+ logging.error(f"Error in processing message: {e}")
88
+ break
89
+ # @exception_decorator
90
+ async def handle_v1_chain(self, ws):
91
+ """
92
+ 处理5.0链路逻辑:
93
+ - 根据接收到的消息执行不同的操作
94
+ - 当'action'为'started'时,读取文件并发送数据块
95
+ - 发送结束标识
96
+ - 当'action'为'result'且'sub'为'stream_tpp'时,返回内容
97
+ """
98
+
99
+ while True:
100
+ _msg = await ws.recv()
101
+ # print(_msg)
102
+ try:
103
+ msg = json.loads(_msg)
104
+ if msg['action'] == "started":
105
+ with open(self.text_path, 'rb') as file:
106
+ for chunk in iter(lambda: file.read(1280), b''):
107
+ await ws.send(chunk)
108
+ await asyncio.sleep(0.04) # 使用asyncio.sleep避免阻塞事件循环
109
+ await ws.send("--end--".encode("utf-8"))
110
+ elif msg['action'] == "result":
111
+ data = msg['data']
112
+ if data.get('sub') == "stream_tpp" or data.get('sub') == "tpp":
113
+ self.response = json.loads(data['content'])
114
+ return
115
+ except Exception as e:
116
+ logging.error(f"error in handle_v1_chain :{e}")
117
+ break
118
+
119
+ def build_params(self,chain=None):
120
+ if chain: #5.4链路参数
121
+ _textParams = {
122
+ "sparkEnv": self.sparkEnv,
123
+ "userId": self.userId,
124
+ "user_data": "",
125
+ "attachparams": str({"nlp_params": {"vWtoken": self.token, "aiui45_intv_mode": 2, "aqua_route": "vwa"}}), # 不能传递字典,需要传str
126
+ "scene": self.scene,
127
+ "debugx": "true",
128
+ "debug": "true"
129
+ }
130
+ # # 序列化 textParams
131
+ textParams = json.dumps(_textParams, ensure_ascii=False)
132
+ def get_audio():
133
+ with open(self.text_path, "rb") as file:
134
+ content = file.read()
135
+ return encode_base64(content,input_encoding='bytes')
136
+
137
+
138
+ return {
139
+ "header": {
140
+ "app_id": self.appId,
141
+ "uid": "efeafe5e-82d6-4922-9770-f7aaabf97548",
142
+ "stmid": "sid1111",
143
+ "status": 3,
144
+ "scene": self.scene
145
+ },
146
+ "parameter": {
147
+ "nlp": {
148
+ "sub_scene": "cbm_v47",
149
+ "new_session": False,
150
+ "nlp": {
151
+ "encoding": "utf8",
152
+ "compress": "raw",
153
+ "format": "json"
154
+ }
155
+ }
156
+ },
157
+ "payload": {
158
+ "cbm_semantic": {
159
+ "compress": "raw",
160
+ "format": "plain",
161
+ "text": encode_base64(textParams),
162
+ "encoding": "utf8",
163
+ "status": 3
164
+ },
165
+ "audio": {
166
+ "audio": get_audio(),
167
+ "status": 2,
168
+ "encoding": "raw",
169
+ "sample_rate": 16000,
170
+ "channels": 1,
171
+ "bit_depth": 16,
172
+ "frame_size": 0
173
+ }
174
+ }
175
+ }
176
+ else: #5.0链路参数
177
+ def get_auth_id():
178
+ """
179
+ 生成基于系统MAC地址的唯一身份验证ID。
180
+
181
+ 返回:
182
+ str: 唯一的身份验证ID。
183
+ """
184
+ # 获取系统MAC地址的整数表示,并转换为12位的十六进制字符串
185
+ mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
186
+
187
+ # 将MAC地址按照标准格式(使用冒号分隔)重新组合
188
+ formatted_mac = ":".join([mac[e:e + 2] for e in range(0, 11, 2)])
189
+
190
+ # 对格式化后的MAC地址进行MD5哈希处理,并返回其十六进制表示
191
+ auth_id = hashlib.md5(formatted_mac.encode("utf-8")).hexdigest()
192
+ return auth_id
193
+ trs_params = {}
194
+ iat_params = {
195
+ "accent": "mandarin",
196
+ "language": self.language,
197
+ "domain": "aiui-automotiveknife",
198
+ "eos": "600",
199
+ "evl": "0",
200
+ "isFar": "0",
201
+ "svl": "50",
202
+ "vgap": "400"
203
+ }
204
+
205
+ nlp_params = {
206
+ "devid": "LG8-LGA26.08.2420010196",
207
+ "city": "合肥市",
208
+ "user_defined_params": {},
209
+ "weather_airquality": "true",
210
+ "deviceId": "LG8-LGA26.08.2420010196",
211
+ "userId": "69b85a13-1434-408b-872f-1632c587dbc4",
212
+ "asp_did": "LG8-LGA26.08.2420010196",
213
+ "vWtoken": self.token,
214
+ "car_identity": "MP24",
215
+ "theme": "standard",
216
+ "vin": "HVWJA1ER5R1203864",
217
+ "interactive_mode": "fullDuplex",
218
+ "did": "VW_HU_ICAS3_LG8-LGA26.08.2420010196_v2.0.1_v0.0.1"
219
+ }
220
+ attach_params = {
221
+ "trs_params": json.dumps(trs_params, ensure_ascii=False),
222
+ "iat_params": json.dumps(iat_params, ensure_ascii=False),
223
+ "nlp_params": json.dumps(nlp_params, ensure_ascii=False)
224
+ }
225
+ return {
226
+ "auth_id": get_auth_id(),
227
+ "ver_type": "websocket",
228
+ "data_type": "audio",
229
+ "scene": "main",
230
+ "lat": "31.704187",
231
+ "lng": "117.239833",
232
+ "attach_params": json.dumps(attach_params, ensure_ascii=False),
233
+ "userparams": "eyJjbGVhbl9oaXN0b3J5Ijoib2ZmIiwic2tpcCI6Im5vdF9za2lwIn0=",
234
+ "interact_mode": "continuous",
235
+ "text_query": "tpp",
236
+ "sample_rate": "16000",
237
+ "aue": "raw",
238
+ "speex_size": "60",
239
+ "dwa": "wpgs",
240
+ "result_level": "complete",
241
+ "debugx": "True",
242
+ "debug": "true",
243
+ "close_delay": "100"
244
+ }
245
+
246
+ @exception_decorator
247
+ def run(self):
248
+ extra_headers = {'Authorization': self.token}
249
+ # 使用split函数分割URL,并找到包含"v2"的部分
250
+ parts = self.url.split('/')
251
+ # "v2"正好位于倒数第二个位置, v2走5.4链路,v1走5.0链路
252
+ version = "v2" if len(parts) > 2 and parts[-2] == 'v2' else None
253
+ # 根据版本选择正确的assemble_ws_auth_url方法参数
254
+ self.url = self.assemble_ws_auth_url(version)
255
+ # 构建frame,对于v2版本添加额外参数
256
+ if version:
257
+ self.request = self.build_params(version)
258
+ # WebSocket连接与消息发送
259
+ asyncio.run(self.WebSocketApi(
260
+ extra_headers,
261
+ version
262
+ ))
263
+
264
+