文章目录
Flask简介
Python 生态最简单的Web开发工具,一天就能入门。与Python生态最知名的Web开发框架 Django 相比,Flask显得特别的轻、小、简单,及其适合小而美的功能Web的开发。
Flask 被设计为可扩展的模式,定位是一个微服务框架,因为很多表单验证、登录登出等功能都没有提供现有的功能模块。
学习资料
基本概念
- 一个 Web 程序就是一个 Flask 类的对象,WSGI 网关将客户端的请求转交给 Flask 对象处理;
- 程序实例需要知道每个 URL 对应哪些后台代码,而路由 route 能处理这种映射关系;
- Flask 实现路由的函数有两种:app.route 修饰器;app.add_url_rule() 的非修饰器形式;
- 同一个 URL 存在多个请求方法,例如 Get、Post、HEAD 等,Flask 对每个路由都指定了请求方法,从而使得用不同的视图函数去处理;
- 程序上下文,current_app 、 g;
- 请求上下文,request 、 session;
- 请求钩子,用于复用通用的函数;
- 模板,是包含变量的 html 文本文件;
- 给模板的变量赋值,返回得到最终的字符串 html,并在客户端展示的过程,称之为渲染 render。这一过程在 Flask 中由 Jinja2 模块完成;
- route() 函数中的参数要以 / 结尾,例如
route('/flask/')
,而不能写route('/flask')
,后者容易报错;
部署环境配置
安装 Python3
Linux 自带了 python2,而且很多系统功能都是基于 python2 开发的;但实际上 Python 项目基本用的都是 py3,所以需要再安装一个 py3,并且不能删除原来的 py2。下面是 Python-3.7.9 的安装方法
0. 切换到root角色: sudo su
1、安装编译环境: yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel libffi-devel gcc
2、载 Python 安装包: wget https://www.python.org/ftp/python/3.7.9/Python-3.7.9.tar.xz
3、解压缩: tar -xvJf Python-3.7.9.tar.xz
4、生成编译脚本在指定目录下: ./configure --prefix=/root/Python-3.7.9
5、编译: make
6、编译安装: make install
7、检查 Python3 是否安装成功: /root/Python-3.7.9/bin/python3
8、建立Python3的软链接: ln -s /root/Python-3.7.9/bin/python3 /usr/bin/python3
9、建立pip3 的软链接:ln -s /root/Python-3.7.9/bin/pip3 /usr/bin/pip3
10、加入环境变量,编辑 /etc/profile 文件: export PATH="/root/Python-3.7.9/bin:$PATH"
11、变量生效:source /etc/profile
12、用root权限安装的软件,切换个人账号时候无法使用,需要在根目录下执行 `chmod 777 /root`,对/root/文件夹赋权即可;
在Linux中配置Python3的虚拟环境
虚拟环境可以避免多项目情况下、包的版本冲突。虚拟环境的配置过程如下:
1. 安装虚拟环境的包 pip3 install virtualenv
2. 创建软链接 ln -s /root/Python-3.7.9/bin/virtualenv /usr/bin/virtualenv
3. 创建虚拟环境 virtualenv --python=/root/Python-3.7.9/bin/python3 ENV
4. 进入虚拟环境所在的目录 cd ENV
5. 启用虚拟环境 source ./bin/activate
6. 安装虚拟环境内所需的python模块,例如 pip flask
7. 退出虚拟环境 deactivate
ENV文件夹要作为Python项目的一个子文件夹存在,程序才可以运行。即:flask的app.py文件,要和ENV文件夹在同一目录下。
配置Git
安装git yum install git
剩下的操作就是通过命令行的方式即可
安装第三方包
有人会问,第三方包的安装有什么好写的?一个一个去安装就行了。这么说好像也没错,但是在实际部署项目的过程中,一个 Python 工程可能会用到几十上百个包,一个一个的安装的话,会相当耗费时间。利用 freeze 包可以实现快速实现依赖包的批量安装。
pip freeze > requirements.txt # 在开发环境中,导出安装模块的信息到文档中
# 在部署环境中,安装该文档里的模块
pip install -r requirements.txt -i https://pypi.douban.com/simple/ --trusted-host pypi.douban.com
开始部署
将服务部署在服务器时,往往选择0.0.0.0 这个地址,它表示网络当中的本机。例如,当你的PC有内网地址和外网地址时,设置为0.0.0.0,那么通过内网地址或外网地址都可以访问我的应用。同时,0.0.0.0还是一个动态IP,部署之后会被外网IP替换。监听在127.0.0.1,只有本机客户端可以访问,其他服务器无法访问。
127.0.0.1是回环地址,localhost则是域名。保留IP。事实上整个 127.* 网段都算能够使用,比如你 ping 127.0.0.2 也是通的。 但是使用127.0.0.1作为默认地址只是一个惯例。如果监听在0.0.0.0上,如果没有端口限制,那么其他服务器则可以连接该服务器的该端口。它表示无效的IPv4地址,因此 ping 0.0.0.0 是无效的。
部署方式一:直接启动
- 第一步、在 Linux 下克隆项目
git clone <git_url>
- 第二步、在该项目目录中,创建虚拟环境所在的目录
virtualenv --python=/root/Python-3.7.9/bin/python3 ENV
- 第三步、进入虚拟环境目录
cd ENV
- 第四步、启用虚拟环境
source ./bin/activate
- 第五步、修改 Flask 主程序的端口为 localhost
app.run(host='localhost', port='8000')
。如果只要求本机访问,host写 localhost;如果要求外网也能通过IP访问,则host写 0.0.0.0 - 第五步、在主程序 app.py 的同级目录下,直接以开发模式启动Flask程序,即完成部署
- 前台启动:python3 /root/app.py
- 后台启动:nohup python3 /root/app.py &
部署方式二:gunicorn
是一个 UNIX 下的 WSGI HTTP 服务器。通过这种方式部署的话,就不用先运行项目代码了。
本质上,程序在 ENV 甚至本机环境中run起来,外网访问该 IP就可以了。但这样存在一些安全和性能的风险,才需要引入服务器软件。gunicorn 采用 gunicorn 做 wsgi容器,用来部署 python。Python 程序的 app 指定端口为 localhost
gunicorn -b 0.0.0.0:8000 test:app
# test.py 文件要放在 ENV 目录中,指定域名和端口。0.0.0.0 要换成服务器电脑的IP
gunicorn -b localhost:8000 -w 4 to_do_list:app
test.py 文件要放在 ENV 目录中,指定域名和端口。0.0.0.0 要换成服务器电脑的IP
其中,-b 后的参数是gunicorn监听的端口, -w是指worker的数量, 最后的参数是app的位置。运行上述命令后,gunicorn运行在私有端口8000处,gunicorn要配合nginx使用,让nginx把这个私有端口(private port)暴露给外部
Flask的app.py文件内,main函数内部写app.run(host='localhost', port='8080')
,然后进入EVN,输入 nohup gunicorn -w 1 -b <服务器IP>:8080 app:app &
即可启动
部署方式三:Nginx
不用 nginx 也可以实现 Flask 的部署,只是性能和安全性差一些。
安装方式: https://www.runoob.com/linux/nginx-install-setup.html
安装完全参考 runoob 的教程即可,很简单
安装后发现文件夹里有两个 nginx.conf 文件,网上解释也不是很清楚
/root/nginx-1.6.2/nginx.conf # 这个好像是worker进程对应的配置
/root/nginx-1.6.2/conf/nginx.conf # 这个好像是master进程对应的配置
/root/nginx-1.6.2/nginx.conf.default # 这个保持暂时不动
日志文件
/root/nginx-1.6.2/logs/error.log # 查看错误日志s
ps aux | grep nginx # 查看nginx的后台进程
nginx # 启动
nginx -c # 执行配置文件来启动
nginx -s reload # 重启
nginx -s stop # 停止
读取的原始默认静态文件路径是 /root/nginx-1.6.2/html/index.html
server {
listen 80; # 开放端口
server_name localhost; # 默认本地ip
location / {
root /root;
index test.html;
}
location /a { # 第二个访问url对应的静态文件
alias /root;
index test.html;
}
}
部署方式四:WSGI
uWSGI 和 gunicorn 都是实现 WSGI 的服务器,选择其中一种就行了。
uWSGI 一个用 C 写的快速应用服务器。它配置丰富,从而配置复杂度也大于 gunicorn 。这个暂时我还没有实现
uwsgi --socket 0.0.0.0:8000 --protocol=http -w wsgi
uwsgi --ini xxx.ini # 启动
uwsgi --reload xxx.pid # 重启
uwsgi --stop xxx.pid # 停止
post的发送与解析方式
基于Flask发送post、与接收post的参数,有多种方式,容易混淆。这里进行一波总结。
# 如果发送的是json格式数据
from flask import request
import json
import requests
@app.route('/data/send/', methods=['GET', 'POST'])
def send():
message = {'id': 1} # dict类型
headers = {'Content-Type': 'application/json'} # 以json形式发送数据
message_json = json.dumps(message) # 将dict对象转化为json
url = 'http://www.baidu.com/data/receive/' # post接口..需要更换为正式的接口url
info = requests.post(url=url, data=message_json, headers=headers)
print(info.text) # 打印返回的结果
return 'ok'
@app.route('/data/receive/', methods=['POST'])
def receive():
json_data = json.loads(request.data) # 将json转化成dict对象
receive_data = json_data['id']
print(receive_data)
return 'ok'
# 如果发送的是表单形式数据
from flask import request
import requests
@app.route('/data/send/', methods=['GET', 'POST'])
def send():
message = {'id': 1} # dict类型
headers = {'Content-Type': 'application/x-www-form-urlencoded'} # 以表单形式发送数据,无需序列化为json
url = 'http://www.baidu.com/' # post接口..需要更换为正式的接口url
info = requests.post(url=url, data=message, headers=headers)
print(info.text) # 打印返回的结果
return 'ok'
@app.route('/data/receive/', methods=['POST'])
def receive():
reveive_data = request.values.get("id")
print(receive_data)
return 'ok'