# flask-restful-api-template-v2.0 **Repository Path**: chuanggao/flask-restful-api-template-v2.0 ## Basic Information - **Project Name**: flask-restful-api-template-v2.0 - **Description**: Flask-Restful+Migrate+JWT+Redis+celery+APScheduler综合后端API服务器案例 - **Primary Language**: Unknown - **License**: AFL-3.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2024-07-16 - **Last Updated**: 2024-07-16 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # flask-restful-api-template > Flask-Restful+Migrate+JWT+Redis+celery+APScheduler综合后端API服务器案例 - 实现用户注册 - 实现用户登录登出-基于jwt - 实现基于token登录安全认证 - 实现redis tasks数据的读写 - 实现celery 异步tasks任务的执行和反馈 - 实现Flask-APScheduler定时任务 - 实现加载yaml配置文件 - 实现yaml配置logger及logger使用 - 实现接口标准化及全球化 - 实现接口响应封装及自定义json返回类型 - 实现SQLAlchemy+Falsk-Restful的集成CURD - v1: 使用 Python 和 Flask 设计 RESTful API - v2: 使用 Flask-RESTful 设计 RESTful API ## 1.创建虚拟环境 ```shell $ python -m venv venv ``` ## 2.安装相关依赖包 ```shell # 激活虚拟环境 # Linux $ source venv/bin/activate # Windows $ venv\Scripts\activate # 安装相关依赖包 $ pip install -r requirements.txt ``` ## 3.初始化迁移数据 - flask-migrate Linux 和 macOS 用户这样做: ``` (venv) $ export FLASK_APP=run.py (venv) $ export FLASK_DEBUG=1 ``` 微软 Windows 用户这样做: ``` (venv) $ set FLASK_APP=run.py (venv) $ set FLASK_DEBUG=1 ``` 创建数据 ```shell (venv) $ flask db init (venv) $ flask db migrate (venv) $ flask db upgrade ``` 初始化数据库命令 ```shell # 此命令会删除数据重新创建数据库 (venv) $ flask initdb --drop This operation will delete the database, do you want to continue? [y/N]: y ``` ## 4.手动录入测试数据 ```sql INSERT INTO `todo` VALUES (1, '白鹿原', '这是一定死啦塞啊;阿凯骄傲灵丹安矿鉴定暗访东方三;啊反馈;安静快撒娇扥卡机', 0); INSERT INTO `todo` VALUES (2, '嫌疑人', 'as大肯借;额看课文静安寺放大反抗航将;来否;付定金奥兰多 看企鹅长恨东澳岛啊;伐开森', 0); ``` ## 5.启动项目 ```shell (venv) $ set FLASK_APP=run.py (venv) $ set FLASK_DEBUG=1 (venv) $ flask run -h 0.0.0.0 -p 5000 * Serving Flask app 'run.py' * Debug mode: on WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead. * Running on all addresses (0.0.0.0) * Running on http://127.0.0.1:5000 * Running on http://172.16.3.134:5000 Press CTRL+C to quit * Restarting with stat * Debugger is active! * Debugger PIN: 170-478-610 ``` ## 6.api访问测试 #### 6.1 API接口列表 ##### 用户状态操作 | 接口 | API地址 | | ---- | ---- | | 注册用户 | http://localhost:5000/api/v1.0/register | | 用户登录 | http://localhost:5000/api/v1.0/login | | 查看所有用户 | http://localhost:5000/api/v1.0/users | | 查看单个用户 | http://localhost:5000/api/v1.0/user/1 | | 更新单个用户 | http://localhost:5000/api/v1.0/user/1 | | 删除单个用户 | http://localhost:5000/api/v1.0/user/1 | | 刷新token | http://localhost:5000/api/v1.0/token/refresh| | 用户注销登录 | http://localhost:5000/api/v1.0/logout/access | | 用户注销刷新 | http://localhost:5000/api/v1.0/logout/refresh | 注册用户 ```shell curl --request POST \ --url http://localhost:5000/api/v1.0/register \ --header 'Content-Type: application/json' \ --data '{"email": "2@2.com","username":"hjl2","password":"123456"}' ``` 用户登录 ```shell curl --request POST \ --url http://localhost:5000/api/v1.0/login \ --data '{"username": "hjl1","password": "123456"}' ``` 查看所有用户 ```shell curl -i http://localhost:5000/api/v1.0/users \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNjYzNTgwNzY5LCJqdGkiOiI4Y2JhMDRmMS1kOTRhLTQ0MWQtOWM5My01OTFhNzlhMjI4YWYiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoiaGpsMSIsIm5iZiI6MTY2MzU4MDc2OSwiZXhwIjoxNjYzNTgxNjY5fQ.1GvPqgtNNOQ95HRFiLwAbeU9-BUU5uJniw0jAz6QLAs' \ --header 'Content-Type: application/json' ``` 查看单个用户 ```shell curl -i http://localhost:5000/api/v1.0/user/1 \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNjYzNTgwNzY5LCJqdGkiOiI4Y2JhMDRmMS1kOTRhLTQ0MWQtOWM5My01OTFhNzlhMjI4YWYiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoiaGpsMSIsIm5iZiI6MTY2MzU4MDc2OSwiZXhwIjoxNjYzNTgxNjY5fQ.1GvPqgtNNOQ95HRFiLwAbeU9-BUU5uJniw0jAz6QLAs' \ -H 'Content-Type: application/json' ``` 更新单个用户 ```shell curl -i -H "Content-Type: application/json" \ -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNjYzNTgwNzY5LCJqdGkiOiI4Y2JhMDRmMS1kOTRhLTQ0MWQtOWM5My01OTFhNzlhMjI4YWYiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoiaGpsMSIsIm5iZiI6MTY2MzU4MDc2OSwiZXhwIjoxNjYzNTgxNjY5fQ.1GvPqgtNNOQ95HRFiLwAbeU9-BUU5uJniw0jAz6QLAs' \ -X PUT -d '{"username": "hjl1"}' \ http://localhost:5000/api/v1.0/user/1 ``` 删除单个用户 ```shell curl --request DELETE \ --url http://localhost:5000/api/v1.0/user/2 \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNjYzNTgwNzY5LCJqdGkiOiI4Y2JhMDRmMS1kOTRhLTQ0MWQtOWM5My01OTFhNzlhMjI4YWYiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoiaGpsMSIsIm5iZiI6MTY2MzU4MDc2OSwiZXhwIjoxNjYzNTgxNjY5fQ.1GvPqgtNNOQ95HRFiLwAbeU9-BUU5uJniw0jAz6QLAs' \ --header 'Content-Type: application/json' ``` 刷新token ```shell curl --request POST \ --url http://localhost:5000/api/v1.0/token/refresh \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY2MzU4MDc2OSwianRpIjoiMzMyNTkyODYtNWY1NS00MzlmLTg2ZDktYWMyODRjZjA2YjMxIiwidHlwZSI6InJlZnJlc2giLCJzdWIiOiJoamwxIiwibmJmIjoxNjYzNTgwNzY5LCJleHAiOjE2NjYxNzI3Njl9.BaMmLRu6H-PjBN4MjWymnB0wlTeioMev4wD_34S5Yd8' \ --header 'Content-Type: application/json' ``` 用户注销登录 ```shell curl --request POST \ --url http://localhost:5000/api/v1.0//logout/access \ --header 'Accept: */*' \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY2MzU4MTU1OCwianRpIjoiOTJiMzllOWMtMjg4OS00NTc0LThlYTQtZmIwMTFiMzJiNWU3IiwidHlwZSI6ImFjY2VzcyIsInN1YiI6ImhqbDEiLCJuYmYiOjE2NjM1ODE1NTgsImV4cCI6MTY2MzU4MjQ1OH0.Hfd4uovp6nDVLqQKDtrNk_ncSWPt7wjR2qFazDWfwuY' \ --header 'Content-Type: application/json' ``` 用户注销刷新 ```shell curl --request POST \ --url http://localhost:5000/api/v1.0//logout/refresh \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6ZmFsc2UsImlhdCI6MTY2MzU4MDc2OSwianRpIjoiMzMyNTkyODYtNWY1NS00MzlmLTg2ZDktYWMyODRjZjA2YjMxIiwidHlwZSI6InJlZnJlc2giLCJzdWIiOiJoamwxIiwibmJmIjoxNjYzNTgwNzY5LCJleHAiOjE2NjYxNzI3Njl9.BaMmLRu6H-PjBN4MjWymnB0wlTeioMev4wD_34S5Yd8' \ --header 'Content-Type: application/json' ``` ##### 任务状态操作 | 接口 | API地址 | | ---- | ---- | | 查看所有任务 | http://localhost:5000/api/v1.0/tasks | | 新增单个任务 | http://localhost:5000/api/v1.0/tasks | | 查看单个任务 | http://localhost:5000/api/v1.0/tasks/3 | | 更新单个任务 | http://localhost:5000/api/v1.0/tasks/3 | | 删除单个任务 | http://localhost:5000/api/v1.0/tasks/3 | 查看所有任务 ```shell curl --request GET \ --url http://localhost:5000/api/v1.0/tasks \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNjYzNTgyNDY3LCJqdGkiOiIyYWQ2NGIyNC03OGFkLTQ2OTQtYWRjZS1hNmZhYjExYzYxNzEiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoiaGpsMSIsIm5iZiI6MTY2MzU4MjQ2NywiZXhwIjoxNjYzNTgzMzY3fQ.tLwVHfBO91JNlBskqBfKzzWh2xf_GKyHGsddjoQ7VIw' \ --header 'Content-Type: application/json' ``` 新增单个任务 ```shell curl --request POST \ --url http://localhost:5000/api/v1.0/tasks \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNjYzNTgyNDY3LCJqdGkiOiIyYWQ2NGIyNC03OGFkLTQ2OTQtYWRjZS1hNmZhYjExYzYxNzEiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoiaGpsMSIsIm5iZiI6MTY2MzU4MjQ2NywiZXhwIjoxNjYzNTgzMzY3fQ.tLwVHfBO91JNlBskqBfKzzWh2xf_GKyHGsddjoQ7VIw' \ --header 'Content-Type: application/json' \ --data '{"title": "阿里巴巴和四十大盗"}' ``` 查看单个任务 ```shell curl --request GET \ --url http://localhost:5000/api/v1.0/tasks/3 \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNjYzNTgyNDY3LCJqdGkiOiIyYWQ2NGIyNC03OGFkLTQ2OTQtYWRjZS1hNmZhYjExYzYxNzEiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoiaGpsMSIsIm5iZiI6MTY2MzU4MjQ2NywiZXhwIjoxNjYzNTgzMzY3fQ.tLwVHfBO91JNlBskqBfKzzWh2xf_GKyHGsddjoQ7VIw' \ --header 'Content-Type: application/json' ``` 更新单个任务 ```shell curl --request PUT \ --url http://localhost:5000/api/v1.0/tasks/3 \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNjYzNTgyNDY3LCJqdGkiOiIyYWQ2NGIyNC03OGFkLTQ2OTQtYWRjZS1hNmZhYjExYzYxNzEiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoiaGpsMSIsIm5iZiI6MTY2MzU4MjQ2NywiZXhwIjoxNjYzNTgzMzY3fQ.tLwVHfBO91JNlBskqBfKzzWh2xf_GKyHGsddjoQ7VIw' \ --header 'Content-Type: application/json' --data '{ "description": "一千零一夜故事里面的篇幅"}' ``` 删除单个任务 ```shell curl --request DELETE \ --url http://localhost:5000/api/v1.0/tasks/3 \ --header 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJmcmVzaCI6dHJ1ZSwiaWF0IjoxNjYzNTgyNDY3LCJqdGkiOiIyYWQ2NGIyNC03OGFkLTQ2OTQtYWRjZS1hNmZhYjExYzYxNzEiLCJ0eXBlIjoiYWNjZXNzIiwic3ViIjoiaGpsMSIsIm5iZiI6MTY2MzU4MjQ2NywiZXhwIjoxNjYzNTgzMzY3fQ.tLwVHfBO91JNlBskqBfKzzWh2xf_GKyHGsddjoQ7VIw' \ --header 'Content-Type: application/json' ``` ### 6.2 redis数据库的API-task | 接口 | API地址 | | ---- | ---- | | redis写入数据 | http://localhost:5000/api/testRedisWrite | | redis读取数据 | http://localhost:5000/api/testRedisRead | 写入数据redis数据库 ```shell curl --request GET \ --url http://localhost:5000/api/v1.0/testRedisWrite ``` 读取redis数据 ```shell curl --request GET \ --url http://localhost:5000/api/v1.0/testRedisRead ``` ## 7.Flask工厂模式集成使用Celery-异步任务 | 接口 | API地址 | | ---- | ---- | | 测试相加-task | http://localhost:5000/api/testAdd | | 测试获取flask上下文-task | http://localhost:5000/api/testFlaskAppContext | - celery启动 windows shell中输入 ```shell celery -A run:celery_app worker --pool=solo -l info ``` Linux shell中输入 ```shell celery -A run:celery_app worker -l info ``` 启动Flask APP ```shell (venv) $ flask run -h 0.0.0.0 -p 5000 ``` 参考文献: > 主要解决了新版本的Celery使用Flask上下文的功能 > https://www.qinzhiqiang.xyz/article/19 ## 8.flask-jwt用户认证授权 ### 8.1 Flask实现JsonWebToken的用户认证授权-flask-jwt-extended插件 本demo使用的就是flask-jwt-extended插件 > https://xugaoxiang.com/2020/09/01/flask-18-jwt-extended/ > https://www.jianshu.com/p/c155c2b7af42 > https://www.cnblogs.com/WiseAdministrator/articles/11734600.html 官方文档 > https://flask-jwt-extended.readthedocs.io/en/stable/ 新版本的flask-jwt-extended,已经改了很多的API了, 参考: https://flask-jwt-extended.readthedocs.io/en/stable/v4_upgrade_guide/#api-changes ### 8.2 Flask实现JsonWebToken的用户认证授权-PyJWT插件 https://www.qinzhiqiang.xyz/article/11 ## 9.Flask-APScheduler定时任务 **APScheduler** APScheduler的全称是Advanced Python Scheduler。 它是一个轻量级的 Python 定时任务调度框架。 APScheduler 支持三种调度任务:固定时间间隔,固定时间点(日期),Linux 下的 Crontab 命令。 同时,它还支持异步执行、后台执行调度任务。 > 官方文档 > https://apscheduler.readthedocs.io/en/latest/ APScheduler操作数据库 `app/tasks/scheduler_task.py` ``` # task.py中使用数据库 def db_query_todo_all(): """ 定时任务使用数据库 """ # 一定是要导入scheduler,这个是带有app及其上下文的,如果直接用current_app替代scheduler.app使用上下文 with scheduler.app.app_context(): data = db.session.query(Users).first() print(data.username) ``` ## 10.Flask接口单元测试+测试报告+测试覆盖率 https://www.qinzhiqiang.xyz/article/20