前言

Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1。

Flask系列文章:

  1. Flask开发初探

正文

本文将结合源码跟踪看下Flask是如何启动并运行一个服务的。在0.11版本以后,支持命令行启动flask。

目前共有两种方式可以载入应用:

1. python app.py

首先,继续贴上最简单的应用app.py:

from flask import Flask
app = Flask(__name__) @app.route('/')
def hello_world():
return 'Hello Flask!' if __name__ == '__main__':
app.run()

执行python app.py即可启动。

我们看到,这段代码先初始化了Flask类并被app所指向,然后执行run()来启动程序的。

查看run方法:

def run(self, host=None, port=None, debug=None, load_dotenv=True, **options):
if os.environ.get("FLASK_RUN_FROM_CLI") == "true":
from .debughelpers import explain_ignored_app_run explain_ignored_app_run()
return if get_load_dotenv(load_dotenv):
cli.load_dotenv() # if set, let env vars override previous values
if "FLASK_ENV" in os.environ:
self.env = get_env()
self.debug = get_debug_flag()
elif "FLASK_DEBUG" in os.environ:
self.debug = get_debug_flag() # debug passed to method overrides all other sources
if debug is not None:
self.debug = bool(debug) _host = "127.0.0.1"
_port = 5000
server_name = self.config.get("SERVER_NAME")
sn_host, sn_port = None, None if server_name:
sn_host, _, sn_port = server_name.partition(":") host = host or sn_host or _host
# pick the first value that's not None (0 is allowed)
port = int(next((p for p in (port, sn_port) if p is not None), _port)) options.setdefault("use_reloader", self.debug)
options.setdefault("use_debugger", self.debug)
options.setdefault("threaded", True) cli.show_server_banner(self.env, self.debug, self.name, False) from werkzeug.serving import run_simple try:
run_simple(host, port, self, **options)
finally:
# reset the first request information if the development server
# reset normally. This makes it possible to restart the server
# without reloader and that stuff from an interactive shell.
self._got_first_request = False

首先入参:

参数 说明
host 服务器地址,不设置的话默认为127.0.0.1
port 端口,不设置的话默认为5000
debug 是否为调试模式, 默认为否
load_dotenv 从项目根目录下的.flaskenv.env文件中导入环境变量

该方法的处理流程是:对入参进行配置处理之后,执行werkzeug的run_simple()方法,

run_simple将启动一个WSGI服务。

关于WSGI协议:

  1. 它是关于HTTP服务器和Web应用的桥梁,定义了标准接口以提升Web应用之间的可移植性,是一套接口交互规范。
  2. 它的功能是监听指定端口服务,将来自HTTP服务器的请求解析为WSGI格式,调用Flask app处理请求。

run_simple中的inner方法是核心,inner调用make_server().serve_forever()启动服务。关于make_server:

def make_server(host=None, port=None, app=None, threaded=False, processes=1,
request_handler=None, passthrough_errors=False,
ssl_context=None, fd=None):
if threaded and processes > 1:
raise ValueError("cannot have a multithreaded and "
"multi process server.")
elif threaded:
return ThreadedWSGIServer(host, port, app, request_handler,
passthrough_errors, ssl_context, fd=fd)
elif processes > 1:
return ForkingWSGIServer(host, port, app, processes, request_handler,
passthrough_errors, ssl_context, fd=fd)
else:
return BaseWSGIServer(host, port, app, request_handler,
passthrough_errors, ssl_context, fd=fd)

make_server会根据线程或者进程数返回相应的WSGI服务器,默认情况下返回BaseWSGIServer,ThreadedWSGIServer和ForkingWSGIServer均集成了BaserWSGIServer,接下来我们看下serve_forever()方法:

def serve_forever(self):
self.shutdown_signal = False
try:
HTTPServer.serve_forever(self)
except KeyboardInterrupt:
pass
finally:
self.server_close()

最终调用了Python标准类库接口HTTPServer的serve_forever()方法,而HTTPServer又是socketserver.TCPServer的子类,通过server_bind来监听服务:

class HTTPServer(socketserver.TCPServer):

    allow_reuse_address = 1    # Seems to make sense in testing environment

    def server_bind(self):
"""Override server_bind to store the server name."""
socketserver.TCPServer.server_bind(self)
host, port = self.server_address[:2]
self.server_name = socket.getfqdn(host)
self.server_port = port

2. Flask命令

接下来我们通过flask命令来启动一个应用,hello.py:

from flask import Flask
app = Flask(__name__) @app.route('/')
def hello_world():
return 'Hello Flask!'

Unix Bash ( Linux 、Mac 及其他):

$ export FLASK_APP=hello
$ flask run

这样便启动了该 应用,那么内部的实现机理是怎样的呢?

  1. 设置环境变量Flask_APP,指定应用的路径
  2. 通过run命令来启动开发服务器,其中flask命令是由Flask安装的。

以上,就是Flask服务启动的流程。

