Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoSign in
Socket

flask

Package Overview
Dependencies
Maintainers
0
Versions
64
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

flask - pypi Package Compare versions

Comparing version
3.1.1
to
3.1.2
+15
docs/_static/flask-icon.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 500 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<rect id="Icon" x="0" y="0" width="500" height="500" style="fill:none;"/>
<clipPath id="_clip1">
<rect x="0" y="0" width="500" height="500"/>
</clipPath>
<g clip-path="url(#_clip1)">
<g>
<path d="M224.446,59.975c-0.056,-4.151 -0.483,-5.543 -2.7,-6.823c-2.104,-1.393 -5.288,-1.421 -8.329,-0.085l-204.674,87.64c-3.042,1.336 -5.913,4.008 -7.448,6.908c-1.535,2.899 -1.705,5.97 -0.511,8.158l17.084,31.384l0.228,0.369c1.847,2.928 6.026,3.696 10.29,1.82l1.251,-0.54c5.344,22.4 14.1,50.429 25.783,70.413l178.294,-79.794c-2.559,-23.14 -9.552,-89.602 -9.268,-119.479l0,0.029Z" style="fill:#3babc3;fill-rule:nonzero;"/>
<path d="M238.603,205.776l-171.698,76.838c10.091,19.132 22.542,39.428 37.722,58.986c50.429,-25.698 100.887,-51.396 151.316,-77.094c-3.269,-8.471 -6.452,-17.653 -17.34,-58.73Z" style="fill:#3babc3;fill-rule:nonzero;"/>
<path d="M497.601,388.846l-12.139,-18.535c-1.819,-2.018 -4.633,-2.786 -7.106,-1.791l-15.578,5.999c-1.848,-2.047 -4.52,-2.815 -7.135,-1.791c-5.089,1.99 -10.206,4.008 -15.294,5.998c-1.649,0.625 -2.104,1.847 -1.791,3.439l0.995,4.861c-28.711,3.099 -77.236,1.564 -120.701,-32.577c-19.216,-15.066 -37.239,-36.386 -52.277,-66.206l-144.75,73.768c26.466,29.08 59.697,54.864 100.973,70.385c57.422,21.633 130.593,23.679 222.838,-13.475l0.512,2.616c0.455,2.928 3.98,6.026 8.755,4.15l15.323,-5.97c5.258,-1.99 5.287,-6.026 4.519,-8.641l19.729,-7.704c2.217,-0.853 9.096,-6.169 3.183,-14.526l-0.056,-0Z" style="fill:#3babc3;fill-rule:nonzero;"/>
</g>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 500 500" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<rect id="Logo" x="0" y="0" width="500" height="500" style="fill:none;"/>
<g>
<path id="Box" d="M500,50l0,400c0,27.596 -22.404,50 -50,50l-400,0c-27.596,0 -50,-22.404 -50,-50l0,-400c0,-27.596 22.404,-50 50,-50l400,0c27.596,0 50,22.404 50,50Z" style="fill:url(#_Linear1);"/>
<path id="Shadow" d="M500,398.646l0,51.354c0,27.596 -22.404,50 -50,50l-94.111,0l-170.452,-170.451c13.541,12.279 29.511,22.845 48.242,29.888c34.453,12.98 78.356,14.208 133.703,-8.084l0.307,1.569c0.273,1.757 2.388,3.616 5.253,2.49l9.193,-3.582c3.156,-1.194 3.173,-3.616 2.712,-5.185l11.837,-4.622c1.331,-0.512 5.458,-3.701 1.91,-8.716l-0.034,0l-7.283,-11.12c-1.091,-1.211 -2.78,-1.672 -4.264,-1.075l-9.346,3.599c-1.109,-1.228 -2.712,-1.688 -4.281,-1.074c-3.054,1.194 -6.124,2.404 -9.177,3.598c-0.989,0.376 -1.262,1.109 -1.074,2.064l0.597,2.917c-17.227,1.859 -46.342,0.938 -72.421,-19.547c-11.53,-9.039 -22.343,-21.831 -31.366,-39.723l-83.923,42.769l-13.246,-10.755c30.258,-15.419 60.532,-30.837 90.79,-46.256c-1.961,-5.083 -3.872,-10.592 -10.404,-35.238l-98.082,43.893l-11.828,-11.828l106.976,-47.876c-1.534,-13.88 -5.728,-53.736 -5.56,-71.67l-0,-0.017c-0.027,-1.894 -0.184,-2.827 -0.85,-3.504l266.182,266.182Zm-388.562,-185.436c1.272,1.164 3.414,1.356 5.594,0.397l0.75,-0.324c0.645,2.703 1.373,5.543 2.181,8.452l-8.525,-8.525Z" style="fill:#3b808b;"/>
<g id="Icon">
<path d="M234.668,135.985c-0.034,-2.49 -0.29,-3.326 -1.62,-4.094c-1.263,-0.835 -3.173,-0.852 -4.998,-0.051l-122.804,52.584c-1.825,0.802 -3.548,2.405 -4.469,4.145c-0.921,1.74 -1.023,3.582 -0.307,4.895l10.251,18.83l0.136,0.222c1.109,1.757 3.616,2.217 6.175,1.091l0.75,-0.324c3.207,13.441 8.46,30.258 15.47,42.248l106.976,-47.876c-1.535,-13.884 -5.731,-53.761 -5.56,-71.687l-0,0.017Z" style="fill:#fff;fill-rule:nonzero;"/>
<path d="M243.162,223.466l-103.019,46.103c6.055,11.478 13.525,23.656 22.633,35.391c30.258,-15.419 60.532,-30.837 90.79,-46.256c-1.961,-5.083 -3.872,-10.592 -10.404,-35.238Z" style="fill:#fff;fill-rule:nonzero;"/>
<path d="M398.56,333.307l-7.283,-11.12c-1.091,-1.211 -2.78,-1.672 -4.264,-1.075l-9.346,3.599c-1.109,-1.228 -2.712,-1.688 -4.281,-1.074c-3.054,1.194 -6.124,2.404 -9.177,3.598c-0.989,0.376 -1.262,1.109 -1.074,2.064l0.597,2.917c-17.227,1.859 -46.342,0.938 -72.421,-19.547c-11.53,-9.039 -22.343,-21.831 -31.366,-39.723l-86.85,44.26c15.879,17.449 35.818,32.919 60.584,42.231c34.453,12.98 78.356,14.208 133.703,-8.084l0.307,1.569c0.273,1.757 2.388,3.616 5.253,2.49l9.193,-3.582c3.156,-1.194 3.173,-3.616 2.712,-5.185l11.837,-4.622c1.331,-0.512 5.458,-3.701 1.91,-8.716l-0.034,0Z" style="fill:#fff;fill-rule:nonzero;"/>
</g>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(3.06162e-14,500,-500,3.06162e-14,267.59,0)"><stop offset="0" style="stop-color:#bdddeb;stop-opacity:1"/><stop offset="1" style="stop-color:#53a9d1;stop-opacity:1"/></linearGradient>
</defs>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg width="100%" height="100%" viewBox="0 0 706 300" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" xmlns:serif="http://www.serif.com/" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linejoin:round;stroke-miterlimit:2;">
<g>
<path id="Name" d="M420.35,117.6l-37.65,-0c-4.4,-0 -7.475,0.85 -9.225,2.55c-1.75,1.7 -2.625,4.65 -2.625,8.85l-0,14.85l39.15,-0l-1.5,18.6l-37.65,-0l-0,43.35l-20.85,-0l-0,-85.05c-0,-7.9 1.725,-13.5 5.175,-16.8c3.45,-3.3 9.375,-4.95 17.775,-4.95l47.4,-0l0,18.6Z" style="fill-rule:nonzero;"/>
<path d="M455.75,205.8l-19.5,0.15l-0,-112.95l19.5,-0l-0,112.8Z" style="fill-rule:nonzero;"/>
<path d="M535.7,205.8l-13.05,-0l-6,-10.35l-20.85,11.25c-11.6,-0 -19.4,-4.2 -23.4,-12.6c-2,-4.1 -3.375,-8.525 -4.125,-13.275c-0.75,-4.75 -1.125,-9.7 -1.125,-14.85c-0,-5.15 0.05,-8.95 0.15,-11.4c0.1,-2.45 0.35,-5.3 0.75,-8.55c0.4,-3.25 0.975,-5.975 1.725,-8.175c0.75,-2.2 1.825,-4.475 3.225,-6.825c1.4,-2.35 3.1,-4.225 5.1,-5.625c4.5,-3.1 10.35,-4.65 17.55,-4.65l20.55,-0l19.5,-1.2l-0,86.25Zm-19.5,-27.3l-0,-40.2l-14.85,-0c-5.5,-0 -9.325,2.1 -11.475,6.3c-2.15,4.2 -3.225,10.475 -3.225,18.825c-0,8.35 1.025,14.225 3.075,17.625c2.05,3.4 5.925,5.1 11.625,5.1l14.85,-7.65Z" style="fill-rule:nonzero;"/>
<path d="M615.65,182.1l0,2.25c-0.6,7.5 -3.775,13.15 -9.525,16.95c-5.75,3.8 -12.925,5.7 -21.525,5.7c-12.7,-0 -21.6,-2.3 -26.7,-6.9c-4.7,-4.2 -7.05,-10.4 -7.05,-18.6l0,-1.8l17.7,0c0,4.6 1.2,7.75 3.6,9.45c2.4,1.7 6.55,2.55 12.45,2.55c8,0 12,-2.9 12,-8.7c0,-4.8 -1.4,-8 -4.2,-9.6c-1.3,-0.8 -2.95,-1.4 -4.95,-1.8l-15.15,-2.55c-13.2,-2.1 -19.8,-10.35 -19.8,-24.75c0,-8 2.925,-14.225 8.775,-18.675c5.85,-4.45 13.275,-6.675 22.275,-6.675c20.5,0 30.75,8.85 30.75,26.55l0,1.95l-16.95,0c-0.2,-4.7 -1.45,-7.9 -3.75,-9.6c-2.3,-1.7 -5.525,-2.55 -9.675,-2.55c-4.15,0 -7.275,0.825 -9.375,2.475c-2.1,1.65 -3.15,3.475 -3.15,5.475c0,5.7 2.3,8.95 6.9,9.75l18.15,3.3c12.8,2.4 19.2,11 19.2,25.8Z" style="fill-rule:nonzero;"/>
<path d="M705.65,205.8l-23.4,-0l-22.5,-30.3l-8.55,12.15l0,18.15l-19.5,-0l0,-112.8l19.5,-0l0,71.25l27.3,-40.65l22.05,-0l-28.05,38.4l33.15,43.8Z" style="fill-rule:nonzero;"/>
<g id="Logo">
<path id="Box" d="M300,30l0,240c0,16.557 -13.443,30 -30,30l-240,-0c-16.557,-0 -30,-13.443 -30,-30l0,-240c0,-16.557 13.443,-30 30,-30l240,0c16.557,0 30,13.443 30,30Z" style="fill:url(#_Linear1);"/>
<path id="Shadow" d="M300,239.188l0,30.812c0,16.557 -13.443,30 -30,30l-56.467,-0l-102.271,-102.271c8.125,7.368 17.707,13.707 28.945,17.933c20.672,7.788 47.014,8.525 80.222,-4.85l0.184,0.941c0.164,1.054 1.433,2.17 3.152,1.494l5.516,-2.149c1.893,-0.716 1.904,-2.169 1.627,-3.111l7.103,-2.773c0.798,-0.307 3.274,-2.221 1.146,-5.23l-0.021,0l-4.37,-6.672c-0.655,-0.727 -1.668,-1.003 -2.558,-0.645l-5.608,2.16c-0.665,-0.737 -1.627,-1.013 -2.569,-0.645c-1.832,0.716 -3.674,1.443 -5.505,2.159c-0.594,0.225 -0.758,0.665 -0.645,1.239l0.358,1.749c-10.336,1.116 -27.805,0.563 -43.452,-11.727c-6.918,-5.424 -13.406,-13.099 -18.82,-23.835l-50.354,25.662l-7.947,-6.453c18.154,-9.251 36.319,-18.502 54.474,-27.754c-1.177,-3.049 -2.323,-6.355 -6.243,-21.143l-58.849,26.336l-7.097,-7.096l64.186,-28.726c-0.921,-8.328 -3.437,-32.242 -3.336,-43.002l-0,-0.01c-0.016,-1.137 -0.111,-1.697 -0.51,-2.103l159.709,159.71Zm-233.137,-111.262c0.763,0.699 2.048,0.814 3.356,0.238l0.45,-0.194c0.387,1.622 0.824,3.325 1.309,5.071l-5.115,-5.115Z" style="fill:#3b808b;"/>
<g id="Icon">
<path d="M140.801,81.591c-0.021,-1.494 -0.174,-1.996 -0.972,-2.456c-0.758,-0.502 -1.904,-0.512 -2.999,-0.031l-73.683,31.551c-1.095,0.481 -2.128,1.443 -2.681,2.486c-0.552,1.044 -0.614,2.149 -0.184,2.937l6.151,11.298l0.081,0.133c0.666,1.055 2.17,1.331 3.705,0.655l0.45,-0.194c1.924,8.064 5.076,18.155 9.282,25.349l64.186,-28.726c-0.921,-8.33 -3.439,-32.257 -3.336,-43.012l-0,0.01Z" style="fill:#fff;fill-rule:nonzero;"/>
<path d="M145.897,134.079l-61.811,27.662c3.633,6.887 8.115,14.194 13.58,21.235c18.154,-9.251 36.319,-18.502 54.474,-27.754c-1.177,-3.049 -2.323,-6.355 -6.243,-21.143Z" style="fill:#fff;fill-rule:nonzero;"/>
<path d="M239.136,199.984l-4.37,-6.672c-0.655,-0.727 -1.668,-1.003 -2.558,-0.645l-5.608,2.16c-0.665,-0.737 -1.627,-1.013 -2.569,-0.645c-1.832,0.716 -3.674,1.443 -5.505,2.159c-0.594,0.225 -0.758,0.665 -0.645,1.239l0.358,1.749c-10.336,1.116 -27.805,0.563 -43.452,-11.727c-6.918,-5.424 -13.406,-13.099 -18.82,-23.835l-52.11,26.557c9.528,10.469 21.491,19.751 36.35,25.338c20.672,7.788 47.014,8.525 80.222,-4.85l0.184,0.941c0.164,1.054 1.433,2.17 3.152,1.494l5.516,-2.149c1.893,-0.716 1.904,-2.169 1.627,-3.111l7.103,-2.773c0.798,-0.307 3.274,-2.221 1.146,-5.23l-0.021,0Z" style="fill:#fff;fill-rule:nonzero;"/>
</g>
</g>
</g>
<defs>
<linearGradient id="_Linear1" x1="0" y1="0" x2="1" y2="0" gradientUnits="userSpaceOnUse" gradientTransform="matrix(1.83697e-14,300,-300,1.83697e-14,160.554,0)"><stop offset="0" style="stop-color:#bdddeb;stop-opacity:1"/><stop offset="1" style="stop-color:#53a9d1;stop-opacity:1"/></linearGradient>
</defs>
</svg>
+2
-2

