ZongXR / Flask-SSM

一款模仿SpringFramework的Python的web后端框架,基于Flask二次封装。通过Python反射模拟了Java的IOC控制反转,通过Python装饰者模式模拟了Java的AOP面向切面编程。具有接口自动发现、定时任务自动注册、事务管理器、单元测试,等功能。简化web后端开发流程,聚焦业务逻辑,让你按照Spring的习惯写Python
https://pypi.org/project/Flask-SSM/
GNU General Public License v3.0
23 stars 5 forks source link
aspect-oriented-programming flask flask-apscheduler flask-sqlalchemy inversion-of-control java mvc mybatis python reflection spring springframework web

Flask-SSM

一款模仿SpringFramework的Python的web后端框架,基于Flask二次封装。通过Python反射模拟了Java的IOC控制反转,通过Python装饰者模式模拟了Java的AOP面向切面编程。具有接口自动发现、定时任务自动注册、事务管理器、单元测试,等功能。简化web后端开发流程,聚焦业务逻辑,让你按照Spring的习惯写Python

使用方法

首先使用以下命令安装该框架
pip install Flask-SSM
使用教程请参考此地址中的test.demo包,这是一个具有典型MVC结构的最小web应用。

创建基础环境

  1. test.demo包所示,在test.demo.__init__.py中定义SpringApplication类的对象。
    sp = SpringApplication()
  2. app.py所示,在app.py中导入该对象,然后对其进行初始化。
    from test.demo import sp
    app = Flask(sp.base_package.__package__)
    sp.init_app(app)
    app.run()
    

应用配置项

  1. test.demo.config包所示,在test.demo.config.__init__.py中导入Configuration类,该包内的配置项能自动识别。
    from flask_ssm.springframework.context.annotation import Configuration
  2. 建议将同一类别的配置写在同一模块内。如test.demo.config.app_config所示:
    APP_HOST = "0.0.0.0"      # 定义了应用的域
    APP_PORT = 5000           # 定义了应用的端口
    APPLICATION_ROOT = "/"    # 定义了应用的根路径
    USE_RELOADER = False      # 是否开启热更新
    DEBUG = False             # 是否处于debug模式
    APP_THREAD = False        # 是否开启多线程
    APP_PROCESS = 1           # 进程个数
    

需要注意的是:

web接口层

  1. test.demo.controller包所示,在test.demo.controller.__init__.py中导入Controller类,标记该包内所有模块的函数为web接口。
    from flask_ssm.springframework.stereotype import Controller
  2. test.demo.controller.base_controller所示,对需要注册的接口直接加上@RequestMapping(value=**, method=**)@GetMapping(value=**)@PostMapping(value=**)。如果需要对参数的类型进行校验,可以使用type hints。
  3. test.demo.controller.customize_controller所示,如果需要json格式的响应体,在@RequestMapping后面加上@ResponseBody,把函数返回值映射为json格式写入响应体中。
    @RequestMapping("/hello_world", [RequestMethod.POST])
    @ResponseBody
    def hello_world(param):
        result = base_service.run(param)
        return CommonResult.ok(data=result)
    
  4. 如果某个模块的接口均为restful风格,那么只需要在该模块引入RestController,而忽略@ResponseBody装饰器
    from flask_ssm.springframework.web.bind.annotation import RestController
  5. test.demo.controller.customize_controller所示,对该模块内的全局异常处理函数加上@ExceptionHandler(value=**)
    @ExceptionHandler(Exception)
    def custom_error_handler(e):
        return str(e)
    

业务逻辑层

  1. test.demo.service包所示,在test.demo.service.__init__.py中导入Service类。
    from flask_ssm.springframework.stereotype import Service
  2. 对于涉及数据修改的函数,使用@Transactional(rollback_for=**)修饰,并使用rollback_for指定回滚的异常类型,从而开启事务。
  3. test.demo.service.base_service所示,对于需要进行单元测试的函数,使用@Test修饰该函数,并作为入口运行。
    @Test
    def run(param):
        result = tablename_dao.query_one(param)
        return str(result)
    if __name__ == "__main__":
        print(run("Hello World"))
    

数据交互层

  1. test.demo.dao包所示,在test.demo.dao.__init__.py中导入Repository类,可以使用注解式数据查询。
    from flask_ssm.springframework.stereotype import Repository
  2. test.demo.dao.tablename_dao所示,对于查询函数,使用@Mapper(result_type=**)修饰,并使用result_type指定返回类型。函数的参数为传入SQL语句的参数,返回值为SQL语句,SQL语句的参数部分同MyBatis的用法,即可实现返回对象的自动封装。如果需要对SQL语句传参类型进行校验,可以使用type hints。
    @Mapper(result_type=str)
    def query_one(param):
        sql = """
            select #{param};
        """
        return sql
    

