Inside Flask - flask.__init__.py 和核心组件

简单的示例

首先看看一个简单的示例。使用 Flask ,通常是从 flask 模块导入 Flask 、 request 等等组件。一个简单的示例如下:

from flask import Flask
app = Flask(__name__)
app.config.update(DEBUG=True) @app.route('/')
@app.route('/index')
def index():
return '<h1>Hello, world!</h1>' if __name__ == '__main__':
app.run()

这个简单示例只使用到 Flask 中的核心 Flask 对象,以及 Flask 的 route 机制,就能简单地提供一个显示 Hello, world! 字符串的 index 页面。其它更加复杂的结构和使用模式,都会基于类似的简单例子进行扩展,以满足一些特定场景的要求。

flask.__init__.py

除了 Flask 类,在 flask 模块里面还包含了其它 Flask 里的核心组件,打开这个源文件,可看到它里面包括:

  • abort

    werkzeug.exceptions 导入,调用时直接抛出异常。它的本质是 werkzeug.exceptions 里面的 Aborter() 对象。

    Aborter 使用工厂模式。其内部使用一个 dict 类型的 mapping 成员变量来保存从 http 状态码到 werkzeug.exceptions 中定义的所有异常类之间的一个映射,然后通过一个 magic 方法 __call__ 创建并抛出异常。

    所有的异常的基类为 HTTPException 。它包含了两个基本的成员,codedescription,分别表示中止时的 http 状态码和要返回给用户的信息。

    异常类定义完后,通过一个函数 _find_exceptions 把所有在这里定义的异常类,放入到 default_exceptions 这个 dict 全局变量中。Abort 的初始化函数默认用 default_exceptions 作为 mapping 的值。

    abort 支持的状态码包括 400 / 401 / 403 / 404 / 405 / 406 / 408 / 409 / 410 / 411 / 412 / 413 / 414 / 415 / 416 / 417 / 418 / 422 / 428 / 429 / 429 / 431 / 500 / 501 / 502 / 503 / 504/ 505 。

    使用示例:

      @app.route('/_404')
    def _404()
    abort(404, 'Oops, 404.')
  • redirect

    werkzeug.utils 导入的重定向函数,通常与 url_for 结合使用。

    redirect 生成一个 Response 对象,默认以 302 状态码返回响应。其响应的模板内容为(其中 escape 为 URL 转义函数):

      '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">\n'
    '<title>Redirecting...</title>\n'
    '<h1>Redirecting...</h1>\n'
    '<p>You should be redirected automatically to target URL: '
    '<a href="%s">%s</a>. If not click the link.' %
    (escape(location), display_location), code, mimetype='text/html'

    可见,当浏览器不支持 302 状态码自动重定向时,可通过点击响应的 html 中的链接进行跳转。

    使用示例:

      @app.route('/_redirect')
    def _redirect()
    return redirect(url_for('.index'))
  • Markup 和 escape

    这两个都是从 Jinja2 中导入,实际由另外一个模块 markupsafe 实现。 Markupmarkupsafe模块的 __init__.py 中,是对文本的一个封装,对字符串进行安全的转义,从而能方便地使用到 html 和 xml 中。 Markup 的实现过程中,使用到 escape 函数帮助转义。

    escape 的实现其实很简单,就是把 html 中的预留字符转换为实体,代码如下:

      return Markup(text_type(s)
    .replace('&', '&amp;')
    .replace('>', '&gt;')
    .replace('<', '&lt;')
    .replace("'", ''')
    .replace('"', '"')
    )

    就是把 & > < ' " 这几个字符转换为实体。

    使用示例:

      Markup('<h1>%s<h1>') % '<h1>Hello, world!<h1>'
    # 结果为 Markup('<h1>&lt;h1&gt;Hello, world!&lt;h1&gt;<h1>')
  • Flask Request Response

    这 3 个类从 flask.app 中导入(使用了当前相对位置导入 from .app import ...)。

    Flask 是整个 Flask 框架的核心类,它实现了 WSGI 的应用接口,提供路由、模板解析、日志、异常管理等等核心功能。

    RequestResponse 分别是对请求和响应的数据的包装,实际的代码在 flask.wrappers 中。它们继承 werkzeug.wrappers 里面的请求和响应类,根据 Flask 的设计概念的需要进行了扩展。

    后续深入分析这 3 个类

    使用示例:

      from flask import Flask, Response, request
    
      app = Flask(__name__)
    
      @app.route('/')
    def index():
    method = request.method
    return Response('Request method: %s' % method) if __name__ == '__main__':
    app.run()
  • 辅助函数 url_for flash send_file, send_from_directory

    这堆辅助函数从 flask.helpers 中导入,包括:

      url_for, flash, send_file, send_from_directory,
    get_flashed_messages, get_template_attribute, make_response, safe_join,
    stream_with_context

    后续深入分析这些函数

  • 上下文全局对象代理 current_app g request

    这些对象从 flask.globals 导入,在当前上下文环境中起作用,包括:

      current_app, g, request, session, _request_ctx_stack,
    _app_ctx_stack

    上下文模式是 web 框架中经常会使用到的模式,它表示当前会话、请求、应用的执行环境,是当前代码执行时所能使用到的变量、函数等等。不同的用户通常使用不同的上下文环境,通过相互隔离上下文环境提供一定的安全特性。上下文还与特定的实现技术有关,线程、协程会使用不同的实现方法,有时在不同的系统中会有需要注意的细节。

    在实践中遇到的一些问题,特别是与 Flask 扩展有关的问题,很多是与上下文不对有关。

    注意,current_app g request session 均是 LocalProxy,在运行时通过查找函数加载真正的对象。

    后续深入分析 flask.globals

  • 上下文处理 has_request_context has_app_context after_this_request copy_current_request_context

    这些函数和组件从 flask.ctx 导入,辅助处理上下文。

    flask.ctx 中还定义了 ApplcaitonContextRequestContext 两个上下文类。

    RequestContext 包含请求时的信息,在请求开始时创建,在请求结束后清理。

    ApplicationContext 包含应用的信息,绑定到当前的线程和协程上。当 RequestContext 发现没有 ApplicationContext 时,也会自动隐式创建一个(在 RequestContext.push() 中)。

    后续深入分析。

  • Module 和 Blueprint

    分别从 flask.moduleflask.blueprints 导入,是 Flask 的扩展机制。根据 Module 中的注释,这种方式已经过时,被 Blueprint 取代。

      .. versionchanged:: 0.7
    Modules were deprecated in favor for blueprints.

    Blueprint 是 Flask 中的主要模块化扩展方法。在编写大规模的应用时,可划分功能为多个 Blueprint,每个 Blueprint 完成特定任务。

    使用示例:

      task_bp = Blueprint('task')
    app.register_blueprint(task_bp, url_prefix='/task')

    后续深入分析。

  • 视图渲染 render_template render_template_string

    这两个函数从 flask.templating 导入,完成模板的渲染工作。

    使用示例:

      # 模板文件 templates/index.html
    <h1>{{ content }}</h1> # 视图渲染代码
    @app.route('/')
    def index():
    return render_template('index.html', content='Hello, world!')

    后续深入分析。

  • 内部信号 signals_available template_rendered request_started 等等

    Flask 提供信号机制,当某些操作发生时,通过信号方式通知其它代码,方便在这些操作发生时进行进一步处理。

    现有的信号包括:

      signals_available, template_rendered, request_started,
    request_finished, got_request_exception, request_tearing_down,
    appcontext_tearing_down, appcontext_pushed,
    appcontext_popped, message_flashed

    信号机制使用 blinker ,如果要自定义信号,需要额外安装这个模块。

  • json 支持 jsonify

    通过 json 方式进行响应。

    使用示例:

      return jsonify([1,2,3,4])
  • Session

    Session 对象,实际类型为 'flask.sessions.SecureCookieSession',需要结合 SecureCookieSessionInterface 一起使用。

    它可以用来定制 Flask 的 Session 保存方式,可放入到数据库或者 redis 里面,实现跨服务器的 session 共享。session 共享后,可通过服务器集群提升整个应用的访问处理能力。

    官方文档有一个使用 redis 实现的 server-side session http://flask.pocoo.org/snippets/75/

    后续深入分析。

总结

以上已列出 Flask 里面的关键组件和概念,如果掌握这部分的概念,则使用 Flask 的过程中所遇到的问题基本能自己动手调试和解决。刚接触像上下文、信号机制、server-side session 等概念时会存在疑惑,这些概念需要理解源代码后,实际编程使用的过程中会慢慢熟悉。

后续的文章围绕上述概念展开,并探索 Flask 如何设计和实现这些概念,在整个实现过程中学习 Flask 的优秀设计。

Inside Flask - flask.__init__.py 和核心组件的更多相关文章

  1. Flask源码阅读-第二篇(flask\__init__.py)

    源码: # -*- coding: utf-8 -*-""" flask ~~~~~ A microframework based on Werkzeug. It's e ...

  2. Inside Flask - flask 扩展加载过程

    Inside Flask - flask 扩展加载过程 flask 扩展(插件)通常是以 flask_<扩展名字> 为扩展的 python 包名,而使用时,可用 import flask. ...

  3. Inside Flask - Flask 简介

    Inside Flask - Flask 简介 前言 Flask 的设计目标是实现一个 wsgi 的微框架,其核心代码保持简单和可扩展性,很容易学习.对于有一定经验初学者而言,跟着例子和一些书的代码来 ...

  4. flask中manage.py的用法

    flask中manage.py的用法#!/usr/bin/env pythonimport osfrom app import create_app, dbfrom app.models import ...

  5. Flask - Flask的蓝图(BluePrint)

    目录 Flask - Flask的蓝图(BluePrint) 一. 初始Flask蓝图 进阶Flask蓝图 使用蓝图做一个增删改查 1.使用蓝图进行web应用搭建: 2.使用Flask蓝图,查看学生信 ...

  6. day92:flask:flask简介&基本运行&路由&HTTP请求和响应

    目录 1.Flask简介 2.关于使用flask之前的准备 3.flask的基本运行 4.flask加载配置 5.传递路由参数(没有限定类型) 6.传递路由参数(通过路由转换器限定路由参数的类型) 7 ...

  7. [python][flask] Flask 入门(以一个博客后台为例)

    目录 1.安装 1.1 创建虚拟环境 1.2 进入虚拟环境 1.3 安装 flask 2.上手 2.1 最小 Demo 2.2 基本知识 3.解构官网指导 Demo 3.1 克隆与代码架构分析 3.2 ...

  8. [python][flask] Flask 图片上传与下载例子(支持漂亮的拖拽上传)

    目录 1.效果预览 2.新增逻辑概览 3.tuchuang.py 逻辑介绍 3.1 图片上传 3.2 图片合法检查 3.3 图片下载 4.__init__.py 逻辑介绍 5.upload.html ...

  9. python三大web框架Django,Flask,Flask,Python几种主流框架,13个Python web框架比较,2018年Python web五大主流框架

    Python几种主流框架 从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python We ...

随机推荐

  1. 不用逗号进行UNION

    ./download.php ...if($link){    //加密后ID$link = base64_decode(urldecode($link));$link_array = explode ...

  2. 【iCore、iCore2、iBoard例程】【异步FIFO跨时钟域通信(通过ARM 读FPGA FIFO)】

    欢迎访问电子工程师学堂,以便了解更多内容:http://www.eeschool.org 一.本实验基于iCore2 完成,通过简单改动,即可用在 iCore 核心板.iBoard 电子学堂上. iC ...

  3. visual studio 中使用的插件介绍

    Highlight all occurrences of selected word 高亮代码 Indent Guides 代码的开头结尾连接竖线..是代码更清洗 PHP Tools for visu ...

  4. PHP常用正则表达式汇总

    1.    平时做网站经常要用正则表达式,下面是一些讲解和例子,仅供大家参考和修改使用: 2.    "^\d+$" //非负整数(正整数 + 0) 3.    "^[0 ...

  5. typecho流程原理和插件机制浅析(第一弹)

    typecho流程原理和插件机制浅析(第一弹) 兜兜 393 2014年03月28日 发布 推荐 5 推荐 收藏 24 收藏,3.5k 浏览 虽然新版本0.9在多次跳票后终于发布了,在漫长的等待里始终 ...

  6. PHP文件操作 之读取一个文件(以二进制只读的方式打开)

    最近应用了文件的读取,顺便复习一下! //读取一个文件 $f = fopen($filename,'rb'); $f: 表示返回的一个资源句柄 $filename:要打开的文件路径 rb:参数,表示只 ...

  7. Apache查看并发及TIME_WAIT过多的解决

    1.查看并发#ps -ef | grep httpd -c2.查看并发数及tpc连接状态netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) pri ...

  8. P1092 虫食算 NOIP2002

    为了测试stl 30分的暴力写法... #include <bits/stdc++.h> using namespace std; const int maxn = 11; int n; ...

  9. EFDC主控文件efdc.inp文件的xml格式化处理——转载http://blog.sina.com.cn/s/articlelist_1584892573_0_1.html

    在对EFDC模型进行系统集成时,虽然可以通过一行一行读来进行解析处理,但那将是一个繁琐的工作.我们经过xml格式化处理后,再经xsd转成Dataset类对象,那么整个主控文件就是一个数据库表集合,对其 ...

  10. CAS实践笔录

    下载CAS 本文下载的是cas-server-4.0.0-release 下载地址: https://www.apereo.org/cas/download 导入Eclipse测试 Import -& ...