Foreword
Flask is by far my favorite a Python Web framework, in order to better achieve its internal control mechanism, this two-day ready to learn at the source Flask, the Deep and share with you the next, which Flask version 1.1.1 .
Flask series:
text
This article will look at how the combination of source tracking Flask is a service up and running.
First, we continue to affix the simplest application:
from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello_world():
return 'Hello Flask!'
if __name__ == '__main__':
app.run()
We see this code to initialize the Flask class and app points, and then do run () to start the program.
View the run method:
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
First, the parameters:
parameter | Explanation |
---|---|
host | Server address, then do not set the default to 127.0.0.1 |
port | Port, then do not set the default is 5000 |
debug | Whether the debug mode, the default is no |
load_dotenv | Set Environment Variables |
options |
The processing flow of the method is: After the process configuration parameters, perform the werkzeug run_simple () method,
run_simple will start a WSGI service.
About WSGI protocol:
- It is about a bridge HTTP server and Web applications, defines a standard interface to enhance portability across Web applications, is a set of interactive interface specification.
- Its function is to monitor the specified port service, the request from the HTTP server resolves to WSGI format, call Flask app to process the request.
inner method run_simple is the core, inner calling make_server (). serve_forever () to start the service. About 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 returns based on the number of processes or threads corresponding WSGI server returns BaseWSGIServer By default, ThreadedWSGIServer and ForkingWSGIServer integrates a BaserWSGIServer, then we look serve_forever () method:
def serve_forever(self):
self.shutdown_signal = False
try:
HTTPServer.serve_forever(self)
except KeyboardInterrupt:
pass
finally:
self.server_close()
The final call to the Python standard library interfaces HTTPServer of serve_forever () method, while HTTPServer is a subclass of socketserver.TCPServer to monitor service through 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
The above is a Flask service to start the process.