# flaskabc **Repository Path**: bigbug55/flaskabc ## Basic Information - **Project Name**: flaskabc - **Description**: 一个python Flask入门案例,主要提供返回hello和生成随机数的功能。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2024-03-26 - **Last Updated**: 2024-03-27 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README ### Flask与Nginx搭配构建后台API系统 > #### 作者:tfzhang 日期:2024-03-25 --- 本文主要介绍基于Flask与Nginx搭建一个简易的API系统,作为演示该系统只有一个后台API,接收来自前台的参数,然后返回生成的随机数。整个部署环境是**Ubuntu18.04**操作系统。 Flask是Python下一个轻量级Web应用框架,关键的优势在于: - 轻量级,简单够用; - 基于python,好上手; Nginx与Flask搭配使用的架构图基本如下: ![Nginx与Flask架构图](.\img\Nginx与Flask架构图.jpg) - Nginx作为网络服务器,接收来自用户的请求,并将请求反向代理到Gunicorn服务器; - Gunicorn是一个运行Python Web应用程序的WSGI(Web 服务器网关接口)HTTP服务器; - supervisor是一个进程管理工具,可以监控gunicorn的运行情况,如果意外关机,可以自动重启; - Flask App就是我们开发的应用服务; #### 1、Flask App的开发: 要开发Flask App,首先安装python环境: ##### 1.1 安装python虚拟环境 查看python3是否安装: ```bash python3 --version ``` 安装虚拟环境模块: ```bash sudo apt install python3-venv ``` 创建flask执行的虚拟环境: ```bash python3 -m venv myflask ``` 创建好后,进入myflask文件夹,运行如下命令激活虚拟环境: ```bash source ./bin/activate ``` 激活后,安装flask库: ```python pip3 install Flask ``` ##### 1.2 开发Flask App 类似C语言下的hello world,首页我们开发一个Flask下的hello world。完成1.1步骤,进入其中的 myflask目录; 创建如下名为app.py的python文件: ```python from flask import Flask app=Flask(__name__) @app.route('/') def index(): return '

Hello World! From Flask!

