Flask a source code analysis: service starts

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:

  1. On the Development Flask

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:

  1. 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.
  2. 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.

Guess you like

Origin www.cnblogs.com/ybjourney/p/11717347.html