@@ -61,4 +61,4 @@ import packaging.version

html_static_path = ["_static"]
html_favicon = "_static/shortcut-icon.png"
html_logo = "_static/flask-vertical.png"
html_favicon = "_static/flask-icon.svg"
html_logo = "_static/flask-logo.svg"
html_title = f"Flask Documentation ({version})"

@@ -65,0 +65,0 @@ html_show_sourcelink = False

Contributing
============
See the Pallets `detailed contributing documentation <_contrib>`_ for many ways
See the Pallets `detailed contributing documentation <contrib_>`_ for many ways
to contribute, including reporting issues, requesting features, asking or

@@ -6,0 +6,0 @@ answering questions, and making PRs.

@@ -99,6 +99,6 @@ Design Decisions in Flask

Flask decides on one template engine: Jinja2. Why doesn't Flask have a
Flask decides on one template engine: Jinja. Why doesn't Flask have a
pluggable template engine interface? You can obviously use a different
template engine, but Flask will still configure Jinja2 for you. While
that limitation that Jinja2 is *always* configured will probably go away,
template engine, but Flask will still configure Jinja for you. While
that limitation that Jinja is *always* configured will probably go away,
the decision to bundle one template engine and use that will not.

@@ -111,3 +111,3 @@

But that's about where similarities end. Jinja2 for example has an
But that's about where similarities end. Jinja for example has an
extensive filter system, a certain way to do template inheritance,

