How The Application and Request Contexts Work in Flask

The goal of this post is to provide clarity on how the Application and Request contexts work in Flask.

Source: https://testdriven.io

#flask 

What is GEEK

Buddha Community

How The Application and Request Contexts Work in Flask
Gordon  Taylor

Gordon Taylor

1668682800

Overview Of How The Application and Request Contexts Work in Flask

The goal of this post is to provide clarity on how the Application and Request contexts work in Flask.

Objectives

By the end of this post, you should be able to explain:

  1. How Flask handles the request object and how this differs from other web frameworks
  2. What the application and request context are
  3. Which data is stored in both the Application and Request contexts
  4. How to utilize current_app, test_request_context, and test_client with the correct contexts

You should also be able to fix the following error:

RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context().

Contexts in Flask

Unlike Django and other web frameworks, Flask view functions do not accept a request object that contains metadata about the HTTP request.

Django Example:

def users(request):
    if request.method == 'POST':
         # Save the form data to the database
         # Send response
   else:
         # Get all users from the database
         # Send response

With Flask, you import in the request object like so:

from flask import request

@app.route('/users', methods=['GET', 'POST'])
def users():
    if request.method == 'POST':
         # Save the form data to the database
         # Send response
    else:
         # Get all users from the database
         # Send response

In the Flask example, the request object looks, feels, and acts like a global variable, but it's not.

If the request object were a global variable, you wouldn't be able to run a multi-threaded Flask app since global variables are not thread-safe.

Instead, Flask uses contexts to make a number of objects "act" like globals only for the particular context (a thread, process, or coroutine) being used. In Flask, this is called a context-local.

Context locals are similar to but ultimately different than Python's thread-local implementation for storing data that is specific to a thread. Flask's implementation is more generic in order to allow for workers to be threads, processes, or coroutines.

Data Stored in Flask Contexts

When a request is received, Flask provides two contexts:

ContextDescriptionAvailable Objects
ApplicationKeeps track of the application-level data (configuration variables, logger, database connection)current_app, g
RequestKeeps track of the request-level data (URL, HTTP method, headers, request data, session info)request, session

It's worth noting that each of the above objects are often referred to as "proxies". This just means that they are proxies to global flavors of the objects. For more on this, check out the second post in this series.

Flask handles the creation of these contexts when a request is received. They can cause confusion as you don't always have access to a particular object depending on which state your application is in.

Let's look at a few examples.

Application Context Example

Assume you have the following Flask app:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return 'Welcome!'

if __name__ == '__main__':
    app.run()

First, let's look at how to work with the current_app object to access the Application context.

Within the Python shell, if you try to access the current_app.config object outside of a view function, you should see the following error:

$ python
>>> from flask import current_app
>>> current_app.config

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "werkzeug/local.py", line 347, in __getattr__
    return getattr(self._get_current_object(), name)
  File "werkzeug/local.py", line 306, in _get_current_object
    return self.__local()
  File "flask/globals.py", line 52, in _find_app
    raise RuntimeError(_app_ctx_err_msg)
RuntimeError: Working outside of application context.

This typically means that you attempted to use functionality that needed
to interface with the current application object in some way. To solve
this, set up an application context with app.app_context().  See the
documentation for more information.

To access objects exposed by the Application and Request contexts outside of a view function, you need to create the appropriate context first:

# without a context manager
$ python

>>> from app import app
>>> from flask import current_app
>>>
>>> app_ctx = app.app_context()
>>> app_ctx.push()
>>>
>>> current_app.config["ENV"]
'production'
>>> app_ctx.pop()
>>>
# with a context manager
$ python

>>> from app import app
>>> from flask import current_app
>>>
>>> with app.app_context():
...     current_app.config["ENV"]
...
'production'
>>>

Request Context Example

You can use the test_request_context method to create a request context:

# without a context manager
$ python

>>> from app import app
>>> from flask import request
>>>
>>> request_ctx = app.test_request_context()
>>> request_ctx.push()
>>>
>>> request.method
'GET'
>>>
>>> request.path
'/'
>>>
>>> request_ctx.pop()
>>>
# with a context manager
$ python

>>> from app import app
>>> from flask import request
>>>
>>> with app.test_request_context('/'):
...     request.method
...     request.path
...
'GET'
'/'
>>>

