Flask 扩展 自定义扩展
创建一个为视图访问加日志的扩展Flask-Logging,并从中了解到写Flask扩展的规范。
创建工程
先创建一个工程,目录结构如下:
flask-logging/├ LICENSE # 授权说明├ README # 项目介绍├ setup.py # 打包分发文件└ flask_logging/ # 扩展代码包└ __init__.py # 扩展代码
根据Flask扩展命名规范,扩展名必须为”Flask-Logging”形式,以”Flask-“为前缀,后面的单词首字母大写。扩展的代码必须放在名为”flask_logging”的包下,注意这里是下划线,与扩展名中的横线不同,单词都小写。”LICENSE”和”README”文件都是审核必须的,关于审核部分,我们会在后面介绍。
编写分发文件
接下来,我们写”setup.py”文件,示例如下:
""" Flask-Logging -------------Log every request to specific view """ from setuptools import setupsetup(name='Flask-Logging',version='1.0',url='http://example.com/flask-logging/',license='BSD',author='Billy J. Hee',author_email='billy@bjhee.com',description='Log every request to specific view',long_description=__doc__,packages=['flask_logging'],zip_safe=False,include_package_data=True,platforms='any',install_requires=['Flask'],classifiers=['Environment :: Web Environment','Intended Audience :: Developers','License :: OSI Approved :: BSD License','Operating System :: OS Independent','Programming Language :: Python','Topic :: Internet :: WWW/HTTP :: Dynamic Content','Topic :: Software Development :: Libraries :: Python Modules'] )
这里需要注意几点:
- 扩展名的格式必须为”Flask-Logging”,上节介绍过
- 必须指定url链接到扩展主页或文档
- “zip_safe”必须为False
- “install_requires”必须列出所有依赖的库
编写扩展代码
进入主题了,由于我们的扩展相当简单,因此所有代码都放在了”__init__.py”中:
#coding:utf8 from flask import current_app, request from functools import wraps from logging.handlers import TimedRotatingFileHandler import logging import time# 指定日志文件名,日志级别,及日志记录格式 entry_log = TimedRotatingFileHandler('entry.log','D') entry_log.setLevel(logging.DEBUG) entry_log.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(message)s'))class Logging:# 构造函数def __init__(self, app=None):self.app = appif app is not None:self.init_app(app)# 初始化应用def init_app(self, app):app.logger.addHandler(entry_log)# 视图装饰器,被装饰的视图将自动记录访问日志def log_entry(self, func):app = self.app or current_app@wraps(func)def decorator(*args, **kwargs):start = time.time()# 记录请求开始app.logger.debug('Start request call: %s' % request.url)ret = func(*args, **kwargs)# 记录请求结束app.logger.debug('Finish request call: %s' % request.url)duration = time.time() - start# 记录请求所耗时长app.logger.debug('Request: %s consumed %f s' % (request.url, duration))return retreturn decorator
代码逻辑都在写注释里了,这个扩展提供了”log_entry”视图装饰器,来记录视图访问日志。这里同样要注意几个重要的部分:
- 构造函数”__init__()”和初始化函数”init_app()”是必须的
- 如果构造函数传入了app,则调用”init_app()”,这样确保两者功能一致
- 构造函数里我们设置了”self.app=app”,而”init_app()”没有,这是为什么呢?这是一种规范,或者说习惯。当系统只有一个app时,建议使用构造函数初始化扩展对象,这时对象中的app就指向这一个应用。而当系统有多个应用同时存在,比如说应用工厂或测试场景下,建议使用”init_app()”来初始化扩展对象,这样扩展对象不会指向任何应用
- 在视图装饰器里,我们使用了”app = self.app or current_app”来获取当前应用,这分别对应于上一点说的单个应用及多个应用场景
- 因为视图装饰器是视图访问时被调用,所以此时应用上下文和请求上下文都存在,因此我们可以访问到”current_app”和”request”对象。离开上下文的话,就无效了
扩展写完了,让我们来测试一下,创建一个Flask应用:
from flask import Flask from flask_logging import Loggingapp = Flask(__name__) logging = Logging(app)@app.route('/') @logging.log_entry def index():return '<h1>Hello World</h1>'if __name__ == '__main__':app.run(host='0.0.0.0', debug=True)
启动应用,访问”http://localhost:5000/”。查看下代码当前路径,是不是出现了”entry.log”文件,并且记录了URL请求日志
关于审核
如果要将自己的扩展提交官方审核,至少要做到下面几点:
- 扩展代码在包”flask_myext”下,审核通过后,Flask会设置一个重定向包”flask.ext.myext”来指向你的包。对于用户来说,官方扩展建议导入”flask.ext.myext”格式的包
- 必须提供一个”setup.py”分发文件,并在PyPI上注册,这样用户就可以通过”pip install”来安装你的扩展
- 必须提供”LICENSE”文件,并且授权是BSD, MIT或WTFPL
- 必须提供”README”文件及文档,文档是由Sphinx生成
- 必须同时提交单元测试代码
- 必须支持Python 2.6和2.7版本
转载于:https://www.cnblogs.com/Erick-L/p/7061669.html
Flask 扩展 自定义扩展相关推荐
- VS Code 安装 Go 插件、自定义扩展配置、断点调试
1. 安装插件 使用快捷键 Ctrl+Shift+X 打开插件安装页面,安装 Go 插件. 2. 自定义扩展配置 使用快捷键 Ctrl+, 打开自定义配置页,编辑 settings.json ,定义与 ...
- 2022还在使用Mysql进行数据检索?ElasticSearch自定义扩展词库完成检索
文章目录 1.为什么要自定义扩展ES词库呢? 2.如何自定义扩展词库呢? 3.Docker安装Nginx 4.在nginx中保存一个简易词库 5.修改IK分词器的配置文件,让其指向nginx保存的词库 ...
- python interpreter 中没有torch_PyTorch扩展自定义PyThon/C++(CUDA)算子的若干方法总结
在做毕设的时候需要实现一个PyTorch原生代码中没有的并行算子,所以用到了这部分的知识,再不总结就要忘光了= =,本文内容主要是PyTorch的官方教程的各种传送门,这些官方教程写的都很好,以后就可 ...
- class ts 扩展方法_JUnit 5自定义扩展
前言 在org.junit.jupiter.api.extension包下,JUnit5提供了丰富的扩展接口,通过实现这些接口,我们可以定制自己的扩展并注册到JUnit中来实现功能扩展. Extens ...
- SharePoint 2013 自定义扩展菜单(二)
转载自:http://www.cnblogs.com/jianyus/p/3376075.html 包含另外三个例子,列表设置.管理中心.人员和组添加菜单 接博文<SharePoint 2013 ...
- Nacos自定义扩展的 Data Id 配置
Spring Cloud Alibaba Nacos Config可支持自定义 Data Id 的配置. 一个完整的配置案例如下所示: 下边我们在service2微服务下配置扩展. spring:ap ...
- Django扩展自定义manage命令
使用django开发,对python manage.py ***命令模式肯定不会陌生.比较常用的有runserver,migrate... 本文讲述如何自定义扩展manage命令. 1.源码分析 ma ...
- ETL作业调度软件TASKCTL自定义扩展作业类型插件安装
TASKCTL批量自动化调度作业类型扩展插件的安装方法如下几种: 1. 直接覆盖法 直接覆盖法的意思就是将自定义扩展好的插件,通常是一个shell脚本,上传至后台调度核心服务上,然后修改后台任务类型的 ...
- 使用C#为.NET Interactive开发自定义扩展
在前面的文章中,我们介绍了如何在.NET Interactive notebook绘制图表和执行SQL. 那么,能不能为.NET Interactive开发交互功能呢? 今天,我们就来演示如何实现. ...
- ASP.NET 3.5核心编程学习笔记(55):自定义扩展程序控件的创建
ASP.NET并没有包含对扩展程序的具体实现.然而,它定义了供所有自定义扩展程序和ACT中所有扩展程序使用的基类ExtenderControl.我们可通过该类创建自己的扩展程序.但并不建议这样做,因为 ...
最新文章
- 引入外部css_css
- AI在管理临床试验设计和执行中,人和机器还在学习曲线上?
- 数据库mongodb和mysql对比
- SAP实施不成功就像女人丰乳没效果
- JavaScript操作DOM元素
- python中扑克牌类设计_Python类的基础设计、使用
- Vue生命周期详解 对应代码解析
- 计算机应用技术研究生开题报告,计算机应用技术专业论文开题报告.doc
- 【长沙集训】2017.10.28
- DynamicFusion: Reconstruction and Tracking of Non-rigid scenes in real-time
- Dynamics 365Online 模板(Template)可以下载了
- BUUCTF misc 解题记录 一(超级详细)
- AHCI和IDE的区别,如何在AHCI模式下安装系统
- 基于层次分析法(AHP)的信贷案例详解
- DBF文件初步了解(二)——DBF数据导出代码实现
- 无线渗透(下)—企业级WPA破解
- ios系统脚本服务器加速,让iOS系统加速飞起来 speed intensifier插件让iOS系统加速
- 小白编译AnyQ-dockerlinux[CentOs]——AnyQ系列之一
- 道一时间转换工具发布
- POE受电设备(PD)电路工作原理