@@ -123,4 +123,4 @@ support for reusable blocks (macros) that can be used from inside

framework there is more than just rendering templates. For instance,
Flask uses Jinja2's extensive autoescaping support. Also it provides
ways to access macros from Jinja2 templates.
Flask uses Jinja's extensive autoescaping support. Also it provides
ways to access macros from Jinja templates.

@@ -156,3 +156,3 @@ A template abstraction layer that would not take the unique features of

Why does Flask call itself a microframework and yet it depends on two
libraries (namely Werkzeug and Jinja2). Why shouldn't it? If we look
libraries (namely Werkzeug and Jinja). Why shouldn't it? If we look
over to the Ruby side of web development there we have a protocol very

@@ -215,3 +215,3 @@ similar to WSGI. Just that it's called Rack there, but besides that it

or anything else in that direction. Flask itself just bridges to Werkzeug
to implement a proper WSGI application and to Jinja2 to handle templating.
to implement a proper WSGI application and to Jinja to handle templating.
It also binds to a few common standard library packages such as logging.

@@ -218,0 +218,0 @@ Everything else is up for extensions.

@@ -6,4 +6,5 @@ .. rst-class:: hide-header

.. image:: _static/flask-horizontal.png
.. image:: _static/flask-name.svg
:align: center
:height: 200px