定时任务

  1. test.demo.task包所示,在test.demo.task.__init__.py中导入Scheduled类,可以实现该包内的定时任务自动注册。
    from flask_ssm.springframework.scheduling.annotation import Scheduled
  2. test.demo.task.my_task所示,在模块中声明FUNC, TRIGGER等用于标志定时任务的变量即可,这些变量必须大写。FUNC表示定时任务执行的函数名,对应的函数需要在文件内给出,置空禁用定时任务。其他标识与Flask-APScheduler的用法完全一致,直接填入即可。
    FUNC = "my_func"           # 生效的函数名,如需禁用可设为None
    TRIGGER = "interval"       # 触发条件,interval表示定时间间隔触发
    SECONDS = 5                # 触发时间间隔设定5秒
    REPLACE_EXISTING = True    # 重启替换持久化
    def my_func():             # 定时执行的函数
        current_app.logger.info("触发定时任务")
    

ORM对象

  1. test.demo.pojo.pojo_demo所示,每一个ORM映射对象需要使用类进行定义,并使用@TableName(value=**)修饰,使用value指定表名。类的属性需要与表的字段对应,并使用Column类封装。
    @TableName("table_name")
    class Pojo:
        user_id = Column(INTEGER, primary_key=True)
        teach_time = Column(DECIMAL(precision=2, scale=0))
    

版本更新