' ``` 编辑保存后,终端运行: ```bash flask run ``` ![2024-03-26-flaskrun启动](.\img\2024-03-26-flaskrun启动.jpg) 根据终端的提示,用浏览器打开http://127.0.0.1:5000/即可看到输出: ![2024-03-26-浏览器打开helloflask](.\img\2024-03-26-浏览器打开helloflask.jpg) 仔细观察终端的输出,可以发现当前的开发环境是:production,而当前的访问端口是5000。 那如何修改这些配置呢?比如将production环境切换为development环境,把端口从5000修改8000等,此时需要使用环境变量。我们在当前开发目录下,创建.flaskenv环境变量文件: ```bash FLASK_ENV=development ##设置为开发环境; FLASK_APP=app.py ##如果你app名为app,可以不显示注明;如果不是,一定要显示注明。 FLASK_RUN_PORT=8000 ``` 那么flask怎么去读这个.flaskenv环境变量文件呢?还需要再安装python-dotenv这个python库: ```bash pip3 install python-dotenv ``` 然后,再次运行flask run: ![2024-03-26-flaskenv环境变量](.\img\2024-03-26-flaskenv环境变量.jpg) 上图中可以发现已经处于开发模式,并且端口也切换到8000。 ##### 1.3 完善Flask App的返回随机数功能: 要返回随机数,来自客服端的关于随机数长度、字符数等请求信息,所以路由端的代码如下: ```python @app.route('/getrandomstr', methods=['POST']) def getrandomstr(): if request.method == 'POST': data_json=request.get_json() #print(data_json) ##get parameters,获取来自客户端的信息; intlen=data_json.get("intlen") intnum=data_json.get("intnum") withnum=data_json.get("withnum") withlow=data_json.get("withlow") withup=data_json.get("withup") withspecial=data_json.get("withspecial") ##请求的随机数长度过长,数量过多则返回fail; if intlen>30 or intnum >1000: return jsonify(data=[], datalen=0, msg="fail") strings=[] ##根据客户端信息调用生成随机数生成; strings=generate_random_string(intlen, intnum, withnum, withlow, withup, withspecial) datalen=len(strings) if datalen>0: return jsonify(data=strings, datalen=datalen, msg="success") else: return jsonify(data=[], datalen=0, msg="fail") ``` 上述路由代码中,核心的随机字符串生成函数generate_random_string: ```python def generate_random_string(length, num_strings, use_numbers, use_lower_case, use_upper_case, use_special_chars): # Create a list of characters to choose from chars = [] if use_numbers: chars += [str(i) for i in range(10)] if use_lower_case: chars += [chr(i) for i in range(97, 123)] if use_upper_case: chars += [chr(i) for i in range(65, 91)] if use_special_chars: chars += ['!','@','#','$'] # Generate the strings strings = [] for _ in range(num_strings): string = '' for _ in range(length): string += random.choice(chars) strings.append(string) return strings ``` 另外还需要引入必要的python库: ```python from flask import request from flask import jsonify import random ``` 编写代码后,运行flask run看是否有出现错误,如果没有错误,接下来就需要来测试随机数端口,看是否可以根据客户端提供的参数返回对应的结果。 我们采用bruno软件来测试API接口:[postman替代,轻量级、免费免安装的postman替代品Bruno (qq.com)](https://mp.weixin.qq.com/s?__biz=MzkzNjU2ODUzMw==&mid=2247484028&idx=1&sn=2e984b26f6c26fab5f0fd1812e6b7c34&chksm=c29df1c6f5ea78d01512dab9eb78c9e7fd8f547e0ac8e1e226579649404b9a18c4bcb999e557&token=519512246&lang=zh_CN#rd)比如测试hello接口: ![2024-03-26-bruno测试gethello](.\img\2024-03-26-bruno测试gethello.jpg) 测试随机数生成的接口: ![2024-03-26-postbruno测试](.\img\2024-03-26-postbruno测试.jpg) 说明现在的Flask App功能已经完善,剩下是生产环境部署。要部署,我们首先修改.flaskenv文件: ```bash FLASK_ENV=production ##设置为生产环境; FLASK_APP=app.py ##如果你app名为app,可以不显示注明;如果不是,一定要显示注明。 FLASK_RUN_PORT=5000 ##重新设置为5000端口 ``` #### 2. gunicorn的安装与使用 生产环境中,Flask自带的WSGI服务器不够用,我们需要使用更专业的服务器,比如gunicorn; 我们在python虚拟环境中,安装gunicorn: ```python pip3 install gunicorn ``` 安装成功后,当前目录下运行gunicorn: ```bash gunicorn -w 3 -b 0.0.0.0:5000 app:app ``` - -w:表示开启三个进程, gunicorn 应该使用的工作进程数量。在这里,它设置为 3,意味着会有 3 个工作进程并行地处理请求,这有助于提高应用的吞吐量; - -b:表示接收所有ip访问,并且端口为5000; - -app:app:启动app(.py文件)模块中的app对象; ![2024-03-26-gunicorn启动三个进程](.\img\2024-03-26-gunicorn启动三个进程.jpg) 如上图gunicorn开始启动运行,开了三个工作进程;再次使用bruno来测试post,注意端口是5000,发现可以正常的工作。 #### 3. supervisor的安装与配置 对照我们的架构图,现在我们还需要安装一个supervisor,supervisor的主要作用是监控gunicorn的运行,万一gunicorn因为各种原因down机,supervisor可以自动重启gunicorn,保证生产环境的稳定性。 ![Nginx与Flask架构图](.\img\Nginx与Flask架构图.jpg) ubuntu下安装supervisor的命令如下: ```bash sudo apt install supervisor ``` 进入supervisor的配置文件夹,/etc/supervisor/conf.d/,创建名为"flaskrandom.conf"配置文件,主要内容如下: ```bash [program:flaskrandom] command=/home/tfzhang/myflask/bin/gunicorn -w 3 -b 0.0.0.0:5000 app:app directory=/home/tfzhang/myflask/ ##app.py所在的目录; user=tfzhang ##当前操作系统的用户名 autostart=true autorestart=true stopasgroup=true killasgroup=true ``` 更新完"flaskrandom.conf"配置文件后,再输入如下两个命令: ```bash sudo supervisorctl reread ##重新读取配置文件; sudo supervisorctl update ##使新配置文件生效; ``` 查看当前supervisor监控的任务: ```bash sudo supervisorctl ``` ![2024-03-26-supervisor基本操作](.\img\2024-03-26-supervisor基本操作.jpg) 可以发现Flask App对应的进程已经运行,用浏览器或者bruno可以正常访问服务,说明supervisor配置正确。 假设现在**意外重启Ubuntu**,可以测试Flask App是否会随着机器的重启,而**自动运行**。 要关闭app服务,则在supervisor终端: ```bash sudo supervisorctl ##启动supervisor终端 supervisor > stop flaskrandom ``` 如果要启动,则同样的: ```bash supervisor > start flaskrandom ``` #### 4. 配置Nginx的反向代理 生产环境中,不会直接使用gunicorn接收用户的请求,用户的请求首先到达Nginx,再由Nginx作反向代理,去访问gunicorn。 为什么需要将Nginx作反向代理? - Nginx功能更强大; - 安全:通过Nginx作内外隔离; Ubuntu下安装Nginx的命令: ```bash sudo apt install nginx ``` 完成nginx安装后,配置nginx文件/etc/nginx/sites-available/default: ```bash server { listen 80 default_server; listen [::]:80 default_server; root /var/www/html; # Add index.php to the list if you are using PHP index index.html index.htm index.php index.nginx-debian.html; server_name _; location / { proxy_pass http://127.0.0.1:5000/; try_files $uri $uri/ =404; } # pass PHP scripts to FastCGI server # location ~ \.php$ { include snippets/fastcgi-php.conf; # # With php-fpm (or other unix sockets): fastcgi_pass unix:/var/run/php/php7.2-fpm.sock; } } ``` 上述配置文件中,最重要的一句是: ```bash proxy_pass http://127.0.0.1:5000/; ``` 主要含义是将原来到"/"的访问重定向到"http://127.0.0.1:5000/",保存上述配置文件,然后重启nginx使得新配置生效: ```bahs sudo service nginx reload ``` 我们再次测试时,可以发现不需要再在浏览器或者bruno中带5000端口号,就可以访问到Flask App的数据,说明nginx的反向代理发挥作用。 ![2024-03-26-nginx反向代理成功](.\img\2024-03-26-nginx反向代理成功.jpg) #### 5. 总结 上述我们所有的操作都是Ubuntu18.04系统上测试通过,由于是本地虚拟机,不能演示如何配置网站域名以及SSL证书,所以关于上线的内容大家可以直接去看其他关于Nginx如何上线的内容,这些内容与Flask App已经没有关系,完全只和Nginx有关。 到实际的云服务器环境,只要你选择的操作系统是Ubuntu18.04,上述操作可以复刻,唯一可能需要注意的地方是防火墙,开端口访问权相关的问题。 #### 6 源代码: app.py源代码位于[gitee](https://gitee.com/bigbug55/flaskabc)