@@ -10,0 +11,0 @@ Welcome to Flask's documentation. Flask is a lightweight WSGI web application framework.

@@ -32,3 +32,3 @@ Streaming Contents

The Jinja2 template engine supports rendering a template piece by
The Jinja template engine supports rendering a template piece by
piece, returning an iterator of strings. Flask provides the

@@ -35,0 +35,0 @@ :func:`~flask.stream_template` and :func:`~flask.stream_template_string`

@@ -102,3 +102,3 @@ Form Validation with WTForms

the input element. Note that WTForms returns standard Python strings,
so we have to tell Jinja2 that this data is already HTML-escaped with
so we have to tell Jinja that this data is already HTML-escaped with
the ``|safe`` filter.

@@ -105,0 +105,0 @@

@@ -142,16 +142,14 @@ Quickstart

from flask import request
from markupsafe import escape
@app.route("/<name>")
def hello(name):
@app.route("/hello")
def hello():
name = request.args.get("name", "Flask")
return f"Hello, {escape(name)}!"
If a user managed to submit the name ``<script>alert("bad")</script>``,
escaping causes it to be rendered as text, rather than running the
script in the user's browser.
If a user submits ``/hello?name=<script>alert("bad")</script>``, escaping causes
it to be rendered as text, rather than running the script in the user's browser.
``<name>`` in the route captures a value from the URL and passes it to
the view function. These variable rules are explained below.
Routing

@@ -358,3 +356,3 @@ -------

cumbersome because you have to do the HTML escaping on your own to keep
the application secure. Because of that Flask configures the `Jinja2
the application secure. Because of that Flask configures the `Jinja
<https://palletsprojects.com/p/jinja/>`_ template engine for you automatically.

@@ -399,4 +397,4 @@

For templates you can use the full power of Jinja2 templates. Head over
to the official `Jinja2 Template Documentation
For templates you can use the full power of Jinja templates. Head over
to the official `Jinja Template Documentation
<https://jinja.palletsprojects.com/templates/>`_ for more information.

@@ -403,0 +401,0 @@

@@ -80,3 +80,3 @@ .. currentmodule:: flask

5000. You can choose to disable this service instead of using a different port by
searching for "AirPlay Receiver" in System Preferences and toggling it off.
searching for "AirPlay Receiver" in System Settings and toggling it off.

@@ -83,0 +83,0 @@

Templates
=========
Flask leverages Jinja2 as its template engine. You are obviously free to use
a different template engine, but you still have to install Jinja2 to run
Flask leverages Jinja as its template engine. You are obviously free to use
a different template engine, but you still have to install Jinja to run
Flask itself. This requirement is necessary to enable rich extensions.
An extension can depend on Jinja2 being present.
An extension can depend on Jinja being present.
This section only gives a very quick introduction into how Jinja2
This section only gives a very quick introduction into how Jinja
is integrated into Flask. If you want information on the template
engine's syntax itself, head over to the official `Jinja2 Template
engine's syntax itself, head over to the official `Jinja Template
Documentation <https://jinja.palletsprojects.com/templates/>`_ for

