# 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作为网络服务器,接收来自用户的请求,并将请求反向代理到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
```

根据终端的提示,用浏览器打开http://127.0.0.1:5000/即可看到输出:

仔细观察终端的输出,可以发现当前的开发环境是: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:

上图中可以发现已经处于开发模式,并且端口也切换到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接口:

测试随机数生成的接口:

说明现在的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对象;

如上图gunicorn开始启动运行,开了三个工作进程;再次使用bruno来测试post,注意端口是5000,发现可以正常的工作。
#### 3. supervisor的安装与配置
对照我们的架构图,现在我们还需要安装一个supervisor,supervisor的主要作用是监控gunicorn的运行,万一gunicorn因为各种原因down机,supervisor可以自动重启gunicorn,保证生产环境的稳定性。

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
```

可以发现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的反向代理发挥作用。

#### 5. 总结
上述我们所有的操作都是Ubuntu18.04系统上测试通过,由于是本地虚拟机,不能演示如何配置网站域名以及SSL证书,所以关于上线的内容大家可以直接去看其他关于Nginx如何上线的内容,这些内容与Flask App已经没有关系,完全只和Nginx有关。
到实际的云服务器环境,只要你选择的操作系统是Ubuntu18.04,上述操作可以复刻,唯一可能需要注意的地方是防火墙,开端口访问权相关的问题。
#### 6 源代码:
app.py源代码位于[gitee](https://gitee.com/bigbug55/flaskabc)