Flask源码分析一:服务启动的更多相关文章

  1. Netty源码分析之服务启动

    本节主要分析server的启动过程. Netty是基于Nio实现的,所以也离不开selector.serverSocketChannel.socketChannel和selectKey等,只不过Net ...

  2. Flask源码分析二:路由内部实现原理

    前言 Flask是目前为止我最喜欢的一个Python Web框架了,为了更好的掌握其内部实现机制,这两天准备学习下Flask的源码,将由浅入深跟大家分享下,其中Flask版本为1.1.1. 上次了解了 ...

  3. zookeeper源码分析之五服务端(集群leader)处理请求流程

    leader的实现类为LeaderZooKeeperServer,它间接继承自标准ZookeeperServer.它规定了请求到达leader时需要经历的路径: PrepRequestProcesso ...

  4. zookeeper源码分析之四服务端(单机)处理请求流程

    上文: zookeeper源码分析之一服务端启动过程 中,我们介绍了zookeeper服务器的启动过程,其中单机是ZookeeperServer启动,集群使用QuorumPeer启动,那么这次我们分析 ...

  5. flask源码分析

    本flask源码分析不间断更新 而且我分析的源码全是我个人觉得是很beautiful的 1 flask-login 1.1 flask.ext.login.login_required(func),下 ...

  6. Tomcat源码分析之—具体启动流程分析

    从Tomcat启动调用栈可知,Bootstrap类的main方法为整个Tomcat的入口,在init初始化Bootstrap类的时候为设置Catalina的工作路径也就是Catalina_HOME信息 ...

  7. JVM源码分析之JVM启动流程

      原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 “365篇原创计划”第十四篇. 今天呢!灯塔君跟大家讲: JVM源码分析之JVM启动流程 前言: 执行Java类的main方法,程序就能运 ...

  8. 源码分析Dubbo服务消费端启动流程

    通过前面文章详解,我们知道Dubbo服务消费者标签dubbo:reference最终会在Spring容器中创建一个对应的ReferenceBean实例,而ReferenceBean实现了Spring生 ...

  9. [Abp vNext 源码分析] - 1. 框架启动流程分析

    一.简要说明 本篇文章主要剖析与讲解 Abp vNext 在 Web API 项目下的启动流程,让大家了解整个 Abp vNext 框架是如何运作的.总的来说 ,Abp vNext 比起 ABP 框架 ...

  10. 4. 源码分析---SOFARPC服务端暴露

    服务端的示例 我们首先贴上我们的服务端的示例: public static void main(String[] args) { ServerConfig serverConfig = new Ser ...

随机推荐

  1. BeanCopier类

    网上学习了一番BeanCopier类. cglib是一款比较底层的操作java字节码的框架. 下面通过拷贝bean对象来测试BeanCopier的特性: public class OrderEntit ...

  2. Winform中设置ZedGraph曲线图的水平与竖直参考线

    场景 Winforn中设置ZedGraph曲线图的属性.坐标轴属性.刻度属性: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10 ...

  3. Centos7 设置redis开机自启

    Centos7 设置redis开机自启 标签(空格分隔):Linux 环境 Centos7.1 redis-3.0.6 chkconfig方式 **service和chkconfig命令的功能好像都被 ...

  4. 《Java并发编程的艺术》读书笔记

    一.并发编程的挑战 上下文切换:cpu通过时间片分配算法来循环执行任务,当前任务执行一个时间片后会切换到下一个任务.但是,在切换前会保存上一个任务的状态,以便下次切换回这个任务时,可以再加载这个任务的 ...

  5. Spring Boot (五): Redis缓存使用姿势盘点

    1. Redis 简介 Redis 是目前业界使用最广泛的内存数据存储.相比 Memcached,Redis 支持更丰富的数据结构,例如 hashes, lists, sets 等,同时支持数据持久化 ...

  6. spring定时任务-文件上传进度条

    spring定时任务 导依赖 <!-- https://mvnrepository.com/artifact/org.quartz-scheduler/quartz --> <dep ...

  7. Mybaits-从零开始-Spring、Spring MVC、MyBatis整合(未万待续)

    Spring.Spring MVC.MyBatis整合(未万待续)

  8. 容器技术----------->Docker

    1. 虚拟化 1)什么是虚拟化 在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种 实体资源,如服务器.网络.内存及存储等,予以抽象.转换后呈现出来,打破实体 ...

  9. jQuery常用方法(三)-jQuery Ajax

    JQuery Ajax 方法说明: load( url, [data], [callback] ) 装入一个远程HTML内容到一个DOM结点. $("#feeds").load(& ...

  10. ES 32 - Elasticsearch 数据建模的探索与实践

    目录 1 什么是数据建模? 2 如何对 ES 中的数据进行建模 2.1 字段类型的建模方案 2.2 检索.聚合及排序的建模方案 2.3 额外存储的建模方案 3 ES 数据建模实例演示 3.1 动态创建 ...