@@ -18,3 +18,3 @@ more information.

Unless customized, Jinja2 is configured by Flask as follows:
Unless customized, Jinja is configured by Flask as follows:

@@ -29,3 +29,3 @@ - autoescaping is enabled for all templates ending in ``.html``,

- Flask inserts a couple of global functions and helpers into the
Jinja2 context, additionally to the values that are present by
Jinja context, additionally to the values that are present by
default.

@@ -36,3 +36,3 @@

The following global variables are available within Jinja2 templates
The following global variables are available within Jinja templates
by default:

@@ -146,3 +146,3 @@

If you want to register your own filters in Jinja2 you have two ways to do
If you want to register your own filters in Jinja you have two ways to do
that. You can either put them by hand into the

@@ -164,3 +164,3 @@ :attr:`~flask.Flask.jinja_env` of the application or use the

function name as name of the filter. Once registered, you can use the filter
in your templates in the same way as Jinja2's builtin filters, for example if
in your templates in the same way as Jinja's builtin filters, for example if
you have a Python list in context called `mylist`::

@@ -219,3 +219,3 @@

The Jinja2 template engine supports rendering a template piece
The Jinja template engine supports rendering a template piece
by piece, returning an iterator of strings. Flask provides the

@@ -222,0 +222,0 @@ :func:`~flask.stream_template` and :func:`~flask.stream_template_string`

@@ -54,3 +54,3 @@ Security Considerations

Flask configures Jinja2 to automatically escape all values unless
Flask configures Jinja to automatically escape all values unless
explicitly told otherwise. This should rule out all XSS problems caused

@@ -60,3 +60,3 @@ in templates, but there are still other places where you have to be

- generating HTML without the help of Jinja2
- generating HTML without the help of Jinja
- calling :class:`~markupsafe.Markup` on data submitted by users

@@ -70,3 +70,3 @@ - sending out HTML from uploaded files, never do that, use the

Another thing that is very important are unquoted attributes. While
Jinja2 can protect you from XSS issues by escaping HTML, there is one
Jinja can protect you from XSS issues by escaping HTML, there is one
thing it cannot protect you from: XSS by attribute injection. To counter

@@ -164,3 +164,3 @@ this possible attack vector, be sure to always quote your attributes with

.. _Flask-Talisman: https://github.com/GoogleCloudPlatform/flask-talisman
.. _Flask-Talisman: https://github.com/wntrblm/flask-talisman

@@ -276,2 +276,23 @@ HTTP Strict Transport Security (HSTS)

Host Header Validation
----------------------
The ``Host`` header is used by the client to indicate what host name the request
was made to. This is used, for example, by ``url_for(..., _external=True)`` to
generate full URLs, for use in email or other messages outside the browser
window.
By default the app doesn't know what host(s) it is allowed to be accessed
through, and assumes any host is valid. Although browsers do not allow setting
the ``Host`` header, requests made by attackers in other scenarios could set
the ``Host`` header to a value they want.
When deploying your application, set :data:`TRUSTED_HOSTS` to restrict what
values the ``Host`` header may be.
The ``Host`` header may be modified by proxies in between the client and your
application. See :doc:`deploying/proxy_fix` to tell your app which proxy values
to trust.
Copy/Paste to Terminal

@@ -278,0 +299,0 @@ ----------------------

Metadata-Version: 2.4
Name: Flask
Version: 3.1.1
Version: 3.1.2
Summary: A simple framework for building complex web applications.

@@ -38,2 +38,4 @@ Maintainer-email: Pallets <contact@palletsprojects.com>

<div align="center"><img src="https://raw.githubusercontent.com/pallets/flask/refs/heads/stable/docs/_static/flask-name.svg" alt="" height="150"></div>
# Flask

@@ -40,0 +42,0 @@

[project]
name = "Flask"
version = "3.1.1"
version = "3.1.2"
description = "A simple framework for building complex web applications."

