Python2.7转Python3后Splunk调用Ansible接口报POST数据类型错误
问题原因
- 基础语法错误:自动转换后的代码存在模块引用混用问题,Python3已将Python2的
urllib2模块拆分为urllib.request/urllib.error/urllib.parse三个模块,代码中残留的urllib2.Request调用在无兼容包的纯净Python3环境(比如Splunk内置Python环境)会直接报错。 - 核心报错根源:你业务逻辑中构造Request对象时传入了
extra_vars对应的JSON字符串作为POST数据,Python3的urllib规范要求POST请求的data参数必须为字节类型,不能直接传字符串,因此触发类型错误。 - 命令行测试正常的原因:你贴的简化测试代码没有传入
data参数,urllib默认发送GET请求,不会校验POST数据格式,因此可以正常执行。
修复步骤
- 修正所有模块引用错误,将代码中
urllib2.开头的调用全部替换为urllib.request. - 构造POST请求时,将字符串类型的请求体编码为UTF-8格式的字节类型
- (可选优化)将已弃用的
base64.encodestring替换为base64.b64encode,同时添加Content-Type请求头声明数据格式,避免服务端无法解析请求
完整修复后代码示例
import sys, urllib.request, urllib.error, urllib.parse, json, tower_cli, os, datetime, base64 def tower_launch(hostname, username, password, job_id, extra_vars): url = f'http://{hostname}/api/v2/job_templates/{job_id}/launch/' req = urllib.request.Request(url=url) # 处理身份认证 auth_str = f'{username}:{password}' base64string = base64.b64encode(auth_str.encode()).decode().strip() req.add_header("Authorization", f"Basic {base64string}") req.add_header("Content-Type", "application/json") # 核心修复:将JSON字符串编码为字节类型 if extra_vars: req.data = json.dumps(extra_vars).encode('utf-8') response = urllib.request.urlopen(req) print(f"Response code was: {response.getcode()}")
内容的提问来源于stack exchange,提问作者chetan
相关产品推荐
相关产品推荐