test_request_context is typically used during testing when you want to use request data without the overhead of a full request.

Testing Example

The most common time to run into issues with the Application and Request context is when your app is under test:

import pytest
from flask import current_app

from app import app


@pytest.fixture
def client():
    with app.test_client() as client:
        assert current_app.config["ENV"] == "production"  # Error!
        yield client


def test_index_page(client):
   response = client.get('/')

   assert response.status_code == 200
   assert b'Welcome!' in response.data

When run, the tests will fail in the fixture:

$ pytest
________________________ ERROR at setup of test_index_page _____________________

@pytest.fixture
def client():
    with app.test_client() as client:
>       assert current_app.config["ENV"] == "production"
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
    def _find_app():
        top = _app_ctx_stack.top
        if top is None:
>           raise RuntimeError(_app_ctx_err_msg)
E           RuntimeError: Working outside of application context.
E
E           This typically means that you attempted to use functionality that needed
E           to interface with the current application object in some way. To solve
E           this, set up an application context with app.app_context().  See the
E           documentation for more information.
================================= 1 error in 0.13s =================================

To fix, create an application context before accessing current_app:

import pytest
from flask import current_app

from app import app


@pytest.fixture
def client():
    with app.test_client() as client:
        with app.app_context():  # New!!
            assert current_app.config["ENV"] == "production"
        yield client


def test_index_page(client):
   response = client.get('/')

   assert response.status_code == 200
   assert b'Welcome!' in response.data

Summary

To summarize, use the following objects in view functions, CLI commands, and test functions:

ObjectContextCommon ErrorSolution
current_appApplication ContextWorking outside of application contextwith app.app_context():
gApplication ContextWorking outside of application contextwith app.test_request_context('/'):
requestRequest ContextWorking outside of request contextwith app.test_request_context('/'):
sessionRequest ContextWorking outside of request contextwith app.test_request_context('/'):

The following methods should be utilized during testing:

Flask MethodDescription
test_clientTest client for the Flask app
test_request_contextPush Request Context for Testing

Conclusion

This blog post just scratches the surface on the application and request contexts. Be sure to check out the second part in this series to learn more: Deep Dive into Flask's Application and Request Contexts

Check out the following course on how to build, test, and deploy a Flask application as well:

This is part one of a two-part series on Flask Contexts:

  1. Basics: Understanding the Application and Request Contexts in Flask (this article!)
  2. Advanced: Deep Dive into Flask's Application and Request Contexts

Original article source at: https://testdriven.io/

#flask #context 

Web development with python and flask: part 3

In this part of the series, we will be taking a look at the HTTP protocol, request/response objects, their application in flask, properties, and their related methods. We will take steps to import it from the flask module, use its properties, and look at some of its related usages

Web applications implement one of the internet data and message exchange architectures that is based on HTTP protocol. The HTTP protocol is just one of the many application layers of TCP/IP. The TCP/IP(Transmission Control Protocol/Internet Protocol) is used as a standard for transmitting data over networks. In simple terms, HTTP has rules, properties, and methods that implement the transmission of messages in form of hyperlinks over the communication structures enforced by the TCP/IP.

.You must know that the internet is based on connected physical computational devices over either copper wires, fiber optical cables, wireless, and other media to form data transmission and retrieval systems across the globe. Trust me, that is a whole career field in itself and we are not interested in its elaborate ramblings in this post.

#flask #web developemnt #flask #flask requests #webdevelopment

Audra  Haag

Audra Haag

1660077480

How The Application and Request Contexts Work in Flask

This article explores how the Application and Request contexts work in Flask.

Source: https://testdriven.io

#flask #python 

How The Application and Request Contexts Work in Flask

The goal of this post is to provide clarity on how the Application and Request contexts work in Flask.

Source: https://testdriven.io

#flask 

How The Application and Request Contexts Work in Flask (Advanced)

Learn how the Application and Request contexts work in Flask (Advanced)

By the end of this post, you should be able to explain:

  1. What a context is
  2. Which data is stored in both the Application and Request contexts
  3. The steps required for processing the Application and Request contexts when a request is handled in Flask
  4. How proxies to the Application and Request context are used
  5. How to utilize the current_app and request proxies in view functions
  6. What a context-local is

#flask #Python