之前公众号有人关注之后会发送一些指令查询 PyTips,今天抽时间实现了一下微信公众号自动回复的功能。
Tornado + Motor + MongoDB
这次没有采用熟悉的 Flask
框架,而是选择了 Tornado + Motor + MongoDB
,一方面是出于对异步框架 tornado
的好奇,另外一个原因是 tornado
稳定支持 Python 3.5 async/await
形式的协程,我想要试一下用起来是什么感觉。
安装虚拟环境
老习惯用 venv
安装新的环境:
1 |
python3 -m venv ./venv3 |
服务器端遇到两个坑,一是开始用 python3
我以为是 3.5 ,但结果服务器版本是 python3.4
,只好重新安装 python3.5:
1 2 3 4 5 6 7 8 |
wget https://www.python.org/ftp/python/3.5.1/Python-3.5.1.tar.xz tar xfvJ Python-3.5.1.tar.xz cd Python-3.5.1 ./configure --prefix=/opt/python3.5 make sudo make install sudo ln -s /opt/python3.5/bin/python3.5 /usr/bin/python3.5 |
另外安装 motor
的时候出现错误 Python.h
找不到,运行完
1 |
sudo apt-get install python-dev |
还是一样,想了半天才想起来应该安装的是 python3-dev
。这些坑,应该是阻止 Python 3.5 推广的一大因素,毕竟服务器一般自带 2.7,好一点的有 3.x 也是 3.4,而不同版本之间的冲突、升级都非常不友好。
虚拟环境创建完成之后:
1 2 |
source venv3/bin/active pip install tornado motor requests |
安装&运行 mongodb
:
1 2 |
sudo apt-get install mongodb mongod --dbpath=./db --bind_ip=127.0.0.1 |
异步
Tornado + Motor 的异步,刚刚开始用起来感觉比较别扭:
1 2 3 4 5 6 7 8 9 10 |
class MainHandler(RequestHandler): async def post(self): db = self.settings['db'] data = await db.get_media(WxMessage(self.request.body)) class Database(): def __init__(self): self._client = motor.motor_tornado.MotorClient() self._db = self._client[DB] async def get_media(self, msg): return await self._db.medias.find_one({"title": {"$regex": msg}}) |