版本更新内容更新日期
1.0.0.0完成模板搭建,实现MVC分层,现在可以自助接入自定义内容。2022年1月2日
1.1.0.0完善模板,现在可以在controller下自建多级包2022年1月9日
1.1.1.0完善模板,现在可以在service下自建多级包2022年1月10日
1.1.2.0完善模板,现在可以在task下自建多级包2022年1月11日
1.1.2.1添加模板目录2021年1月30日
1.2.0.0service层设置为单例模式;补充SQLalchemy的点查询demo2022年7月14日
1.3.0.0分离pojo和dao2022年7月16日
1.3.1.0输出更多日志2022年7月16日
1.3.2.0增加ViewObject; 增加logs目录2022年8月5日
1.4.0.0修改前端页面,可自定义请求方式、mime值、url、请求正文; 更改数据库用户名密码; 输出更多日志2022年8月5日
1.4.1.0修改前端页面样式2022年8月5日
1.5.0.0新增自定义异常及全局、局部异常处理2022年8月5日
1.5.1.0优化导入包路径2022年8月5日
1.5.2.0将多个Controller分布到不同的蓝图2022年8月7日
1.6.0.0将蓝图注册与初始化解耦,自动将py模块注册为蓝图; 异常handler增加日志输出2022年8月7日
1.7.0.0规范命名; service使用模块自动单例模式2022年8月10日
1.7.0.1优化代码; 更新使用说明2022年8月11日
1.8.0.0现在不需要把BluePrint对象命名为bp,也能实现蓝图的自动注册2022年8月13日
1.8.0.1fix some bugs2022年8月13日
1.9.0.0解耦task、controller、config、utils各个子模块,不需要的模块直接删除即可;fix some bugs2022年12月28日
2.0.0.0优化代码,提升执行效率2022年12月28日
2.1.0.0修复BUG; 新增事务管理器; 新增工具类2023年4月27日
2.2.0.0新增运行入口; 新增docker部署运行方式2023年5月22日
2.2.1.0暴露端口50002023年5月22日
2.2.2.0排除目录docs, sql2023年5月22日
2.2.2.1add some exclude path2023年5月22日
2.2.2.2修复数据库连接包含特殊字符导致无法连接的BUG2023年5月26日
2.3.0.0新增单元测试功能; 前端新增PUT和DELETE请求方式; 规范dao的用法2023年5月26日
2.3.0.1fix some bugs2023年5月29日
2.4.0.0add initializer2023年5月30日
2.4.0.1fix some bugs2023年5月30日
2.4.0.2fix some bugs2023年5月31日
2.4.0.3fix some bugs2023年6月1日
2.5.0.0add mapper decorator; fix some bugs; add unit test example; change dao function usage2023年6月2日
2.5.1.0@mapper新增np.ndarray类型支持, 新增其他自定义参数, 修复注释错误; @test优化执行逻辑2023年6月3日
2.6.0.0config包自动配置,现在仅需要在其中写入键值对即可自动生效2023年6月24日
2.7.0.0将配置信息全部写入config包内; 新增eureka注册功能2023年6月24日
2.7.1.0新增HOST, PORT等配置项; 初始化脚本新增--app-host, --app-port, --app-debug, --application-root选项2023年6月24日
2.7.2.0initializer的--application-root选项修改index.html2023年6月25日
2.7.3.0fix some bugs2023年6月26日
2.7.4.0允许使用同名环境变量对配置项覆盖; fix some bugs2023年6月27日
2.7.5.0更换eureka客户端; fix some bugs2023年6月29日
2.7.6.0增加多线程、多进程配置项2023年7月1日
2.7.6.1fix some bugs2023年7月14日
2.8.0.0新增上传文件功能2023年7月17日
2.8.1.0传输文件使用临时文件,避免磁盘IO2023年7月18日
2.8.2.0增加定时任务配置项; 主页新增"清屏"按钮2023年7月20日
2.8.2.1开启定时任务调度持久化; fix some bugs2023年7月20日
2.8.2.2fix some bugs2023年7月21日
2.8.2.3fix some bugs; 修改数据库配置项2023年7月23日
2.8.2.4启用自动重新加载2023年7月24日
2.8.2.5修正不规范的命名2023年7月26日
2.8.2.6修复pybatis的空指针异常2023年7月28日
2.8.2.7fix some bugs; 优化代码执行逻辑2023年8月11日
2.9.0.0优化代码执行逻辑; 修改定时任务默认配置项; @mapper新增Generator的定义2023年8月28日
2.9.1.0fix some bugs; 更新pybatis的用法2023年8月31日
2.9.1.1删除CursorResultUtils.py; 更新说明文档2023年9月1日
2.9.1.2fix some bugs2023年9月14日
2.9.2.0更新pybatis用法; 更新说明文档2023年9月15日
2.9.3.0更新主页, 新增表单提交功能2023年9月20日
2.9.4.0新增对mime值选项的悬停提示, 提示内容为后端接收参数方式2023年9月21日
2.9.4.1fix some bugs2023年9月25日
2.9.5.0修改前端页面样式2023年10月12日
2.9.6.0基于反射技术给定时任务加入上下文,修复定时任务中缺失上下文的BUG; 修复前端页面多次请求参数错误的BUG2023年10月31日
3.0.0.0彻底分离框架与业务逻辑,构建框架Flask-SSM2023年11月9日
3.1.0.0新增装饰器@TableName; 装饰器@Test新增统计运行时间的功能,并输出到日志; 修复若干BUG2023年11月10日
3.2.0.0新增安装脚本; 框架上传至pypi官方源2023年11月11日
3.3.0.0新增@RequestMapping@ExceptionHandler装饰器; 修改包结构2023年11月12日
3.4.0.0新增@GetMapping@PostMapping装饰器2023年11月13日
3.5.0.0@RequestMapping装饰器实现参数注入功能,现在可以直接把请求参数写入接口的函数形参。2023年11月14日
3.5.1.0优化执行逻辑,提升执行效率2023年11月14日
3.6.0.0新增@ResponseBody装饰器, 修复若干BUG2023年11月19日
3.7.0.0新增RestController2023年11月27日
3.7.1.0新增@PutMapping@DeleteMapping@PatchMapping装饰器2023年11月30日
3.7.1.1fix some bugs2023年12月11日
3.7.1.2去除不必要的依赖2023年12月13日
3.7.2.0定时任务默认使用文件名作为IDFUNC为空时禁用定时任务; 优化执行逻辑,提升运行效率2023年12月21日
3.7.2.1fix some bugs2023年12月25日
3.7.2.2SQL语句兼容MyBatis的#{param}形式; fix some bugs2023年12月26日
3.7.2.3SQL语句兼容MyBatis的${param}形式2023年12月26日
3.7.2.4fix some bugs2023年12月29日
3.7.2.5change github username2023年12月29日
3.7.2.6change github username2023年12月29日
3.7.3.0兼容Python 3.102024年7月12日
3.7.3.1fix some bugs2024年7月12日
3.7.3.2fix some bugs2024年7月13日
3.7.3.3fix some bugs2024年7月25日
3.7.3.4fix some bugs2024年7月27日
3.8.0.0集成Flask-Pydantic,现在可以使用type hints对API及SQL的参数类型进行校验2024年7月31日
3.8.0.1修复使用外部web服务器运行带来的BUG2024年8月2日