flask
Advanced tools
| <?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. |
+8
-8
@@ -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. |
+2
-1
@@ -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 @@ |
+9
-11
@@ -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 @@ |
+1
-1
@@ -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 @@ |
+11
-11
| 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 @@ ---------------------- |
+3
-1
| 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 @@ |
+1
-6
| [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 = [ |
+2
-0
@@ -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 @@ |
+2
-2
@@ -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] |
+40
-33
@@ -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( |
+10
-21
@@ -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
Alert delta unavailable
Currently unable to show alert delta for PyPI packages.
13876
0.08%1750030
-0.98%