Skip to content

从前端技术学习python(一)

发布日期:2023-08-07

从前端开发者的角度,学习 python 服务器开发,主要用于树莓派局域网服务


学习背景

最近在使用树莓派搭建 python 服务,实现对树莓派的网络控制。其中需要用到很多 python 的库,是 nodejs 没有提供的,因此最好的方式是使用 python 搭建 web 服务来调用这些库,包括 picamera、gpiozero 等。

pip - python 的包管理器

node 有 npm,python 有 pip,他们都是包管理器。不同的是,pip 默认全局安装,不存在局部安装的选择。全局安装有一个很麻烦的问题,假如我有两个项目依赖两个不同版本的 jinja2,就会有依赖冲突。

为了解决 pip 依赖冲突问题,就不能什么都全局安装,于是有了 venv 虚拟环境,早期的 python 开发需要手动创建虚拟环境。虽然操作起来有点麻烦,但确实解决了依赖冲突的问题。

(手动创建虚拟环境)[https://www.liaoxuefeng.com/wiki/1016959663602400/1019273143120480]

pipenv 虚拟环境管理器

pipenv 是 python 官方推荐的虚拟环境管理器,可以自动创建虚拟环境,用起来更像 npm,pip install 的行为就是全局安装,而 pipenv install 则会自动创建虚拟环境,把依赖装在虚拟环境中。

在 mac 下,pipenv 的默认在 ~/.local/share/virtualenvs 下创建虚拟环境,并安装依赖,相当于 node_modules 目录。可以通过 pipenv --venv 命令查看虚拟环境安装的位置。

不习惯依赖被安装在项目外面?设置 export PIPENV_VENV_IN_PROJECT=1 这个环境变量(写到.zshrc中),pipenv 会在当前目录下创建 .venv 的目录,以后都会把模块装到这个目录下。这样一来,项目结构看起来就和 npm 前端项目非常相似了,找到了熟悉的感觉。

下面是一些命令和 npm 的对比

pipenv install // 相当于 npm install
pipenv run python3 app.py // 相当于 npm run xxx
pipenv run flask run // 启动 flask 服务

Pipenv & 虚拟环境

vscode 找不到虚拟环境?

在测试项目时,发现 vscode 找不到 flask 的定义,给不了我代码提示。原来是因为我的 vscode 工作目录不在虚拟环境目录中。比如我的 vscode 工作目录是 /learn_python,而我创建了 /learn_python/app 目录,并在里面执行了 pipenv install 创建虚拟目录,因此 vscode 就找不到环境了。可以在 vscode 右下角的 Select Interpreter 中选择环境。

关于 flask-socketio,在 flask 上使用 websocket

为了使用 websocket,使用这个包配合 flask 使用,通常会遇到一个报错,提示你需要安装一个 websocket 服务

The WebSocket transport is not available, you must install a WebSocket server

flask-socketio 的 issue 里面也有人提到了这个问题,作者给出的解决方法是安装 simple-websocket参见issue

深入探究这个问题,为什么这个包不提供 websocket 服务,而要用户自行安装呢?首先了解下项目的作者 miguelgrinberg,这个人是 socketio 的 python 实现 python-socketio 的作者,也是上述的两个包 flask-socketiosimple-websocket 的作者,确实是这个领域的大佬。

flask-socketio 实际上是对 python-socketio 的封装,上面说的那个报错信息,其实是在 python-socketio 项目里面,因此要深入了解怎样使用 flask-socketio,就要去看看 python-socketio 的文档,因为作者默认你了解这个包,只是提供一个 flask 可用的便利的封装。作为一窍不通直接安装 flask-socketio 的人来说,踩坑确实是必经之路了。

了解这些之后,就可以理解为什么 flask-socketio 不提供 websocket 服务了。因为 python-socketio 也不提供 websocket,而是根据不同的异步服务做相应的适配。python 本身并不是一个异步的语言,是多线程的,而 simple-websocket 就是为多线程的 python 服务准备的 websocket 服务器。下面这篇文章选自 python-socketio 文档,解释了其对不同异步服务做的适配。

python-socketio 关于部署策略的文档

ps:作为前端开发人员,一开始看到他的项目的 star 只有几百-5k,还以为这些项目不太能用,事实上他一直在维护这些项目。只是在 python 中使用 websocket 的人比较少,属于小众需求,因此不能以 star 作为衡量项目的标准,小众领域关注的人少 star 就少了,不代表项目质量。

WSGI 是什么,为什么在 node 中没有这个东西?

WSGI 是一种 python 特有的协议,规定了 server 和 application 应该怎样通讯,怎样实现。

server 专注于实现网络请求。接收 http 请求,将请求信息转发给 application 处理,并根据处理返回的内容,进行 http 响应。常见的gunicorn、uwsgi,是高性能的 server。

application 专注于实现业务。接收请求信息,并根据请求信息实现业务需求,返回响应信息。常见的 Flask、Django,就是 application 框架,虽然他们本身也提供了 server,但其性能往往没有专注于 server 的库来的高效。因此常规的做法是,在开发过程中使用自带的 server,而部署时则使用高效的 server 来部署。

WSGI 把 web 服务拆分成两个部分,有利于更好的解藕,同时也有历史原因。WSGI 出现的时候已经有很多 python server 和 application 解决方案,群魔乱舞,需要一个统一的接口规范。nodejs 出现的比较晚,没有出现这种拆分,因此每个框架都有自己的 server 解决方案。比如 koa 框架,本身就是 server + application,对于解析 get 请求不需要额外的依赖,但是本身并不提供 body 的解释工作,需要安装 koa-body 进行解析。

Python Web开发最难懂的WSGI协议,到底包含哪些内容?

Power by vitepress