mirror of https://github.com/pallets/flask.git
commit
ea93a52d7d
|
@ -31,7 +31,6 @@ jobs:
|
||||||
- {name: '3.9', python: '3.9', os: ubuntu-latest, tox: py39}
|
- {name: '3.9', python: '3.9', os: ubuntu-latest, tox: py39}
|
||||||
- {name: '3.8', python: '3.8', os: ubuntu-latest, tox: py38}
|
- {name: '3.8', python: '3.8', os: ubuntu-latest, tox: py38}
|
||||||
- {name: '3.7', python: '3.7', os: ubuntu-latest, tox: py37}
|
- {name: '3.7', python: '3.7', os: ubuntu-latest, tox: py37}
|
||||||
- {name: '3.6', python: '3.6', os: ubuntu-latest, tox: py36}
|
|
||||||
- {name: 'PyPy', python: 'pypy-3.7', os: ubuntu-latest, tox: pypy37}
|
- {name: 'PyPy', python: 'pypy-3.7', os: ubuntu-latest, tox: pypy37}
|
||||||
- {name: Typing, python: '3.10', os: ubuntu-latest, tox: typing}
|
- {name: Typing, python: '3.10', os: ubuntu-latest, tox: typing}
|
||||||
steps:
|
steps:
|
||||||
|
|
|
@ -7,8 +7,7 @@ Using ``async`` and ``await``
|
||||||
|
|
||||||
Routes, error handlers, before request, after request, and teardown
|
Routes, error handlers, before request, after request, and teardown
|
||||||
functions can all be coroutine functions if Flask is installed with the
|
functions can all be coroutine functions if Flask is installed with the
|
||||||
``async`` extra (``pip install flask[async]``). It requires Python 3.7+
|
``async`` extra (``pip install flask[async]``). This allows views to be
|
||||||
where ``contextvars.ContextVar`` is available. This allows views to be
|
|
||||||
defined with ``async def`` and use ``await``.
|
defined with ``async def`` and use ``await``.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
@ -30,6 +29,12 @@ well as all the HTTP method handlers in views that inherit from the
|
||||||
something like ``ValueError: set_wakeup_fd only works in main thread``,
|
something like ``ValueError: set_wakeup_fd only works in main thread``,
|
||||||
please upgrade to Python 3.9.
|
please upgrade to Python 3.9.
|
||||||
|
|
||||||
|
.. admonition:: Using ``async`` with greenlet
|
||||||
|
|
||||||
|
When using gevent or eventlet to serve an application or patch the
|
||||||
|
runtime, greenlet>=1.0 is required. When using PyPy, PyPy>=7.3.7 is
|
||||||
|
required.
|
||||||
|
|
||||||
|
|
||||||
Performance
|
Performance
|
||||||
-----------
|
-----------
|
||||||
|
|
|
@ -112,10 +112,9 @@ shell with the :func:`shell <cli.shell_command>` command. An application
|
||||||
context will be active, and the app instance will be imported. ::
|
context will be active, and the app instance will be imported. ::
|
||||||
|
|
||||||
$ flask shell
|
$ flask shell
|
||||||
Python 3.6.2 (default, Jul 20 2017, 03:52:27)
|
Python 3.10.0 (default, Oct 27 2021, 06:59:51) [GCC 11.1.0] on linux
|
||||||
[GCC 7.1.1 20170630] on linux
|
App: example [production]
|
||||||
App: example
|
Instance: /home/david/Projects/pallets/flask/instance
|
||||||
Instance: /home/user/Projects/hello/instance
|
|
||||||
>>>
|
>>>
|
||||||
|
|
||||||
Use :meth:`~Flask.shell_context_processor` to add other automatic imports.
|
Use :meth:`~Flask.shell_context_processor` to add other automatic imports.
|
||||||
|
|
|
@ -1,67 +1,171 @@
|
||||||
Standalone WSGI Containers
|
Standalone WSGI Servers
|
||||||
==========================
|
=======================
|
||||||
|
|
||||||
|
Most WSGI servers also provide HTTP servers, so they can run a WSGI
|
||||||
|
application and make it available externally.
|
||||||
|
|
||||||
|
It may still be a good idea to run the server behind a dedicated HTTP
|
||||||
|
server such as Apache or Nginx. See :ref:`deploying-proxy-setups` if you
|
||||||
|
run into issues with that.
|
||||||
|
|
||||||
There are popular servers written in Python that contain WSGI applications and
|
|
||||||
serve HTTP. These servers stand alone when they run; you can proxy to them
|
|
||||||
from your web server. Note the section on :ref:`deploying-proxy-setups` if you
|
|
||||||
run into issues.
|
|
||||||
|
|
||||||
Gunicorn
|
Gunicorn
|
||||||
--------
|
--------
|
||||||
|
|
||||||
`Gunicorn`_ 'Green Unicorn' is a WSGI HTTP Server for UNIX. It's a pre-fork
|
`Gunicorn`_ is a WSGI and HTTP server for UNIX. To run a Flask
|
||||||
worker model ported from Ruby's Unicorn project. It supports both `eventlet`_
|
application, tell Gunicorn how to import your Flask app object.
|
||||||
and `greenlet`_. Running a Flask application on this server is quite simple::
|
|
||||||
|
|
||||||
$ gunicorn myproject:app
|
.. code-block:: text
|
||||||
|
|
||||||
`Gunicorn`_ provides many command-line options -- see ``gunicorn -h``.
|
$ gunicorn -w 4 -b 0.0.0.0:5000 your_project:app
|
||||||
For example, to run a Flask application with 4 worker processes (``-w
|
|
||||||
4``) binding to localhost port 4000 (``-b 127.0.0.1:4000``)::
|
|
||||||
|
|
||||||
$ gunicorn -w 4 -b 127.0.0.1:4000 myproject:app
|
The ``-w 4`` option uses 4 workers to handle 4 requests at once. The
|
||||||
|
``-b 0.0.0.0:5000`` serves the application on all interfaces on port
|
||||||
|
5000.
|
||||||
|
|
||||||
The ``gunicorn`` command expects the names of your application module or
|
Gunicorn provides many options for configuring the server, either
|
||||||
package and the application instance within the module. If you use the
|
through a configuration file or with command line options. Use
|
||||||
application factory pattern, you can pass a call to that::
|
``gunicorn --help`` or see the docs for more information.
|
||||||
|
|
||||||
|
The command expects the name of your module or package to import and
|
||||||
|
the application instance within the module. If you use the application
|
||||||
|
factory pattern, you can pass a call to that.
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
$ gunicorn -w 4 -b 0.0.0.0:5000 "myproject:create_app()"
|
||||||
|
|
||||||
|
|
||||||
|
Async with Gevent or Eventlet
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The default sync worker is appropriate for many use cases. If you need
|
||||||
|
asynchronous support, Gunicorn provides workers using either `gevent`_
|
||||||
|
or `eventlet`_. This is not the same as Python's ``async/await``, or the
|
||||||
|
ASGI server spec.
|
||||||
|
|
||||||
|
When using either gevent or eventlet, greenlet>=1.0 is required,
|
||||||
|
otherwise context locals such as ``request`` will not work as expected.
|
||||||
|
When using PyPy, PyPy>=7.3.7 is required.
|
||||||
|
|
||||||
|
To use gevent:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
$ gunicorn -k gevent -b 0.0.0.0:5000 your_project:app
|
||||||
|
|
||||||
|
To use eventlet:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
$ gunicorn -k eventlet -b 0.0.0.0:5000 your_project:app
|
||||||
|
|
||||||
$ gunicorn "myproject:create_app()"
|
|
||||||
|
|
||||||
.. _Gunicorn: https://gunicorn.org/
|
.. _Gunicorn: https://gunicorn.org/
|
||||||
|
.. _gevent: http://www.gevent.org/
|
||||||
.. _eventlet: https://eventlet.net/
|
.. _eventlet: https://eventlet.net/
|
||||||
|
.. _greenlet: https://greenlet.readthedocs.io/en/latest/
|
||||||
|
|
||||||
|
|
||||||
uWSGI
|
uWSGI
|
||||||
--------
|
-----
|
||||||
|
|
||||||
`uWSGI`_ is a fast application server written in C. It is very configurable
|
`uWSGI`_ is a fast application server written in C. It is very
|
||||||
which makes it more complicated to setup than gunicorn.
|
configurable, which makes it more complicated to setup than Gunicorn.
|
||||||
|
It also provides many other utilities for writing robust web
|
||||||
|
applications. To run a Flask application, tell Gunicorn how to import
|
||||||
|
your Flask app object.
|
||||||
|
|
||||||
Running `uWSGI HTTP Router`_::
|
.. code-block:: text
|
||||||
|
|
||||||
$ uwsgi --http 127.0.0.1:5000 --module myproject:app
|
$ uwsgi --master -p 4 --http 0.0.0.0:5000 -w your_project:app
|
||||||
|
|
||||||
For a more optimized setup, see :doc:`configuring uWSGI and NGINX <uwsgi>`.
|
The ``-p 4`` option uses 4 workers to handle 4 requests at once. The
|
||||||
|
``--http 0.0.0.0:5000`` serves the application on all interfaces on port
|
||||||
|
5000.
|
||||||
|
|
||||||
|
uWSGI has optimized integration with Nginx and Apache instead of using
|
||||||
|
a standard HTTP proxy. See :doc:`configuring uWSGI and Nginx <uwsgi>`.
|
||||||
|
|
||||||
|
|
||||||
|
Async with Gevent
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The default sync worker is appropriate for many use cases. If you need
|
||||||
|
asynchronous support, uWSGI provides workers using `gevent`_. It also
|
||||||
|
supports other async modes, see the docs for more information. This is
|
||||||
|
not the same as Python's ``async/await``, or the ASGI server spec.
|
||||||
|
|
||||||
|
When using gevent, greenlet>=1.0 is required, otherwise context locals
|
||||||
|
such as ``request`` will not work as expected. When using PyPy,
|
||||||
|
PyPy>=7.3.7 is required.
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
$ uwsgi --master --gevent 100 --http 0.0.0.0:5000 -w your_project:app
|
||||||
|
|
||||||
.. _uWSGI: https://uwsgi-docs.readthedocs.io/en/latest/
|
.. _uWSGI: https://uwsgi-docs.readthedocs.io/en/latest/
|
||||||
.. _uWSGI HTTP Router: https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html#the-uwsgi-http-https-router
|
|
||||||
|
|
||||||
Gevent
|
Gevent
|
||||||
-------
|
------
|
||||||
|
|
||||||
`Gevent`_ is a coroutine-based Python networking library that uses
|
Prefer using `Gunicorn`_ with Gevent workers rather than using Gevent
|
||||||
`greenlet`_ to provide a high-level synchronous API on top of `libev`_
|
directly. Gunicorn provides a much more configurable and
|
||||||
event loop::
|
production-tested server. See the section on Gunicorn above.
|
||||||
|
|
||||||
|
`Gevent`_ allows writing asynchronous, coroutine-based code that looks
|
||||||
|
like standard synchronous Python. It uses `greenlet`_ to enable task
|
||||||
|
switching without writing ``async/await`` or using ``asyncio``.
|
||||||
|
|
||||||
|
It provides a WSGI server that can handle many connections at once
|
||||||
|
instead of one per worker process.
|
||||||
|
|
||||||
|
`Eventlet`_, described below, is another library that does the same
|
||||||
|
thing. Certain dependencies you have, or other consideration, may affect
|
||||||
|
which of the two you choose to use
|
||||||
|
|
||||||
|
To use gevent to serve your application, import its ``WSGIServer`` and
|
||||||
|
use it to run your ``app``.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
from gevent.pywsgi import WSGIServer
|
from gevent.pywsgi import WSGIServer
|
||||||
from yourapplication import app
|
from your_project import app
|
||||||
|
|
||||||
http_server = WSGIServer(('', 5000), app)
|
http_server = WSGIServer(("", 5000), app)
|
||||||
http_server.serve_forever()
|
http_server.serve_forever()
|
||||||
|
|
||||||
.. _Gevent: http://www.gevent.org/
|
|
||||||
.. _greenlet: https://greenlet.readthedocs.io/en/latest/
|
Eventlet
|
||||||
.. _libev: http://software.schmorp.de/pkg/libev.html
|
--------
|
||||||
|
|
||||||
|
Prefer using `Gunicorn`_ with Eventlet workers rather than using
|
||||||
|
Eventlet directly. Gunicorn provides a much more configurable and
|
||||||
|
production-tested server. See the section on Gunicorn above.
|
||||||
|
|
||||||
|
`Eventlet`_ allows writing asynchronous, coroutine-based code that looks
|
||||||
|
like standard synchronous Python. It uses `greenlet`_ to enable task
|
||||||
|
switching without writing ``async/await`` or using ``asyncio``.
|
||||||
|
|
||||||
|
It provides a WSGI server that can handle many connections at once
|
||||||
|
instead of one per worker process.
|
||||||
|
|
||||||
|
`Gevent`_, described above, is another library that does the same
|
||||||
|
thing. Certain dependencies you have, or other consideration, may affect
|
||||||
|
which of the two you choose to use
|
||||||
|
|
||||||
|
To use eventlet to serve your application, import its ``wsgi.server``
|
||||||
|
and use it to run your ``app``.
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
import eventlet
|
||||||
|
from eventlet import wsgi
|
||||||
|
from your_project import app
|
||||||
|
|
||||||
|
wsgi.server(eventlet.listen(("", 5000), app)
|
||||||
|
|
||||||
|
|
||||||
Twisted Web
|
Twisted Web
|
||||||
-----------
|
-----------
|
||||||
|
@ -69,7 +173,9 @@ Twisted Web
|
||||||
`Twisted Web`_ is the web server shipped with `Twisted`_, a mature,
|
`Twisted Web`_ is the web server shipped with `Twisted`_, a mature,
|
||||||
non-blocking event-driven networking library. Twisted Web comes with a
|
non-blocking event-driven networking library. Twisted Web comes with a
|
||||||
standard WSGI container which can be controlled from the command line using
|
standard WSGI container which can be controlled from the command line using
|
||||||
the ``twistd`` utility::
|
the ``twistd`` utility:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ twistd web --wsgi myproject.app
|
$ twistd web --wsgi myproject.app
|
||||||
|
|
||||||
|
@ -79,13 +185,16 @@ This example will run a Flask application called ``app`` from a module named
|
||||||
Twisted Web supports many flags and options, and the ``twistd`` utility does
|
Twisted Web supports many flags and options, and the ``twistd`` utility does
|
||||||
as well; see ``twistd -h`` and ``twistd web -h`` for more information. For
|
as well; see ``twistd -h`` and ``twistd web -h`` for more information. For
|
||||||
example, to run a Twisted Web server in the foreground, on port 8080, with an
|
example, to run a Twisted Web server in the foreground, on port 8080, with an
|
||||||
application from ``myproject``::
|
application from ``myproject``:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
$ twistd -n web --port tcp:8080 --wsgi myproject.app
|
$ twistd -n web --port tcp:8080 --wsgi myproject.app
|
||||||
|
|
||||||
.. _Twisted: https://twistedmatrix.com/trac/
|
.. _Twisted: https://twistedmatrix.com/trac/
|
||||||
.. _Twisted Web: https://twistedmatrix.com/trac/wiki/TwistedWeb
|
.. _Twisted Web: https://twistedmatrix.com/trac/wiki/TwistedWeb
|
||||||
|
|
||||||
|
|
||||||
.. _deploying-proxy-setups:
|
.. _deploying-proxy-setups:
|
||||||
|
|
||||||
Proxy Setups
|
Proxy Setups
|
||||||
|
|
|
@ -322,9 +322,9 @@ ecosystem remain consistent and compatible.
|
||||||
`Official Pallets Themes`_. A link to the documentation or project
|
`Official Pallets Themes`_. A link to the documentation or project
|
||||||
website must be in the PyPI metadata or the readme.
|
website must be in the PyPI metadata or the readme.
|
||||||
7. For maximum compatibility, the extension should support the same
|
7. For maximum compatibility, the extension should support the same
|
||||||
versions of Python that Flask supports. 3.6+ is recommended as of
|
versions of Python that Flask supports. 3.7+ is recommended as of
|
||||||
2020. Use ``python_requires=">= 3.6"`` in ``setup.py`` to indicate
|
December 2021. Use ``python_requires=">= 3.7"`` in ``setup.py`` to
|
||||||
supported versions.
|
indicate supported versions.
|
||||||
|
|
||||||
.. _PyPI: https://pypi.org/search/?c=Framework+%3A%3A+Flask
|
.. _PyPI: https://pypi.org/search/?c=Framework+%3A%3A+Flask
|
||||||
.. _mailinglist: https://mail.python.org/mailman/listinfo/flask
|
.. _mailinglist: https://mail.python.org/mailman/listinfo/flask
|
||||||
|
|
|
@ -6,9 +6,7 @@ Python Version
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
We recommend using the latest version of Python. Flask supports Python
|
We recommend using the latest version of Python. Flask supports Python
|
||||||
3.6 and newer.
|
3.7 and newer.
|
||||||
|
|
||||||
``async`` support in Flask requires Python 3.7+ for ``contextvars.ContextVar``.
|
|
||||||
|
|
||||||
|
|
||||||
Dependencies
|
Dependencies
|
||||||
|
@ -51,6 +49,18 @@ use them if you install them.
|
||||||
.. _watchdog: https://pythonhosted.org/watchdog/
|
.. _watchdog: https://pythonhosted.org/watchdog/
|
||||||
|
|
||||||
|
|
||||||
|
greenlet
|
||||||
|
~~~~~~~~
|
||||||
|
|
||||||
|
You may choose to use gevent or eventlet with your application. In this
|
||||||
|
case, greenlet>=1.0 is required. When using PyPy, PyPy>=7.3.7 is
|
||||||
|
required.
|
||||||
|
|
||||||
|
These are not minimum supported versions, they only indicate the first
|
||||||
|
versions that added necessary features. You should use the latest
|
||||||
|
versions of each.
|
||||||
|
|
||||||
|
|
||||||
Virtual environments
|
Virtual environments
|
||||||
--------------------
|
--------------------
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ filelock==3.3.2
|
||||||
# via
|
# via
|
||||||
# tox
|
# tox
|
||||||
# virtualenv
|
# virtualenv
|
||||||
greenlet==1.1.2
|
greenlet==1.1.2 ; python_version < "3.11"
|
||||||
# via -r requirements/tests.in
|
# via -r requirements/tests.in
|
||||||
identify==2.3.3
|
identify==2.3.3
|
||||||
# via pre-commit
|
# via pre-commit
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
pytest
|
pytest
|
||||||
asgiref
|
asgiref
|
||||||
blinker
|
blinker
|
||||||
greenlet
|
greenlet ; python_version < "3.11"
|
||||||
python-dotenv
|
python-dotenv
|
||||||
|
|
|
@ -10,7 +10,7 @@ attrs==21.2.0
|
||||||
# via pytest
|
# via pytest
|
||||||
blinker==1.4
|
blinker==1.4
|
||||||
# via -r requirements/tests.in
|
# via -r requirements/tests.in
|
||||||
greenlet==1.1.2
|
greenlet==1.1.2 ; python_version < "3.11"
|
||||||
# via -r requirements/tests.in
|
# via -r requirements/tests.in
|
||||||
iniconfig==1.1.1
|
iniconfig==1.1.1
|
||||||
# via pytest
|
# via pytest
|
||||||
|
|
|
@ -35,7 +35,7 @@ classifiers =
|
||||||
packages = find:
|
packages = find:
|
||||||
package_dir = = src
|
package_dir = = src
|
||||||
include_package_data = true
|
include_package_data = true
|
||||||
python_requires = >= 3.6
|
python_requires = >= 3.7
|
||||||
# Dependencies are in setup.py for GitHub's dependency graph.
|
# Dependencies are in setup.py for GitHub's dependency graph.
|
||||||
|
|
||||||
[options.packages.find]
|
[options.packages.find]
|
||||||
|
@ -88,7 +88,7 @@ per-file-ignores =
|
||||||
|
|
||||||
[mypy]
|
[mypy]
|
||||||
files = src/flask
|
files = src/flask
|
||||||
python_version = 3.6
|
python_version = 3.7
|
||||||
allow_redefinition = True
|
allow_redefinition = True
|
||||||
disallow_subclassing_any = True
|
disallow_subclassing_any = True
|
||||||
# disallow_untyped_calls = True
|
# disallow_untyped_calls = True
|
||||||
|
|
|
@ -16,7 +16,6 @@ from werkzeug.exceptions import BadRequest
|
||||||
from werkzeug.exceptions import BadRequestKeyError
|
from werkzeug.exceptions import BadRequestKeyError
|
||||||
from werkzeug.exceptions import HTTPException
|
from werkzeug.exceptions import HTTPException
|
||||||
from werkzeug.exceptions import InternalServerError
|
from werkzeug.exceptions import InternalServerError
|
||||||
from werkzeug.local import ContextVar
|
|
||||||
from werkzeug.routing import BuildError
|
from werkzeug.routing import BuildError
|
||||||
from werkzeug.routing import Map
|
from werkzeug.routing import Map
|
||||||
from werkzeug.routing import MapAdapter
|
from werkzeug.routing import MapAdapter
|
||||||
|
@ -1621,13 +1620,6 @@ class Flask(Scaffold):
|
||||||
"Install Flask with the 'async' extra in order to use async views."
|
"Install Flask with the 'async' extra in order to use async views."
|
||||||
) from None
|
) from None
|
||||||
|
|
||||||
# Check that Werkzeug isn't using its fallback ContextVar class.
|
|
||||||
if ContextVar.__module__ == "werkzeug.local":
|
|
||||||
raise RuntimeError(
|
|
||||||
"Async cannot be used with this combination of Python "
|
|
||||||
"and Greenlet versions."
|
|
||||||
)
|
|
||||||
|
|
||||||
return asgiref_async_to_sync(func)
|
return asgiref_async_to_sync(func)
|
||||||
|
|
||||||
def make_response(self, rv: ResponseReturnValue) -> Response:
|
def make_response(self, rv: ResponseReturnValue) -> Response:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import dataclasses
|
||||||
import decimal
|
import decimal
|
||||||
import io
|
import io
|
||||||
import json as _json
|
import json as _json
|
||||||
|
@ -16,12 +17,6 @@ if t.TYPE_CHECKING:
|
||||||
from ..app import Flask
|
from ..app import Flask
|
||||||
from ..wrappers import Response
|
from ..wrappers import Response
|
||||||
|
|
||||||
try:
|
|
||||||
import dataclasses
|
|
||||||
except ImportError:
|
|
||||||
# Python < 3.7
|
|
||||||
dataclasses = None # type: ignore
|
|
||||||
|
|
||||||
|
|
||||||
class JSONEncoder(_json.JSONEncoder):
|
class JSONEncoder(_json.JSONEncoder):
|
||||||
"""The default JSON encoder. Handles extra types compared to the
|
"""The default JSON encoder. Handles extra types compared to the
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import asyncio
|
import asyncio
|
||||||
import sys
|
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
|
@ -79,7 +78,6 @@ def _async_app():
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires Python >= 3.7")
|
|
||||||
@pytest.mark.parametrize("path", ["/", "/home", "/bp/", "/view", "/methodview"])
|
@pytest.mark.parametrize("path", ["/", "/home", "/bp/", "/view", "/methodview"])
|
||||||
def test_async_route(path, async_app):
|
def test_async_route(path, async_app):
|
||||||
test_client = async_app.test_client()
|
test_client = async_app.test_client()
|
||||||
|
@ -89,7 +87,6 @@ def test_async_route(path, async_app):
|
||||||
assert b"POST" in response.get_data()
|
assert b"POST" in response.get_data()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires Python >= 3.7")
|
|
||||||
@pytest.mark.parametrize("path", ["/error", "/bp/error"])
|
@pytest.mark.parametrize("path", ["/error", "/bp/error"])
|
||||||
def test_async_error_handler(path, async_app):
|
def test_async_error_handler(path, async_app):
|
||||||
test_client = async_app.test_client()
|
test_client = async_app.test_client()
|
||||||
|
@ -97,7 +94,6 @@ def test_async_error_handler(path, async_app):
|
||||||
assert response.status_code == 412
|
assert response.status_code == 412
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires Python >= 3.7")
|
|
||||||
def test_async_before_after_request():
|
def test_async_before_after_request():
|
||||||
app_first_called = False
|
app_first_called = False
|
||||||
app_before_called = False
|
app_before_called = False
|
||||||
|
@ -154,10 +150,3 @@ def test_async_before_after_request():
|
||||||
test_client.get("/bp/")
|
test_client.get("/bp/")
|
||||||
assert bp_before_called
|
assert bp_before_called
|
||||||
assert bp_after_called
|
assert bp_after_called
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.version_info >= (3, 7), reason="should only raise Python < 3.7")
|
|
||||||
def test_async_runtime_error():
|
|
||||||
app = Flask(__name__)
|
|
||||||
with pytest.raises(RuntimeError):
|
|
||||||
app.async_to_sync(None)
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import gc
|
import gc
|
||||||
import re
|
import re
|
||||||
import sys
|
|
||||||
import time
|
import time
|
||||||
import uuid
|
import uuid
|
||||||
import weakref
|
import weakref
|
||||||
|
@ -1323,7 +1322,6 @@ def test_jsonify_mimetype(app, req_ctx):
|
||||||
assert rv.mimetype == "application/vnd.api+json"
|
assert rv.mimetype == "application/vnd.api+json"
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skipif(sys.version_info < (3, 7), reason="requires Python >= 3.7")
|
|
||||||
def test_json_dump_dataclass(app, req_ctx):
|
def test_json_dump_dataclass(app, req_ctx):
|
||||||
from dataclasses import make_dataclass
|
from dataclasses import make_dataclass
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue