Freeswitch拨号计划调用Python脚本连接Redis数据库报错求助
首先明确:完全可以在FreeSWITCH的Python脚本中调用第三方模块,你遇到的ImportError只是因为mod_python找不到redis模块的安装路径而已,下面一步步帮你解决:
一、定位问题根源
FreeSWITCH的mod_python使用的Python环境,和你平时在终端用的Python环境可能不是同一个(或者模块路径没同步)。先确认redis模块的安装位置:
在终端执行:
# 用pip还是pip3取决于你安装redis时用的版本 pip show redis # 或者 pip3 show redis
输出里的Location字段就是redis模块所在的路径,比如/usr/local/lib/python3.9/site-packages。
二、三种解决方案
1. 在Python脚本中手动添加模块路径
直接在test.py的最顶部添加路径,让Python能找到redis模块:
import sys # 替换成你刚才查到的Location路径 sys.path.append("/usr/local/lib/python3.9/site-packages") import redis # 后续你的Redis操作代码 r = redis.Redis(host='localhost', port=6379, db=0) # 比如查询key:r.get("your_key")
修改后在fs_cli里重新运行python test,应该就能成功导入了。
2. 给FreeSWITCH设置PYTHONPATH环境变量
如果不想每个脚本都加路径,可以修改FreeSWITCH的启动环境:
- 如果你用systemd管理FreeSWITCH,编辑
/etc/systemd/system/freeswitch.service,在[Service]段添加:
然后执行Environment="PYTHONPATH=/usr/local/lib/python3.9/site-packages:$PYTHONPATH"systemctl daemon-reload && systemctl restart freeswitch。 - 如果是用init脚本,找到
/etc/init.d/freeswitch,在启动命令前添加:
重启FreeSWITCH即可。export PYTHONPATH="/usr/local/lib/python3.9/site-packages:$PYTHONPATH"
3. 确保用mod_python对应的Python版本安装redis
先确认mod_python用的是哪个Python版本:
在fs_cli里执行:
python import sys; print(sys.version)
比如输出是Python2.7.x,那你就用pip2 install redis重新安装redis;如果是Python3.x,就用pip3 install redis,这样模块会直接安装到mod_python能识别的路径里。
三、更优的实现方案
如果你的需求只是在来电时查询Redis,其实可以不用Python脚本,FreeSWITCH自带的mod_redis就能直接在拨号计划里完成查询,更高效:
在拨号计划的XML里添加:
<!-- 把Redis中key为caller_info的值存入FreeSWITCH变量redis_result --> <action application="redis" data="get caller_info redis_result"/> <!-- 后续可以直接使用${redis_result}变量 --> <action application="log" data="INFO Redis查询结果:${redis_result}"/>
这种方式不需要额外的Python层,性能更好,配置也更简单。
如果必须用Python,除了导入模块,也可以用subprocess调用redis-cli命令来查询(适合临时快速验证):
import subprocess # 查询key为caller_info的值 result = subprocess.check_output(["redis-cli", "GET", "caller_info"]).decode('utf-8').strip()
注意事项
- 确保FreeSWITCH进程有访问Redis的权限:比如Redis的
bind地址不是仅本地(如果FreeSWITCH和Redis不在同一机器),或者设置了正确的密码。 - 检查mod_python的编译是否和目标Python版本匹配:如果编译mod_python时用的是Python2,就不要用Python3的模块。
内容的提问来源于stack exchange,提问作者Ricardo