@@ -169,7 +169,2 @@ readme = "README.md"

[tool.gha-update]
tag-only = [
"slsa-framework/slsa-github-generator",
]
[tool.tox]

@@ -176,0 +171,0 @@ env_list = [

@@ -0,1 +1,3 @@

<div align="center"><img src="https://raw.githubusercontent.com/pallets/flask/refs/heads/stable/docs/_static/flask-name.svg" alt="" height="150"></div>
# Flask

@@ -2,0 +4,0 @@

@@ -190,4 +190,4 @@ from __future__ import annotations

def wrapper(*args: t.Any, **kwargs: t.Any) -> t.Any:
with ctx: # type: ignore[union-attr]
return ctx.app.ensure_sync(f)(*args, **kwargs) # type: ignore[union-attr]
with ctx:
return ctx.app.ensure_sync(f)(*args, **kwargs)

@@ -194,0 +194,0 @@ return update_wrapper(wrapper, f) # type: ignore[return-value]

@@ -16,2 +16,3 @@ from __future__ import annotations

from .globals import _cv_app
from .globals import _cv_request

@@ -66,31 +67,36 @@ from .globals import current_app

) -> t.Iterator[t.AnyStr] | t.Callable[[t.Iterator[t.AnyStr]], t.Iterator[t.AnyStr]]:
"""Request contexts disappear when the response is started on the server.
This is done for efficiency reasons and to make it less likely to encounter
memory leaks with badly written WSGI middlewares. The downside is that if
you are using streamed responses, the generator cannot access request bound
information any more.
"""Wrap a response generator function so that it runs inside the current
request context. This keeps :data:`request`, :data:`session`, and :data:`g`
available, even though at the point the generator runs the request context
will typically have ended.
This function however can help you keep the context around for longer::
Use it as a decorator on a generator function:
.. code-block:: python
from flask import stream_with_context, request, Response
@app.route('/stream')
@app.get("/stream")
def streamed_response():
@stream_with_context
def generate():
yield 'Hello '
yield request.args['name']
yield '!'
yield "Hello "
yield request.args["name"]
yield "!"
return Response(generate())
Alternatively it can also be used around a specific generator::
Or use it as a wrapper around a created generator:
.. code-block:: python
from flask import stream_with_context, request, Response
@app.route('/stream')
@app.get("/stream")
def streamed_response():
def generate():
yield 'Hello '
yield request.args['name']
yield '!'
yield "Hello "
yield request.args["name"]
yield "!"
return Response(stream_with_context(generate()))

@@ -110,5 +116,4 @@

def generator() -> t.Iterator[t.AnyStr | None]:
ctx = _cv_request.get(None)
if ctx is None:
def generator() -> t.Iterator[t.AnyStr]:
if (req_ctx := _cv_request.get(None)) is None:
raise RuntimeError(

@@ -118,24 +123,26 @@ "'stream_with_context' can only be used when a request"

)
with ctx:
# Dummy sentinel. Has to be inside the context block or we're
# not actually keeping the context around.
yield None
# The try/finally is here so that if someone passes a WSGI level
# iterator in we're still running the cleanup logic. Generators
# don't need that because they are closed on their destruction
# automatically.
app_ctx = _cv_app.get()
# Setup code below will run the generator to this point, so that the
# current contexts are recorded. The contexts must be pushed after,
# otherwise their ContextVar will record the wrong event loop during
# async view functions.
yield None # type: ignore[misc]
# Push the app context first, so that the request context does not
# automatically create and push a different app context.
with app_ctx, req_ctx:
try:
yield from gen
finally:
# Clean up in case the user wrapped a WSGI iterator.
if hasattr(gen, "close"):
gen.close()
# The trick is to start the generator. Then the code execution runs until
# the first dummy None is yielded at which point the context was already
# pushed. This item is discarded. Then when the iteration continues the
# real generator is executed.
# Execute the generator to the sentinel value. This ensures the context is
# preserved in the generator's state. Further iteration will push the
# context and yield from the original iterator.
wrapped_g = generator()
next(wrapped_g)
return wrapped_g # type: ignore[return-value]
return wrapped_g

@@ -399,3 +406,3 @@

