• 自建扩展介绍

    • Flask扩展分两类

      1. 纯功能, 如: Flask-Login 提供用户认证
      2. 对已有的库和工具包装(简化继承操作,并提供有用的功能,更方便)

        如: Flask-SQLAlchemy 包装了 SQLAlchemy
    • 涉及的 python 包
      1. setuptools
      2. wheel
      3. twine: 发布python 包 (发布到 PyPI 后才能使用 pippipenv 安装)
      4. readme_renderer: 将 mdrsttxt 文本 渲染成.html
    • 命名:
      1. 扩展的名称: Flask-<功能/第三方库名> 或 <功能/第三方库名>-Flask
      2. 扩展的包名: flask_<功能/第三方库名> (小写加下划线)
  • 扩展类实现

    • 编写扩展类(以 Flask-Share 为例)

      • 使用扩展步骤: 导入扩展类 - 实例化 - 传入 app 初始化
        1. from flask_share import Share
        2. share = Share() # extensions.py 中统一实例化所有扩展
        3. share.init_app(app) # 在工厂函数中统一初始化所有扩展
        4. # 也可以一步到位
        5. # share = share(app)
      • 新建扩展类 (flask_share/__init__.py)
        1. class Share(object):
        2. def __inti__(self, app=None):
        3. self.init_app(app)
        4. def init_app(self, app):
        5. # 兼容 0.7 以前版本
        6. if not hasattr(app, 'extensions'):
        7. app.extensions={}
        8. # 在 app 应用中存储所有扩展实例, 可验证扩展是否完成实例化
        9. app.extensions['share'] = self
        10. # 扩展类添加到模板上下文中
        11. app.jinja_env.globals['share'] = self
        12. # app.context_processor(lambda:{'share': self})
        13. # 扩展配置, 初始化后添加到 app.config 中, 以 SHARE_ 开头避免冲突
        14. app.config.setdefault('SHARE_SITES', 'weibo,wechat,douban,facebook,twitter,google,linkedin,qq,qzone')
        15. app.config.setdefault('SHARE_MOBILESITES','weibo,douban,qq,qzone')
        16. app.config.setdefault('SHARE_HIDE_ON_MOBILE', False)
        17. app.config.setdefault('SHARE_SERVER_LOCAL', False) # 是否使用内置资源
    • 实现扩展功能
      • 加载静态资源
        1. class Share(object):
        2. @staticmethod
        3. def load(css_url=None, js_url=None):
        4. if current_app.config('SHARE_SERVE_LOCAL'):# 使用本地进入条件
        5. css_url = url_for('share.static', filename='css/share.min.css')
        6. js_url = url_for('share.static', filename='js/share.min.js')
        7. if css_url is None:
        8. css_url = 'https://cdn.bootcss.com/social.share.js/1.0.16/css/share.min.css'
        9. if js_url is None:
        10. js_url = 'https://cdn.bootcss.com/social-share.js/1.0.16/js/social-share.min.js'
        11. return Markup('''<link rel="stylesheet" href="%s">\n
        12. <script src="%s"></script>'''% (css_url, js_url))
        13. def init_app(self, app):
        14. # app.static_url_path 的引用是为了和用户设置一致
        15. blueprint = Blueprint('share', __name__, static_folder='static',
        16. static_url_path='/share'+ app.static_url_path)
        17. app.register_blueprint(blueprint)
      • 创建前端分享组件
        1. class Share(object):
        2. @staticmethod
        3. def create( title='', sites=None, mobile_sites=None,align='left',addtion_class=''):
        4. if sites is None:
        5. sites = current_app.config['SHARE_SITES']
        6. if mobile_sites is None:
        7. mobile_sites = current_app.config['SHARE_MOBILE_SITES']
        8. return Markup('''
        9. <div class="social-share %s" data-sites="%s" data-mobile-site="%s"align="%s">
        10. %s</div>'''%(addition_class, sites, mobile_sites,align, title ))
      • 在模板中使用
        1. {{ share.create('分享到:') }}
  • 开源发布准备

      1. 添加文档字符串与注释后的完整代码
      1. """
      2. Flask-Share
      3. # ~~~~~~~~~~~~~~
      4. Create social share component in Jinja2 tempalte based on share.js.
      5. :copyright: (c) 2017 by Gavin Li.
      6. :license: MIT, see LICENSE for more details.
      7. """
      8. import re
      9. from flask import current_app, url_for, Markup, Blueprint, request
      10. class Share(object):
      11. @staticmethod
      12. def load(css_url=None, js_url=None):
      13. """ Load share.js resourse.
      14. :param css_url: if set, will be used as css url
      15. :param js_url: if set, will be used as js url
      16. :param serve_local: if set to True, the local resource will be used
      17. """
      18. @staticmethod
      19. def create( title='', sites=None, mobile_sites=None,align='left',addtion_class=''):
      20. """ Create a share component.
      21. :param title: the prompt displayed on the left of the share component.
      22. :param sites: a string that consist of sites, separate by comma.
      23. :param mobile_sites: a string that consist of sites, separate by comma.
      24. supported site name: weibo, wechat, douban, facebook, twitter, google, linkedin, qq, qzone."
      25. for example: weibo,wechat, qq.
      26. :param mobile_sites: the sites displayed on mobile.
      27. :param align: the align of the share component,default to '`left`'.
      28. :param addition_class: the style class added to the share component.
      29. """
      1. 编写 README 与文档
      • 小项目 直接用 README概括所有的必需的说明
      • 大项目 比较复杂的,多文件组织文档内容

        将项目部署到 Read the Docs

        Sphinx + Github + Readthedocs的工作流编写和部署文档
      1. 定义 python 包的元数据:(setup.py)
      1. """
      2. Flask-Share
      3. Create social share component in Jinja2 template based on share.js.
      4. :copyright: (c) 2022 by Gavin li.
      5. :license: MIT, see LICENSE for more details.
      6. """
      7. form os import path
      8. from codecs import open
      9. form setuptools import setup
      10. basedir = path.abspath(path.dirname(__file__))
      11. # Get the long description from the README file
      12. with open(path.join(basedir,'README.md'), encoding='utf-8') as f:
      13. long_description = f.read()
      14. setup(
      15. name='Flask-Share', # 包名称
      16. version='0.1.0', # 版本
      17. url='https://github.com/lghpython/flask-share',
      18. license='MIT',
      19. author='xxx'
      20. author_email='xx@xx.com',
      21. description='xxx',
      22. long_description=long_description,
      23. long_description_content_type='text/markdown', # 默认渲染格式为 rst
      24. platforms='any',
      25. packages=['flask_share'], # 包含的包列表,包括子包,可用find_pakages()
      26. zip_safe=False,
      27. test_suite='test_flask_share', 测试包或模块
      28. include_package_data=True,
      29. install_requires=['Flask'], # 安装依赖
      30. keywords='flask extension development', # 项目关键词
      31. classifiers=[ # 分类词, 在 PyPI 中设置分类
      32. 'DevelopmentStatus::3-Alpha',
      33. 'Environment::WebEnvironment',
      34. 'IntendedAudience::Developers',
      35. 'License::OSIApproved::MITLicense',
      36. 'ProgrammingLanguage::Python',
      37. 'ProgrammingLanguage::Python::2',
      38. 'ProgrammingLanguage::Python::2.7',
      39. 'ProgrammingLanguage::Python::3',
      40. 'ProgrammingLanguage::Python::3.3',
      41. 'ProgrammingLanguage::Python::3.4',
      42. 'ProgrammingLanguage::Python::3.5',
      43. 'ProgrammingLanguage::Python::3.6',
      44. 'Topic::Internet::WWW/HTTP::DynamicContent',
      45. 'Topic::SoftwareDevelopment::Libraries::PythonModules']
      46. ],
      47. )
      1. 指定打包其他文件: MANIFEST.in

        需要在 setup()方法中设置: include_package_data=True
      1. graft flask_share/static
      2. include LICENSE test_flask_share.py
      3. # exclude 用来排除匹配文件
      4. # recursive-include 递归匹配
      5. # recursive-exclude 递归排除匹配
      6. # graft 目录 包含目录下所有
      7. # prune 目录 配出目录下所有
      1. 编写单元测试
      1. import unittest
      2. from flask import Flask, render_template_string, current_app
      3. from flask_share import Share
      4. class ShareTestCase(unittest.TestCase):
      5. def setUp(self):
      6. self.mobile_agent={{'HTTP_USER_AGENT':'Mozilla/5.0(iPhone;CPUiPhoneOS9_1likeMacOSX)\
      7. AppleWebKit/601.1.46(KHTML,likeGecko)Version/9.0Mobile/13B143Safari/601.1'}}
      8. app = Flask(__name__)
      9. app.testing=True
      10. self.share=Share(app)
      11. @app.route('/')
      12. def index():
      13. return render_template_string('{{share.load() }}\n {{share.create() }}')
      14. # 推送上下文
      15. self.context=app.app_context()
      16. self.context.push()
      17. self.client - app.test_client()
      18. def tearDown(self):
      19. self.context.pop()
      20. def test_create_on_mobile(self):
      21. current_app.config['SHARE_HIDE_ON_MOBILE'] = True
      22. response = self.client.get('/', environ_base=self.mobile_agent)
      23. data = response.get_data(as_text=True)
      24. self.assertIn('social-share.min.js', data)
      25. self.assertNotIn('<div class="socail-share"', data))
      1. setup.cfg
  • 发布到 PyPI

    • 创建 PyPI 账号

      • 注册访问
      • 方便访问: 创建 .pypirc文件, 放置$HOME/.pypirc(win) 或~/.pypir(mac linux) 明文密码限制访问权限
        1. [distutils]
        2. index-servers=
        3. pypi
        4. [pypi]
        5. username: 用户名
        6. password: 密码
    • setuptools 打包
      • 创建 Source Distributions 包
        1. python setup.py sdist
      • 创建 Wheel 包
        1. python setup.py bdist_wheel
      • 合并命令
        1. python setup.py sdist bdist_wheel
    • twine 上传
      • 安装 twine
        1. pipenv install twine --dev
      • 上传
        1. twine upload dist/*
  • 编写良好的扩展

    • 命名规范(Flask-Foo 或 Foo-Flask)
    • 使用相对宽松的开源许可证(MIT/BSD)
    • 支持工厂模式(添加 initi_app() 方法)
    • 支持同时运行多程序实例( 使用 current_app 获取程序实例)
    • 包含 setup.py脚本,并列出所有安装依赖(必需)
    • 包含单元测试
    • 编写文档并在线发布
    • 上传到 PyPI

Flask 自建扩展的更多相关文章

  1. Flask 的 请求扩展 与 中间件

    Flask 的 请求扩展 与 中间件 flask 可以通过 扩展(装饰器)来实现类似于django 中间件的功能 类似于django 的中间件, 在执行视图函数之前, 之后的执行某些功能 1 @app ...

  2. Python flask 构建可扩展的restful apl☝☝☝

    Python flask 构建可扩展的restful apl☝☝☝ Flask-RESTful是flask的扩展,增加了对快速构建REST API的支持.Flask-RESTful通过最少的设置鼓励最 ...

  3. Python flask 构建可扩展的restful apl✍✍✍

    Python flask 构建可扩展的restful apl  整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感受,单论单个知识点课 ...

  4. flask 利用flask_wtf扩展 创建web表单

    在Flask中,为了处理web表单,我们一般使用Flask-WTF扩展,它封装了WTForms,并且它有验证表单数据的功能 创建语句格式: startTime = DateTimeField('计划开 ...

  5. Flask之邮件扩展

    4.4 Flask—Mail 在开发过程中,很多应用程序都需要通过邮件提醒用户,Flask的扩展包Flask-Mail通过包装了Python内置的smtplib包,可以用在Flask程序中发送邮件. ...

  6. flask 之(四) --- 扩展|缓存|会话

    扩展 蓝图内置扩展 (实现的是路由的拆分) '''----------- app.py -------------''' from flask import Flask from users_view ...

  7. Python flask 构建可扩展的restful ap

    Flask-RESTful是flask的扩展,增加了对快速构建REST API的支持. Flask-RESTful通过最少的设置鼓励最佳的实践. pip install flask-restfulFl ...

  8. Flask的请求扩展

    from flask import Flask,request app = Flask(__name__) 一.请求前 before_request 用法 @app.before_request de ...

  9. Chrome 33+ 自建 扩展 实现 custom.css

    http://bbs.kafan.cn/thread-1674386-1-2.html

随机推荐

  1. Jupyter Notebook 更改字体、字体大小、行高

    (废话):今天在做实验的时候遇到了一点问题,就问了问本科的室友,结果室友推荐我使用Jupyter Notebook来写代码,以前看其他同学使用过,但是一直在用Pycharm写,需要的时候顶多是Debu ...

  2. 【故障公告】数据库服务器 CPU 100% 引发全站故障

    今天 11:12-12:03 期间,园子使用的阿里云 RDS 实例(SQL Server2016 标准版,16核CPU)出现 CPU 100% 问题,引发全站故障,由此给您带来麻烦,请您谅解. 发现故 ...

  3. 看一遍就懂:MVCC原理详解

    MVCC实现原理也是一道非常高频的面试题,自己在整理这篇文章的时候,感觉到网上的资料在讲这块知识点上写的五花八门,好像大家的理解并没有一致. 这里将自己所理解的做一个总结,个人会觉得这是一篇含金量挺高 ...

  4. Spring与Struts2整合时action自动注入的问题

    当Struts和Spring框架进行整合时,原本由action实例化对象的过程移交给spring来做(这个过程依赖一个叫struts2-spring-plugin的jar包,这个包主要的功能就是实现刚 ...

  5. shell——并发工具parallel

    官方文档:https://www.gnu.org/software/parallel/parallel_tutorial.html 安装 (wget -O - pi.dk/3 || curl pi.d ...

  6. 帆软报表(finereport)雷达图钻取详细点新页面展示

    添加参数栏,季度下拉框的空间名为combobox0 添加雷达图,通过第三页面做跳转 雷达图钻取.cpt为联动钻取的第三页面 添加纬度(所点击钻取的点) 参数   wd 添加季度参数 jd    值为季 ...

  7. 6、前端--DOM操作(查找标签、节点操作、获取值操作、class操作、样式操作、绑定事件、内置参数this)

    DOM操作之查找标签 前缀关键字>>>:document # 基本查找(核心) document.getElementById 根据ID获取一个标签 document.getElem ...

  8. 编译安装&打包压缩&定时任务

    内容概要 编译安装 打包压缩 定时任务 内容详细 一.编译安装 1.特点 使用源代码,编译打包软件. ​ 1.可以自定制软件 ​ 2.按需构建软件啊 2.步骤 下载安装包 wget 下载网址 如果没有 ...

  9. uniapp 微信发送订阅消息

    这篇主要针对小程序进行演示,既然是发送消息,那么就有三个问题.发送什么内容,给谁发送,怎么发送!往下一条一条解决. 发送什么消息内容 - 通过微信公众号平台 选择对应的消息模板 选择以后在我的模板里面 ...

  10. Hyperledger Fabric 2.x 动态更新智能合约

    一.说明 在上一篇文章中分享了智能合约的安装与使用,如果业务有变更代码需要修改怎么办呢?本文分享如何对已安装的合约进行版本更新. 二.环境准备 区块链网络安装:<Hyperledger Fabr ...