Flask Http request - context, request hook

Posted by lulubell on Fri, 24 Dec 2021 04:11:29 +0100

Basic knowledge

Flask has two main dependencies

  1. WSGI (Web Server Gateway Interface) Toolset—— Werkzeug
  • WSGI (Web Server Gateway Interface) is a standard used in Python to specify how the web server communicates with Python Web programs
  • Werkzeug implements routing, debugging, and Web server gateway interfaces
  1. Jinja2 template engine
  • Jinja2 is responsible for the Html Template

Flash HTTP request

Request processing flow

  1. The user enters a URL in the browser to access a resource.
  2. Flask interprets HTTP requests into Python content through WSGI
  3. Flash executes the corresponding view function according to the requested URL, obtains the return value and generates a response
  4. The response is converted into HTTP response through WSGI in turn, and then passed to the browser through the Web server
  5. The browser receives and parses the response and displays the information in the page.

Flask context

There are two contexts in Flask

  • Request context

Request context contains

  1. Request: Flash wraps the request information in the request object, including Url, request method, Header, request parameters, etc., which can be obtained directly in the view function
  2. session 
  • Application context

Application context contains

  1. current_app: request the current application instance, including configuration information, etc
  2. g: the application context will be activated with the entry of each request, and will be destroyed at the end of each request, so g is only available in the current request, usually with before_request hook usage

The following examples show

@app.before_request
def set_name():
    g.name = 'my_name'

@app.route("/")
def hello_world():
    print(request.url)
    print(request.method)
    session["USERNAME"] = "test"
    print(session)
    print(current_app.secret_key)
    print(g.get('name'))
    return "<p>Hello, World!</p>"

visit http://127.0.0.1:5000/ , the output results are as follows

http://127.0.0.1:5000/

GET

<SecureCookieSession {'USERNAME': 'test'}>

miles-secret

my_name

How does the flash context work

  • The request context and application context are stored in the form of heap, respectively_ request_ctx_stack and_ app_ctx_stack
  • Flash through flash wsgi_ The app () method manages the context, and Flask creates the current request context after each request
  • After the current request context is created, use flash Push () method, respectively push to_ request_ctx_stack and_ app_ctx_stack, the specific steps are as follows:
  1. To prevent the previous request from abnormal termination, pop the top request context first
  2. If the application context is missing, create one first
  3. push the application context and request context into the corresponding stack successively
  4. Open session
  5. Match view by url

flask.push() method source code

  def push(self) -> None:
    """Binds the request context to the current context."""
    # If an exception occurs in debug mode or if context preservation is
    # activated under exception situations exactly one context stays
    # on the stack.  The rationale is that you want to access that
    # information under debug situations.  However if someone forgets to
    # pop that context again we want to make sure that on the next push
    # it's invalidated, otherwise we run at risk that something leaks
    # memory.  This is usually only a problem in test suite since this
    # functionality is not active in production environments.
        top = _request_ctx_stack.top
        if top is not None and top.preserved:
        	top.pop(top._preserved_exc)

        # Before we push the request context we have to ensure that there
        # is an application context.
        app_ctx = _app_ctx_stack.top
        if app_ctx is None or app_ctx.app != self.app:
            app_ctx = self.app.app_context()
            app_ctx.push()
            self._implicit_app_ctx_stack.append(app_ctx)
        else:
            self._implicit_app_ctx_stack.append(None)

        _request_ctx_stack.push(self)

        # Open the session at the moment that the request context is available.
        # This allows a custom open_session method to use the request context.
        # Only open a new session if this is the first time the request was
        # pushed, otherwise stream_with_context loses the session.
        if self.session is None:
            session_interface = self.app.session_interface
            self.session = session_interface.open_session(self.app, self.request)
            if self.session is None:
                self.session = session_interface.make_null_session(self.app)

        # Match the request URL after loading the session, so that the
        # session is available in custom URL converters.
        if self.url_adapter is not None:
            self.match_request()

Flash request hook

Through the request Hook, you can execute different functions at different request processing stages to preprocess and post process requests, such as processing database connections, printing logs, etc.

The Flask request hook includes:

  • before_ first_request: run before the first request
  • before_request: run before each request
  • after_request: run after each request, provided - no exception is thrown
  • teardown_request: run after each request, and after_ The difference of request is that it will be executed even if there is an exception thrown. If there is an exception, the exception object will be passed in as a parameter
  • after_this_request: it is registered in the view function and will only be executed after the view function

Topics: Python Flask