response_class=current_app.response_class,
_root_path=current_app.root_path, # type: ignore
_root_path=current_app.root_path,
)

@@ -406,3 +413,3 @@ return kwargs

def send_file(
path_or_file: os.PathLike[t.AnyStr] | str | t.BinaryIO,
path_or_file: os.PathLike[t.AnyStr] | str | t.IO[bytes],
mimetype: str | None = None,

@@ -409,0 +416,0 @@ as_attachment: bool = False,

@@ -426,3 +426,3 @@ from __future__ import annotations

@cached_property
def name(self) -> str: # type: ignore
def name(self) -> str:
"""The name of the application. This is usually the import name

@@ -525,3 +525,3 @@ with the difference that it's guessed from the run file if the

def create_global_jinja_loader(self) -> DispatchingJinjaLoader:
"""Creates the loader for the Jinja2 environment. Can be used to
"""Creates the loader for the Jinja environment. Can be used to
override just the loader and keeping the rest unchanged. It's

@@ -528,0 +528,0 @@ discouraged to override this function. Instead one should override

@@ -87,3 +87,3 @@ from __future__ import annotations

self.static_folder = static_folder # type: ignore
self.static_folder = static_folder
self.static_url_path = static_url_path

@@ -90,0 +90,0 @@

@@ -110,3 +110,3 @@ from __future__ import annotations

__setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail # type: ignore # noqa: B950
__setitem__ = __delitem__ = clear = pop = popitem = update = setdefault = _fail # noqa: B950
del _fail

@@ -113,0 +113,0 @@

@@ -40,3 +40,3 @@ from __future__ import annotations

class Environment(BaseEnvironment):
"""Works like a regular Jinja2 environment but has some additional
"""Works like a regular Jinja environment but has some additional
knowledge of how Flask's blueprint works so that it can prepend the

@@ -43,0 +43,0 @@ name of the blueprint to referenced templates if necessary.

@@ -88,3 +88,3 @@ from __future__ import annotations

def json_dumps(self, obj: t.Any, **kwargs: t.Any) -> str: # type: ignore
def json_dumps(self, obj: t.Any, **kwargs: t.Any) -> str:
"""Serialize ``obj`` to a JSON-formatted string.

@@ -244,6 +244,6 @@

# Re-push contexts that were preserved during the request.
while self._new_contexts:
cm = self._new_contexts.pop()
for cm in self._new_contexts:
self._context_stack.enter_context(cm)
self._new_contexts.clear()
return response

@@ -250,0 +250,0 @@

@@ -309,3 +309,26 @@ import io

def test_async_view(self, app, client):
@app.route("/")
async def index():
flask.session["test"] = "flask"
@flask.stream_with_context
def gen():
yield flask.session["test"]
return flask.Response(gen())
# response is closed without reading stream
client.get().close()
# response stream is read
assert client.get().text == "flask"
# same as above, but with client context preservation
with client:
client.get().close()
with client:
assert client.get().text == "flask"
class TestHelpers:

@@ -312,0 +335,0 @@ @pytest.mark.parametrize(

@@ -141,30 +141,19 @@ import importlib.metadata

def test_redirect_keep_session(app, client, app_ctx):
@app.route("/", methods=["GET", "POST"])
def test_redirect_session(app, client, app_ctx):
@app.route("/redirect")
def index():
if flask.request.method == "POST":
return flask.redirect("/getsession")
flask.session["data"] = "foo"
return "index"
flask.session["redirect"] = True
return flask.redirect("/target")
@app.route("/getsession")
@app.route("/target")
def get_session():
return flask.session.get("data", "<missing>")
flask.session["target"] = True
return ""
with client:
rv = client.get("/getsession")
assert rv.data == b"<missing>"
client.get("/redirect", follow_redirects=True)
assert flask.session["redirect"] is True
assert flask.session["target"] is True
rv = client.get("/")
assert rv.data == b"index"
assert flask.session.get("data") == "foo"
rv = client.post("/", data={}, follow_redirects=True)
assert rv.data == b"foo"
assert flask.session.get("data") == "foo"
rv = client.get("/getsession")
assert rv.data == b"foo"
def test_session_transactions(app, client):

@@ -171,0 +160,0 @@ @app.route("/")

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display