1660260240
The goal of this post is to provide clarity on how the Application and Request contexts work in Flask.
Source: https://testdriven.io
1668682800
The goal of this post is to provide clarity on how the Application and Request contexts work in Flask.
By the end of this post, you should be able to explain:
current_app
, test_request_context
, and test_client
with the correct contextsYou 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().
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.
When a request is received, Flask provides two contexts:
Context | Description | Available Objects |
---|---|---|
Application | Keeps track of the application-level data (configuration variables, logger, database connection) | current_app , g |
Request | Keeps 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.
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'
>>>
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.
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
To summarize, use the following objects in view functions, CLI commands, and test functions:
Object | Context | Common Error | Solution |
---|---|---|---|
current_app | Application Context | Working outside of application context | with app.app_context(): |
g | Application Context | Working outside of application context | with app.test_request_context('/'): |
request | Request Context | Working outside of request context | with app.test_request_context('/'): |
session | Request Context | Working outside of request context | with app.test_request_context('/'): |
The following methods should be utilized during testing:
Flask Method | Description |
---|---|
test_client | Test client for the Flask app |
test_request_context | Push Request Context for Testing |
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:
Original article source at: https://testdriven.io/
1622190649
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
1660077480
This article explores how the Application and Request contexts work in Flask.
Source: https://testdriven.io
1660260240
The goal of this post is to provide clarity on how the Application and Request contexts work in Flask.
Source: https://testdriven.io
1631911080
Learn how the Application and Request contexts work in Flask (Advanced)
By the end of this post, you should be able to explain:
current_app
and request
proxies in view functions