update project metadata
new readme readme as setup.py long_description links in changes git in authors add travis osx env break out docs build in travis remove python_requires for now
This commit is contained in:
parent
f9c6f389ac
commit
9bf5c3b3a3
16 changed files with 309 additions and 652 deletions
2
.gitattributes
vendored
2
.gitattributes
vendored
|
|
@ -1 +1 @@
|
||||||
CHANGES merge=union
|
CHANGES.rst merge=union
|
||||||
|
|
|
||||||
11
.travis.yml
11
.travis.yml
|
|
@ -4,7 +4,9 @@ language: python
|
||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
- python: 3.6
|
- python: 3.6
|
||||||
env: TOXENV=py,simplejson,devel,lowest,codecov,docs-html
|
env: TOXENV=py,simplejson,devel,lowest,codecov
|
||||||
|
- python: 3.6
|
||||||
|
env: TOXENV=docs-html
|
||||||
- python: 3.5
|
- python: 3.5
|
||||||
env: TOXENV=py,codecov
|
env: TOXENV=py,codecov
|
||||||
- python: 3.4
|
- python: 3.4
|
||||||
|
|
@ -15,9 +17,16 @@ matrix:
|
||||||
env: TOXENV=py,codecov
|
env: TOXENV=py,codecov
|
||||||
- python: nightly
|
- python: nightly
|
||||||
env: TOXENV=py
|
env: TOXENV=py
|
||||||
|
- os: osx
|
||||||
|
language: generic
|
||||||
|
env: TOXENV=py
|
||||||
allow_failures:
|
allow_failures:
|
||||||
- python: nightly
|
- python: nightly
|
||||||
env: TOXENV=py
|
env: TOXENV=py
|
||||||
|
- os: osx
|
||||||
|
language: generic
|
||||||
|
env: TOXENV=py
|
||||||
|
fast_finish: true
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- pip install tox
|
- pip install tox
|
||||||
|
|
|
||||||
46
AUTHORS
46
AUTHORS
|
|
@ -1,40 +1,12 @@
|
||||||
Flask is written and maintained by Armin Ronacher and
|
Flask is developed and maintained by the Pallets team and community
|
||||||
various contributors:
|
contributors. It was created by Armin Ronacher. The core maintainers
|
||||||
|
are:
|
||||||
|
|
||||||
Development Lead
|
- David Lord (davidism)
|
||||||
````````````````
|
- Adrian Mönnich (ThiefMaster)
|
||||||
|
- Armin Ronacher (mitsuhiko)
|
||||||
|
- Marcus Unterwaditzer (untitaker)
|
||||||
|
|
||||||
- Armin Ronacher <armin.ronacher@active-4.com>
|
A full list of contributors is available from git with::
|
||||||
|
|
||||||
Patches and Suggestions
|
git shortlog -sne
|
||||||
```````````````````````
|
|
||||||
|
|
||||||
- Adam Byrtek
|
|
||||||
- Adam Zapletal
|
|
||||||
- Ali Afshar
|
|
||||||
- Chris Edgemon
|
|
||||||
- Chris Grindstaff
|
|
||||||
- Christopher Grebs
|
|
||||||
- Daniel Neuhäuser
|
|
||||||
- Dan Sully
|
|
||||||
- David Lord @davidism
|
|
||||||
- Edmond Burnett
|
|
||||||
- Florent Xicluna
|
|
||||||
- Georg Brandl
|
|
||||||
- Hsiaoming Yang @lepture
|
|
||||||
- Jeff Widman @jeffwidman
|
|
||||||
- Joshua Bronson @jab
|
|
||||||
- Justin Quick
|
|
||||||
- Kenneth Reitz
|
|
||||||
- Keyan Pishdadian
|
|
||||||
- Marian Sigler
|
|
||||||
- Martijn Pieters
|
|
||||||
- Matt Campell
|
|
||||||
- Matthew Frazier
|
|
||||||
- Michael van Tellingen
|
|
||||||
- Ron DuPlain
|
|
||||||
- Sebastien Estienne
|
|
||||||
- Simon Sapin
|
|
||||||
- Stephane Wirtel
|
|
||||||
- Thomas Schranz
|
|
||||||
- Zhao Xiaohong
|
|
||||||
|
|
|
||||||
211
CHANGES.rst
211
CHANGES.rst
|
|
@ -1,3 +1,5 @@
|
||||||
|
.. currentmodule:: flask
|
||||||
|
|
||||||
Flask Changelog
|
Flask Changelog
|
||||||
===============
|
===============
|
||||||
|
|
||||||
|
|
@ -11,114 +13,126 @@ unreleased
|
||||||
- Bump minimum dependency versions to the latest stable versions:
|
- Bump minimum dependency versions to the latest stable versions:
|
||||||
Werkzeug >= 0.14, Jinja >= 2.10, itsdangerous >= 0.24, Click >= 5.1.
|
Werkzeug >= 0.14, Jinja >= 2.10, itsdangerous >= 0.24, Click >= 5.1.
|
||||||
(`#2586`_)
|
(`#2586`_)
|
||||||
- Make ``app.run()`` into a noop if a Flask application is run from the
|
- Skip :meth:`app.run <Flask.run>` when a Flask application is run from
|
||||||
development server on the command line. This avoids some behavior that
|
the command line. This avoids some behavior that was confusing to
|
||||||
was confusing to debug for newcomers.
|
debug.
|
||||||
- Change default configuration ``JSONIFY_PRETTYPRINT_REGULAR=False``.
|
- Change the default for :data:`JSONIFY_PRETTYPRINT_REGULAR` to
|
||||||
``jsonify()`` method returns compressed response by default, and pretty
|
``False``. :func:`~json.jsonify` returns a compact format by default,
|
||||||
response in debug mode. (`#2193`_)
|
and an indented format in debug mode. (`#2193`_)
|
||||||
- Change ``Flask.__init__`` to accept two new keyword arguments,
|
- :meth:`Flask.__init__ <Flask>` accepts the ``host_matching`` argument
|
||||||
``host_matching`` and ``static_host``. This enables ``host_matching`` to be
|
and sets it on :attr:`~Flask.url_map`. (`#1559`_)
|
||||||
set properly by the time the constructor adds the static route, and enables
|
- :meth:`Flask.__init__ <Flask>` accepts the ``static_host`` argument
|
||||||
the static route to be properly associated with the required host.
|
and passes it as the ``host`` argument when defining the static route.
|
||||||
(``#1559``)
|
(`#1559`_)
|
||||||
- ``send_file`` supports Unicode in ``attachment_filename``. (`#2223`_)
|
- :func:`send_file` supports Unicode in ``attachment_filename``.
|
||||||
- Pass ``_scheme`` argument from ``url_for`` to ``handle_build_error``.
|
(`#2223`_)
|
||||||
(`#2017`_)
|
- Pass ``_scheme`` argument from :func:`url_for` to
|
||||||
- Add support for ``provide_automatic_options`` in ``add_url_rule`` to disable
|
:meth:`~Flask.handle_url_build_error`. (`#2017`_)
|
||||||
adding OPTIONS method when the ``view_func`` argument is not a class.
|
- :meth:`~Flask.add_url_rule` accepts the ``provide_automatic_options``
|
||||||
(`#1489`_).
|
argument to disable adding the ``OPTIONS`` method. (`#1489`_)
|
||||||
- ``MethodView`` can inherit method handlers from base classes. (`#1936`_)
|
- :class:`~views.MethodView` subclasses inherit method handlers from
|
||||||
- Errors caused while opening the session at the beginning of the request are
|
base classes. (`#1936`_)
|
||||||
handled by the app's error handlers. (`#2254`_)
|
- Errors caused while opening the session at the beginning of the
|
||||||
- Blueprints gained ``json_encoder`` and ``json_decoder`` attributes to
|
request are handled by the app's error handlers. (`#2254`_)
|
||||||
override the app's encoder and decoder. (`#1898`_)
|
- Blueprints gained :attr:`~Blueprint.json_encoder` and
|
||||||
- ``Flask.make_response`` raises ``TypeError`` instead of ``ValueError`` for
|
:attr:`~Blueprint.json_decoder` attributes to override the app's
|
||||||
bad response types. The error messages have been improved to describe why the
|
encoder and decoder. (`#1898`_)
|
||||||
type is invalid. (`#2256`_)
|
- :meth:`Flask.make_response` raises ``TypeError`` instead of
|
||||||
- Add ``routes`` CLI command to output routes registered on the application.
|
``ValueError`` for bad response types. The error messages have been
|
||||||
(`#2259`_)
|
improved to describe why the type is invalid. (`#2256`_)
|
||||||
|
- Add ``routes`` CLI command to output routes registered on the
|
||||||
|
application. (`#2259`_)
|
||||||
- Show warning when session cookie domain is a bare hostname or an IP
|
- Show warning when session cookie domain is a bare hostname or an IP
|
||||||
address, as these may not behave properly in some browsers, such as Chrome.
|
address, as these may not behave properly in some browsers, such as
|
||||||
(`#2282`_)
|
Chrome. (`#2282`_)
|
||||||
- Allow IP address as exact session cookie domain. (`#2282`_)
|
- Allow IP address as exact session cookie domain. (`#2282`_)
|
||||||
- ``SESSION_COOKIE_DOMAIN`` is set if it is detected through ``SERVER_NAME``.
|
- ``SESSION_COOKIE_DOMAIN`` is set if it is detected through
|
||||||
(`#2282`_)
|
``SERVER_NAME``. (`#2282`_)
|
||||||
- Auto-detect zero-argument app factory called ``create_app`` or ``make_app``
|
- Auto-detect zero-argument app factory called ``create_app`` or
|
||||||
from ``FLASK_APP``. (`#2297`_)
|
``make_app`` from ``FLASK_APP``. (`#2297`_)
|
||||||
- Factory functions are not required to take a ``script_info`` parameter to
|
- Factory functions are not required to take a ``script_info`` parameter
|
||||||
work with the ``flask`` command. If they take a single parameter or a
|
to work with the ``flask`` command. If they take a single parameter or
|
||||||
parameter named ``script_info``, the ``ScriptInfo`` object will be passed.
|
a parameter named ``script_info``, the :class:`~cli.ScriptInfo` object
|
||||||
(`#2319`_)
|
will be passed. (`#2319`_)
|
||||||
- FLASK_APP=myproject.app:create_app('dev') support.
|
- ``FLASK_APP`` can be set to an app factory, with arguments if needed,
|
||||||
- ``FLASK_APP`` can be set to an app factory, with arguments if needed, for
|
for example ``FLASK_APP=myproject.app:create_app('dev')``. (`#2326`_)
|
||||||
example ``FLASK_APP=myproject.app:create_app('dev')``. (`#2326`_)
|
- ``FLASK_APP`` can point to local packages that are not installed in
|
||||||
- ``FLASK_APP`` can point to local packages that are not installed in dev mode,
|
editable mode, although ``pip install -e`` is still preferred.
|
||||||
although `pip install -e` should still be preferred. (`#2414`_)
|
(`#2414`_)
|
||||||
- ``View.provide_automatic_options = True`` is set on the view function from
|
- The :class:`~views.View` class attribute
|
||||||
``View.as_view``, to be detected in ``app.add_url_rule``. (`#2316`_)
|
:attr:`~views.View.provide_automatic_options` is set in
|
||||||
|
:meth:`~views.View.as_view`, to be detected by
|
||||||
|
:meth:`~Flask.add_url_rule`. (`#2316`_)
|
||||||
- Error handling will try handlers registered for ``blueprint, code``,
|
- Error handling will try handlers registered for ``blueprint, code``,
|
||||||
``app, code``, ``blueprint, exception``, ``app, exception``. (`#2314`_)
|
``app, code``, ``blueprint, exception``, ``app, exception``.
|
||||||
- ``Cookie`` is added to the response's ``Vary`` header if the session is
|
(`#2314`_)
|
||||||
accessed at all during the request (and it wasn't deleted). (`#2288`_)
|
- ``Cookie`` is added to the response's ``Vary`` header if the session
|
||||||
- ``app.test_request_context()`` take ``subdomain`` and ``url_scheme``
|
is accessed at all during the request (and not deleted). (`#2288`_)
|
||||||
parameters for use when building base URL. (`#1621`_)
|
- :meth:`~Flask.test_request_context` accepts ``subdomain`` and
|
||||||
- Set ``APPLICATION_ROOT = '/'`` by default. This was already the implicit
|
``url_scheme`` arguments for use when building the base URL.
|
||||||
default when it was set to ``None``.
|
(`#1621`_)
|
||||||
- ``TRAP_BAD_REQUEST_ERRORS`` is enabled by default in debug mode.
|
- Set :data:`APPLICATION_ROOT` to ``'/'`` by default. This was already
|
||||||
``BadRequestKeyError`` has a message with the bad key in debug mode instead
|
the implicit default when it was set to ``None``.
|
||||||
of the generic bad request message. (`#2348`_)
|
- :data:`TRAP_BAD_REQUEST_ERRORS` is enabled by default in debug mode.
|
||||||
- Allow registering new tags with ``TaggedJSONSerializer`` to support
|
``BadRequestKeyError`` has a message with the bad key in debug mode
|
||||||
storing other types in the session cookie. (`#2352`_)
|
instead of the generic bad request message. (`#2348`_)
|
||||||
- Only open the session if the request has not been pushed onto the context
|
- Allow registering new tags with
|
||||||
stack yet. This allows ``stream_with_context`` generators to access the same
|
:class:`~json.tag.TaggedJSONSerializer` to support storing other types
|
||||||
session that the containing view uses. (`#2354`_)
|
in the session cookie. (`#2352`_)
|
||||||
- Add ``json`` keyword argument for the test client request methods. This will
|
- Only open the session if the request has not been pushed onto the
|
||||||
dump the given object as JSON and set the appropriate content type.
|
context stack yet. This allows :func:`~stream_with_context`
|
||||||
(`#2358`_)
|
generators to access the same session that the containing view uses.
|
||||||
- Extract JSON handling to a mixin applied to both the request and response
|
(`#2354`_)
|
||||||
classes used by Flask. This adds the ``is_json`` and ``get_json`` methods to
|
- Add ``json`` keyword argument for the test client request methods.
|
||||||
the response to make testing JSON response much easier. (`#2358`_)
|
This will dump the given object as JSON and set the appropriate
|
||||||
- Removed error handler caching because it caused unexpected results for some
|
content type. (`#2358`_)
|
||||||
exception inheritance hierarchies. Register handlers explicitly for each
|
- Extract JSON handling to a mixin applied to both the :class:`Request`
|
||||||
exception if you don't want to traverse the MRO. (`#2362`_)
|
and :class:`Response` classes. This adds the :meth:`~Response.is_json`
|
||||||
|
and :meth:`~Response.get_json` methods to the response to make testing
|
||||||
|
JSON response much easier. (`#2358`_)
|
||||||
|
- Removed error handler caching because it caused unexpected results for
|
||||||
|
some exception inheritance hierarchies. Register handlers explicitly
|
||||||
|
for each exception if you want to avoid traversing the MRO. (`#2362`_)
|
||||||
- Fix incorrect JSON encoding of aware, non-UTC datetimes. (`#2374`_)
|
- Fix incorrect JSON encoding of aware, non-UTC datetimes. (`#2374`_)
|
||||||
- Template auto reloading will honor the ``run`` command's ``debug`` flag even
|
- Template auto reloading will honor debug mode even even if
|
||||||
if ``app.jinja_env`` was already accessed. (`#2373`_)
|
:attr:`~Flask.jinja_env` was already accessed. (`#2373`_)
|
||||||
- The following old deprecated code was removed. (`#2385`_)
|
- The following old deprecated code was removed. (`#2385`_)
|
||||||
|
|
||||||
- ``flask.ext`` - import extensions directly by their name instead of
|
- ``flask.ext`` - import extensions directly by their name instead of
|
||||||
through the ``flask.ext`` namespace. For example,
|
through the ``flask.ext`` namespace. For example,
|
||||||
``import flask.ext.sqlalchemy`` becomes ``import flask_sqlalchemy``.
|
``import flask.ext.sqlalchemy`` becomes ``import flask_sqlalchemy``.
|
||||||
- ``Flask.init_jinja_globals`` - extend ``Flask.create_jinja_environment``
|
- ``Flask.init_jinja_globals`` - extend
|
||||||
instead.
|
:meth:`Flask.create_jinja_environment` instead.
|
||||||
- ``Flask.error_handlers`` - tracked by ``Flask.error_handler_spec``,
|
- ``Flask.error_handlers`` - tracked by
|
||||||
use ``@app.errorhandler`` to register handlers.
|
:attr:`Flask.error_handler_spec`, use :meth:`Flask.errorhandler` to
|
||||||
- ``Flask.request_globals_class`` - use ``Flask.app_ctx_globals_class``
|
register handlers.
|
||||||
instead.
|
- ``Flask.request_globals_class`` - use
|
||||||
- ``Flask.static_path`` - use ``Flask.static_url_path`` instead.
|
:attr:`Flask.app_ctx_globals_class` instead.
|
||||||
- ``Request.module`` - use ``Request.blueprint`` instead.
|
- ``Flask.static_path`` - use :attr:`Flask.static_url_path` instead.
|
||||||
|
- ``Request.module`` - use :attr:`Request.blueprint` instead.
|
||||||
|
|
||||||
- The ``request.json`` property is no longer deprecated. (`#1421`_)
|
- The :attr:`Request.json` property is no longer deprecated. (`#1421`_)
|
||||||
- Support passing an existing ``EnvironBuilder`` or ``dict`` to
|
- Support passing a :class:`~werkzeug.test.EnvironBuilder` or
|
||||||
``test_client.open``. (`#2412`_)
|
``dict`` to :meth:`test_client.open <werkzeug.test.Client.open>`.
|
||||||
- The ``flask`` command and ``app.run`` will load environment variables using
|
(`#2412`_)
|
||||||
from ``.env`` and ``.flaskenv`` files if python-dotenv is installed.
|
- The ``flask`` command and :meth:`Flask.run` will load environment
|
||||||
(`#2416`_)
|
variables from ``.env`` and ``.flaskenv`` files if python-dotenv is
|
||||||
- When passing a full URL to the test client, use the scheme in the URL instead
|
installed. (`#2416`_)
|
||||||
of the ``PREFERRED_URL_SCHEME``. (`#2430`_)
|
- When passing a full URL to the test client, the scheme in the URL is
|
||||||
- ``app.logger`` has been simplified. ``LOGGER_NAME`` and
|
used instead of :data:`PREFERRED_URL_SCHEME`. (`#2430`_)
|
||||||
``LOGGER_HANDLER_POLICY`` config was removed. The logger is always named
|
- :attr:`Flask.logger` has been simplified. ``LOGGER_NAME`` and
|
||||||
``flask.app``. The level is only set on first access, it doesn't check
|
``LOGGER_HANDLER_POLICY`` config was removed. The logger is always
|
||||||
``app.debug`` each time. Only one format is used, not different ones
|
named ``flask.app``. The level is only set on first access, it doesn't
|
||||||
depending on ``app.debug``. No handlers are removed, and a handler is only
|
check :attr:`Flask.debug` each time. Only one format is used, not
|
||||||
added if no handlers are already configured. (`#2436`_)
|
different ones depending on :attr:`Flask.debug`. No handlers are
|
||||||
- Blueprint view function name may not contain dots. (`#2450`_)
|
removed, and a handler is only added if no handlers are already
|
||||||
- Fix a ``ValueError`` caused by invalid Range requests in some cases.
|
configured. (`#2436`_)
|
||||||
(`#2526`_)
|
- Blueprint view function names may not contain dots. (`#2450`_)
|
||||||
- The dev server now uses threads by default. (`#2529`_)
|
- Fix a ``ValueError`` caused by invalid ``Range`` requests in some
|
||||||
- Loading config files with ``silent=True`` will ignore ``ENOTDIR``
|
cases. (`#2526`_)
|
||||||
errors. (`#2581`_)
|
- The development server uses threads by default. (`#2529`_)
|
||||||
|
- Loading config files with ``silent=True`` will ignore
|
||||||
|
:data:`~errno.ENOTDIR` errors. (`#2581`_)
|
||||||
- Pass ``--cert`` and ``--key`` options to ``flask run`` to run the
|
- Pass ``--cert`` and ``--key`` options to ``flask run`` to run the
|
||||||
development server over HTTPS. (`#2606`_)
|
development server over HTTPS. (`#2606`_)
|
||||||
- Added :data:`SESSION_COOKIE_SAMESITE` to control the ``SameSite``
|
- Added :data:`SESSION_COOKIE_SAMESITE` to control the ``SameSite``
|
||||||
|
|
@ -127,6 +141,7 @@ unreleased
|
||||||
.. _pallets/meta#24: https://github.com/pallets/meta/issues/24
|
.. _pallets/meta#24: https://github.com/pallets/meta/issues/24
|
||||||
.. _#1421: https://github.com/pallets/flask/issues/1421
|
.. _#1421: https://github.com/pallets/flask/issues/1421
|
||||||
.. _#1489: https://github.com/pallets/flask/pull/1489
|
.. _#1489: https://github.com/pallets/flask/pull/1489
|
||||||
|
.. _#1559: https://github.com/pallets/flask/issues/1559
|
||||||
.. _#1621: https://github.com/pallets/flask/pull/1621
|
.. _#1621: https://github.com/pallets/flask/pull/1621
|
||||||
.. _#1898: https://github.com/pallets/flask/pull/1898
|
.. _#1898: https://github.com/pallets/flask/pull/1898
|
||||||
.. _#1936: https://github.com/pallets/flask/pull/1936
|
.. _#1936: https://github.com/pallets/flask/pull/1936
|
||||||
|
|
|
||||||
|
|
@ -131,8 +131,22 @@ Read more about `coverage <https://coverage.readthedocs.io>`_.
|
||||||
Running the full test suite with ``tox`` will combine the coverage reports
|
Running the full test suite with ``tox`` will combine the coverage reports
|
||||||
from all runs.
|
from all runs.
|
||||||
|
|
||||||
``make`` targets
|
|
||||||
~~~~~~~~~~~~~~~~
|
Building the docs
|
||||||
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Build the docs in the ``docs`` directory using Sphinx::
|
||||||
|
|
||||||
|
cd docs
|
||||||
|
make html
|
||||||
|
|
||||||
|
Open ``_build/html/index.html`` in your browser to view the docs.
|
||||||
|
|
||||||
|
Read more about `Sphinx <http://www.sphinx-doc.org>`_.
|
||||||
|
|
||||||
|
|
||||||
|
make targets
|
||||||
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
Flask provides a ``Makefile`` with various shortcuts. They will ensure that
|
Flask provides a ``Makefile`` with various shortcuts. They will ensure that
|
||||||
all dependencies are installed.
|
all dependencies are installed.
|
||||||
|
|
|
||||||
48
LICENSE
48
LICENSE
|
|
@ -1,33 +1,31 @@
|
||||||
Copyright (c) 2015 by Armin Ronacher and contributors. See AUTHORS
|
Copyright © 2010 by the Pallets team.
|
||||||
for more details.
|
|
||||||
|
|
||||||
Some rights reserved.
|
Some rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms of the software as well
|
Redistribution and use in source and binary forms of the software as
|
||||||
as documentation, with or without modification, are permitted provided
|
well as documentation, with or without modification, are permitted
|
||||||
that the following conditions are met:
|
provided that the following conditions are met:
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
* Redistributions of source code must retain the above copyright notice,
|
||||||
notice, this list of conditions and the following disclaimer.
|
this list of conditions and the following disclaimer.
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
copyright notice, this list of conditions and the following
|
notice, this list of conditions and the following disclaimer in the
|
||||||
disclaimer in the documentation and/or other materials provided
|
documentation and/or other materials provided with the distribution.
|
||||||
with the distribution.
|
|
||||||
|
|
||||||
* The names of the contributors may not be used to endorse or
|
* Neither the name of the copyright holder nor the names of its
|
||||||
promote products derived from this software without specific
|
contributors may be used to endorse or promote products derived from
|
||||||
prior written permission.
|
this software without specific prior written permission.
|
||||||
|
|
||||||
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
|
||||||
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
|
THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
DAMAGE.
|
SUCH DAMAGE.
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
include Makefile CHANGES LICENSE AUTHORS tox.ini
|
include Makefile CHANGES.rst LICENSE AUTHORS tox.ini
|
||||||
|
|
||||||
graft artwork
|
graft artwork
|
||||||
graft tests
|
graft tests
|
||||||
|
|
|
||||||
18
Makefile
18
Makefile
|
|
@ -9,7 +9,6 @@ test: clean-pyc install-dev
|
||||||
pytest
|
pytest
|
||||||
|
|
||||||
coverage: clean-pyc install-dev
|
coverage: clean-pyc install-dev
|
||||||
pip install -q -e .[test]
|
|
||||||
coverage run -m pytest
|
coverage run -m pytest
|
||||||
coverage report
|
coverage report
|
||||||
coverage html
|
coverage html
|
||||||
|
|
@ -34,20 +33,3 @@ clean-pyc:
|
||||||
find . -name '*.pyc' -exec rm -f {} +
|
find . -name '*.pyc' -exec rm -f {} +
|
||||||
find . -name '*.pyo' -exec rm -f {} +
|
find . -name '*.pyo' -exec rm -f {} +
|
||||||
find . -name '*~' -exec rm -f {} +
|
find . -name '*~' -exec rm -f {} +
|
||||||
|
|
||||||
upload-docs:
|
|
||||||
$(MAKE) -C docs html dirhtml latex epub
|
|
||||||
$(MAKE) -C docs/_build/latex all-pdf
|
|
||||||
cd docs/_build/; mv html flask-docs; zip -r flask-docs.zip flask-docs; mv flask-docs html
|
|
||||||
rsync -a docs/_build/dirhtml/ flow.srv.pocoo.org:/srv/websites/flask.pocoo.org/docs/
|
|
||||||
rsync -a docs/_build/latex/Flask.pdf flow.srv.pocoo.org:/srv/websites/flask.pocoo.org/docs/flask-docs.pdf
|
|
||||||
rsync -a docs/_build/flask-docs.zip flow.srv.pocoo.org:/srv/websites/flask.pocoo.org/docs/flask-docs.zip
|
|
||||||
rsync -a docs/_build/epub/Flask.epub flow.srv.pocoo.org:/srv/websites/flask.pocoo.org/docs/flask-docs.epub
|
|
||||||
|
|
||||||
# ebook-convert docs: http://manual.calibre-ebook.com/cli/ebook-convert.html
|
|
||||||
ebook:
|
|
||||||
@echo 'Using .epub from `make upload-docs` to create .mobi.'
|
|
||||||
@echo 'Command `ebook-covert` is provided by calibre package.'
|
|
||||||
@echo 'Requires X-forwarding for Qt features used in conversion (ssh -X).'
|
|
||||||
@echo 'Do not mind "Invalid value for ..." CSS errors if .mobi renders.'
|
|
||||||
ssh -X pocoo.org ebook-convert /var/www/flask.pocoo.org/docs/flask-docs.epub /var/www/flask.pocoo.org/docs/flask-docs.mobi --cover http://flask.pocoo.org/docs/_images/logo-full.png --authors 'Armin Ronacher'
|
|
||||||
|
|
|
||||||
49
README
49
README
|
|
@ -1,49 +0,0 @@
|
||||||
|
|
||||||
|
|
||||||
// Flask //
|
|
||||||
|
|
||||||
web development, one drop at a time
|
|
||||||
|
|
||||||
|
|
||||||
~ What is Flask?
|
|
||||||
|
|
||||||
Flask is a microframework for Python based on Werkzeug
|
|
||||||
and Jinja2. It's intended for getting started very quickly
|
|
||||||
and was developed with best intentions in mind.
|
|
||||||
|
|
||||||
~ Is it ready?
|
|
||||||
|
|
||||||
It's still not 1.0 but it's shaping up nicely and is
|
|
||||||
already widely used. Consider the API to slightly
|
|
||||||
improve over time but we don't plan on breaking it.
|
|
||||||
|
|
||||||
~ What do I need?
|
|
||||||
|
|
||||||
All dependencies are installed by using `pip install Flask`.
|
|
||||||
We encourage you to use a virtualenv. Check the docs for
|
|
||||||
complete installation and usage instructions.
|
|
||||||
|
|
||||||
~ Where are the docs?
|
|
||||||
|
|
||||||
Go to http://flask.pocoo.org/docs/ for a prebuilt version
|
|
||||||
of the current documentation. Otherwise build them yourself
|
|
||||||
from the sphinx sources in the docs folder.
|
|
||||||
|
|
||||||
~ Where are the tests?
|
|
||||||
|
|
||||||
Good that you're asking. The tests are in the
|
|
||||||
tests/ folder. To run the tests use the
|
|
||||||
`pytest` testing tool:
|
|
||||||
|
|
||||||
$ pytest
|
|
||||||
|
|
||||||
Details on contributing can be found in CONTRIBUTING.rst
|
|
||||||
|
|
||||||
~ Where can I get help?
|
|
||||||
|
|
||||||
Either use the #pocoo IRC channel on irc.freenode.net or
|
|
||||||
ask on the mailinglist: http://flask.pocoo.org/mailinglist/
|
|
||||||
|
|
||||||
See http://flask.pocoo.org/community/ for more resources.
|
|
||||||
|
|
||||||
|
|
||||||
62
README.rst
Normal file
62
README.rst
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
Flask
|
||||||
|
=====
|
||||||
|
|
||||||
|
Flask is a lightweight `WSGI`_ web application framework. It is designed
|
||||||
|
to make getting started quick and easy, with the ability to scale up to
|
||||||
|
complex applications. It began as a simple wrapper around `Werkzeug`_
|
||||||
|
and `Jinja`_ and has become one of the most popular Python web
|
||||||
|
application frameworks.
|
||||||
|
|
||||||
|
Flask offers suggestions, but doesn't enforce any dependencies or
|
||||||
|
project layout. It is up to the developer to choose the tools and
|
||||||
|
libraries they want to use. There are many extensions provided by the
|
||||||
|
community that make adding new functionality easy.
|
||||||
|
|
||||||
|
|
||||||
|
Installing
|
||||||
|
----------
|
||||||
|
|
||||||
|
Install and update using `pip`_:
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
pip install -U Flask
|
||||||
|
|
||||||
|
|
||||||
|
A Simple Example
|
||||||
|
----------------
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
from flask import Flask
|
||||||
|
|
||||||
|
app = Flask(__name__)
|
||||||
|
|
||||||
|
@app.route('/')
|
||||||
|
def hello():
|
||||||
|
return 'Hello, World!'
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
$ FLASK_APP=hello.py flask run
|
||||||
|
* Running on http://localhost:5000/
|
||||||
|
|
||||||
|
|
||||||
|
Links
|
||||||
|
-----
|
||||||
|
|
||||||
|
* Website: https://www.palletsprojects.com/p/flask/
|
||||||
|
* Releases: https://pypi.org/project/Flask/
|
||||||
|
* Code: https://github.com/pallets/flask
|
||||||
|
* Issue tracker: https://github.com/pallets/flask/issues
|
||||||
|
* Test status:
|
||||||
|
|
||||||
|
* Linux, Mac: https://travis-ci.org/pallets/flask
|
||||||
|
* Windows: https://ci.appveyor.com/project/pallets/flask
|
||||||
|
|
||||||
|
* Test coverage: https://codecov.io/gh/pallets/flask
|
||||||
|
|
||||||
|
.. _WSGI: https://wsgi.readthedocs.io
|
||||||
|
.. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/
|
||||||
|
.. _Jinja: https://www.palletsprojects.com/p/jinja/
|
||||||
|
.. _pip: https://pip.pypa.io/en/stable/quickstart/
|
||||||
|
|
@ -4,28 +4,23 @@ Welcome to Flask
|
||||||
================
|
================
|
||||||
|
|
||||||
.. image:: _static/logo-full.png
|
.. image:: _static/logo-full.png
|
||||||
:alt: Flask: web development, one drop at a time
|
:alt: Flask: web development, one drop at a time
|
||||||
:class: floatingflask
|
:class: floatingflask
|
||||||
|
|
||||||
Welcome to Flask's documentation. This documentation is divided into
|
Welcome to Flask's documentation. Get started with :ref:`installation`
|
||||||
different parts. I recommend that you get started with
|
and then get an overview with the :ref:`quickstart`. There is also a
|
||||||
:ref:`installation` and then head over to the :ref:`quickstart`.
|
more detailed :ref:`tutorial` that shows how to create a small but
|
||||||
Besides the quickstart, there is also a more detailed :ref:`tutorial` that
|
complete application with Flask. Common patterns are described in the
|
||||||
shows how to create a complete (albeit small) application with Flask. If
|
:ref:`patterns` section. The rest of the docs desribe each component of
|
||||||
you'd rather dive into the internals of Flask, check out
|
Flask in detail, with a full reference in the :ref:`api` section.
|
||||||
the :ref:`api` documentation. Common patterns are described in the
|
|
||||||
:ref:`patterns` section.
|
|
||||||
|
|
||||||
Flask depends on two external libraries: the `Jinja2`_ template
|
Flask depends on the `Jinja`_ template engine and the `Werkzeug`_ WSGI
|
||||||
engine and the `Werkzeug`_ WSGI toolkit. These libraries are not documented
|
toolkit. The documentation for these libraries can be found at:
|
||||||
here. If you want to dive into their documentation, check out the
|
|
||||||
following links:
|
|
||||||
|
|
||||||
- `Jinja2 Documentation <http://jinja.pocoo.org/docs>`_
|
- `Jinja documentation <http://jinja.pocoo.org/docs>`_
|
||||||
- `Werkzeug Documentation <http://werkzeug.pocoo.org/docs>`_
|
- `Werkzeug documentation <http://werkzeug.pocoo.org/docs>`_
|
||||||
|
|
||||||
|
.. _Jinja: https://www.palletsprojects.com/p/jinja/
|
||||||
.. _Jinja2: http://jinja.pocoo.org/
|
.. _Werkzeug: https://www.palletsprojects.com/p/werkzeug/
|
||||||
.. _Werkzeug: http://werkzeug.pocoo.org/
|
|
||||||
|
|
||||||
.. include:: contents.rst.inc
|
.. include:: contents.rst.inc
|
||||||
|
|
|
||||||
|
|
@ -1,309 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
Flask Extension Tests
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Tests the Flask extensions.
|
|
||||||
|
|
||||||
:copyright: (c) 2015 by Ali Afshar.
|
|
||||||
:license: BSD, see LICENSE for more details.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import shutil
|
|
||||||
import urllib2
|
|
||||||
import tempfile
|
|
||||||
import subprocess
|
|
||||||
import argparse
|
|
||||||
|
|
||||||
from flask import json
|
|
||||||
|
|
||||||
from setuptools.package_index import PackageIndex
|
|
||||||
from setuptools.archive_util import unpack_archive
|
|
||||||
|
|
||||||
flask_svc_url = 'http://flask.pocoo.org/extensions/'
|
|
||||||
|
|
||||||
|
|
||||||
# OS X has awful paths when using mkstemp or gettempdir(). I don't
|
|
||||||
# care about security or clashes here, so pick something that is
|
|
||||||
# actually memorable.
|
|
||||||
if sys.platform == 'darwin':
|
|
||||||
_tempdir = '/private/tmp'
|
|
||||||
else:
|
|
||||||
_tempdir = tempfile.gettempdir()
|
|
||||||
tdir = _tempdir + '/flaskext-test'
|
|
||||||
flaskdir = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
|
|
||||||
|
|
||||||
|
|
||||||
# virtualenv hack *cough*
|
|
||||||
os.environ['PYTHONDONTWRITEBYTECODE'] = ''
|
|
||||||
|
|
||||||
|
|
||||||
RESULT_TEMPATE = u'''\
|
|
||||||
<!doctype html>
|
|
||||||
<title>Flask-Extension Test Results</title>
|
|
||||||
<style type=text/css>
|
|
||||||
body { font-family: 'Georgia', serif; font-size: 17px; color: #000; }
|
|
||||||
a { color: #004B6B; }
|
|
||||||
a:hover { color: #6D4100; }
|
|
||||||
h1, h2, h3 { font-family: 'Garamond', 'Georgia', serif; font-weight: normal; }
|
|
||||||
h1 { font-size: 30px; margin: 15px 0 5px 0; }
|
|
||||||
h2 { font-size: 24px; margin: 15px 0 5px 0; }
|
|
||||||
h3 { font-size: 19px; margin: 15px 0 5px 0; }
|
|
||||||
textarea, code,
|
|
||||||
pre { font-family: 'Consolas', 'Menlo', 'Deja Vu Sans Mono',
|
|
||||||
'Bitstream Vera Sans Mono', monospace!important; font-size: 15px;
|
|
||||||
background: #eee; }
|
|
||||||
pre { padding: 7px 15px; line-height: 1.3; }
|
|
||||||
p { line-height: 1.4; }
|
|
||||||
table { border: 1px solid black; border-collapse: collapse;
|
|
||||||
margin: 15px 0; }
|
|
||||||
td, th { border: 1px solid black; padding: 4px 10px;
|
|
||||||
text-align: left; }
|
|
||||||
th { background: #eee; font-weight: normal; }
|
|
||||||
tr.success { background: #D3F5CC; }
|
|
||||||
tr.failed { background: #F5D2CB; }
|
|
||||||
</style>
|
|
||||||
<h1>Flask-Extension Test Results</h1>
|
|
||||||
<p>
|
|
||||||
This page contains the detailed test results for the test run of
|
|
||||||
all {{ 'approved' if approved }} Flask extensions.
|
|
||||||
<h2>Summary</h2>
|
|
||||||
<table class=results>
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th>Extension
|
|
||||||
<th>Version
|
|
||||||
<th>Author
|
|
||||||
<th>License
|
|
||||||
<th>Outcome
|
|
||||||
{%- for iptr, _ in results[0].logs|dictsort %}
|
|
||||||
<th>{{ iptr }}
|
|
||||||
{%- endfor %}
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{%- for result in results %}
|
|
||||||
{% set outcome = 'success' if result.success else 'failed' %}
|
|
||||||
<tr class={{ outcome }}>
|
|
||||||
<th>{{ result.name }}
|
|
||||||
<td>{{ result.version }}
|
|
||||||
<td>{{ result.author }}
|
|
||||||
<td>{{ result.license }}
|
|
||||||
<td>{{ outcome }}
|
|
||||||
{%- for iptr, _ in result.logs|dictsort %}
|
|
||||||
<td><a href="#{{ result.name }}-{{ iptr }}">see log</a>
|
|
||||||
{%- endfor %}
|
|
||||||
</tr>
|
|
||||||
{%- endfor %}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
<h2>Test Logs</h2>
|
|
||||||
<p>Detailed test logs for all tests on all platforms:
|
|
||||||
{%- for result in results %}
|
|
||||||
{%- for iptr, log in result.logs|dictsort %}
|
|
||||||
<h3 id="{{ result.name }}-{{ iptr }}">
|
|
||||||
{{ result.name }} - {{ result.version }} [{{ iptr }}]</h3>
|
|
||||||
<pre>{{ log }}</pre>
|
|
||||||
{%- endfor %}
|
|
||||||
{%- endfor %}
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
def log(msg, *args):
|
|
||||||
print('[EXTTEST] ' + (msg % args))
|
|
||||||
|
|
||||||
|
|
||||||
class TestResult(object):
|
|
||||||
|
|
||||||
def __init__(self, name, folder, statuscode, interpreters):
|
|
||||||
intrptr = os.path.join(folder, '.tox/%s/bin/python'
|
|
||||||
% interpreters[0])
|
|
||||||
self.statuscode = statuscode
|
|
||||||
self.folder = folder
|
|
||||||
self.success = statuscode == 0
|
|
||||||
|
|
||||||
def fetch(field):
|
|
||||||
try:
|
|
||||||
c = subprocess.Popen([intrptr, 'setup.py',
|
|
||||||
'--' + field], cwd=folder,
|
|
||||||
stdout=subprocess.PIPE)
|
|
||||||
return c.communicate()[0].strip()
|
|
||||||
except OSError:
|
|
||||||
return '?'
|
|
||||||
self.name = name
|
|
||||||
self.license = fetch('license')
|
|
||||||
self.author = fetch('author')
|
|
||||||
self.version = fetch('version')
|
|
||||||
|
|
||||||
self.logs = {}
|
|
||||||
for interpreter in interpreters:
|
|
||||||
logfile = os.path.join(folder, '.tox/%s/log/test.log'
|
|
||||||
% interpreter)
|
|
||||||
if os.path.isfile(logfile):
|
|
||||||
self.logs[interpreter] = open(logfile).read()
|
|
||||||
else:
|
|
||||||
self.logs[interpreter] = ''
|
|
||||||
|
|
||||||
|
|
||||||
def create_tdir():
|
|
||||||
try:
|
|
||||||
shutil.rmtree(tdir)
|
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
os.mkdir(tdir)
|
|
||||||
|
|
||||||
|
|
||||||
def package_flask():
|
|
||||||
distfolder = tdir + '/.flask-dist'
|
|
||||||
c = subprocess.Popen(['python', 'setup.py', 'sdist', '--formats=gztar',
|
|
||||||
'--dist', distfolder], cwd=flaskdir)
|
|
||||||
c.wait()
|
|
||||||
return os.path.join(distfolder, os.listdir(distfolder)[0])
|
|
||||||
|
|
||||||
|
|
||||||
def get_test_command(checkout_dir):
|
|
||||||
if os.path.isfile(checkout_dir + '/Makefile'):
|
|
||||||
return 'make test'
|
|
||||||
return 'python setup.py test'
|
|
||||||
|
|
||||||
|
|
||||||
def fetch_extensions_list():
|
|
||||||
req = urllib2.Request(flask_svc_url, headers={'accept':'application/json'})
|
|
||||||
d = urllib2.urlopen(req).read()
|
|
||||||
data = json.loads(d)
|
|
||||||
for ext in data['extensions']:
|
|
||||||
yield ext
|
|
||||||
|
|
||||||
|
|
||||||
def checkout_extension(name):
|
|
||||||
log('Downloading extension %s to temporary folder', name)
|
|
||||||
root = os.path.join(tdir, name)
|
|
||||||
os.mkdir(root)
|
|
||||||
checkout_path = PackageIndex().download(name, root)
|
|
||||||
|
|
||||||
unpack_archive(checkout_path, root)
|
|
||||||
path = None
|
|
||||||
for fn in os.listdir(root):
|
|
||||||
path = os.path.join(root, fn)
|
|
||||||
if os.path.isdir(path):
|
|
||||||
break
|
|
||||||
log('Downloaded to %s', path)
|
|
||||||
return path
|
|
||||||
|
|
||||||
|
|
||||||
tox_template = """[tox]
|
|
||||||
envlist=%(env)s
|
|
||||||
|
|
||||||
[testenv]
|
|
||||||
deps=
|
|
||||||
%(deps)s
|
|
||||||
distribute
|
|
||||||
py
|
|
||||||
commands=bash flaskext-runtest.sh {envlogdir}/test.log
|
|
||||||
downloadcache=%(cache)s
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def create_tox_ini(checkout_path, interpreters, flask_dep):
|
|
||||||
tox_path = os.path.join(checkout_path, 'tox-flask-test.ini')
|
|
||||||
if not os.path.exists(tox_path):
|
|
||||||
with open(tox_path, 'w') as f:
|
|
||||||
f.write(tox_template % {
|
|
||||||
'env': ','.join(interpreters),
|
|
||||||
'cache': tdir,
|
|
||||||
'deps': flask_dep
|
|
||||||
})
|
|
||||||
return tox_path
|
|
||||||
|
|
||||||
|
|
||||||
def iter_extensions(only_approved=True):
|
|
||||||
for ext in fetch_extensions_list():
|
|
||||||
if ext['approved'] or not only_approved:
|
|
||||||
yield ext['name']
|
|
||||||
|
|
||||||
|
|
||||||
def test_extension(name, interpreters, flask_dep):
|
|
||||||
checkout_path = checkout_extension(name)
|
|
||||||
log('Running tests with tox in %s', checkout_path)
|
|
||||||
|
|
||||||
# figure out the test command and write a wrapper script. We
|
|
||||||
# can't write that directly into the tox ini because tox does
|
|
||||||
# not invoke the command from the shell so we have no chance
|
|
||||||
# to pipe the output into a logfile. The /dev/null hack is
|
|
||||||
# to trick py.test (if used) into not guessing widths from the
|
|
||||||
# invoking terminal.
|
|
||||||
test_command = get_test_command(checkout_path)
|
|
||||||
log('Test command: %s', test_command)
|
|
||||||
f = open(checkout_path + '/flaskext-runtest.sh', 'w')
|
|
||||||
f.write(test_command + ' &> "$1" < /dev/null\n')
|
|
||||||
f.close()
|
|
||||||
|
|
||||||
# if there is a tox.ini, remove it, it will cause troubles
|
|
||||||
# for us. Remove it if present, we are running tox ourselves
|
|
||||||
# afterall.
|
|
||||||
|
|
||||||
create_tox_ini(checkout_path, interpreters, flask_dep)
|
|
||||||
rv = subprocess.call(['tox', '-c', 'tox-flask-test.ini'], cwd=checkout_path)
|
|
||||||
return TestResult(name, checkout_path, rv, interpreters)
|
|
||||||
|
|
||||||
|
|
||||||
def run_tests(extensions, interpreters):
|
|
||||||
results = {}
|
|
||||||
create_tdir()
|
|
||||||
log('Packaging Flask')
|
|
||||||
flask_dep = package_flask()
|
|
||||||
log('Running extension tests')
|
|
||||||
log('Temporary Environment: %s', tdir)
|
|
||||||
for name in extensions:
|
|
||||||
log('Testing %s', name)
|
|
||||||
result = test_extension(name, interpreters, flask_dep)
|
|
||||||
if result.success:
|
|
||||||
log('Extension test succeeded')
|
|
||||||
else:
|
|
||||||
log('Extension test failed')
|
|
||||||
results[name] = result
|
|
||||||
return results
|
|
||||||
|
|
||||||
|
|
||||||
def render_results(results, approved):
|
|
||||||
from jinja2 import Template
|
|
||||||
items = results.values()
|
|
||||||
items.sort(key=lambda x: x.name.lower())
|
|
||||||
rv = Template(RESULT_TEMPATE, autoescape=True).render(results=items,
|
|
||||||
approved=approved)
|
|
||||||
fd, filename = tempfile.mkstemp(suffix='.html')
|
|
||||||
os.fdopen(fd, 'w').write(rv.encode('utf-8') + '\n')
|
|
||||||
return filename
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
|
||||||
parser = argparse.ArgumentParser(description='Runs Flask extension tests')
|
|
||||||
parser.add_argument('--all', dest='all', action='store_true',
|
|
||||||
help='run against all extensions, not just approved')
|
|
||||||
parser.add_argument('--browse', dest='browse', action='store_true',
|
|
||||||
help='show browser with the result summary')
|
|
||||||
parser.add_argument('--env', dest='env', default='py25,py26,py27',
|
|
||||||
help='the tox environments to run against')
|
|
||||||
parser.add_argument('--extension=', dest='extension', default=None,
|
|
||||||
help='tests a single extension')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
if args.extension is not None:
|
|
||||||
only_approved = False
|
|
||||||
extensions = [args.extension]
|
|
||||||
else:
|
|
||||||
only_approved = not args.all
|
|
||||||
extensions = iter_extensions(only_approved)
|
|
||||||
|
|
||||||
results = run_tests(extensions, [x.strip() for x in args.env.split(',')])
|
|
||||||
filename = render_results(results, only_approved)
|
|
||||||
if args.browse:
|
|
||||||
import webbrowser
|
|
||||||
webbrowser.open('file:///' + filename.lstrip('/'))
|
|
||||||
print('Results written to {}'.format(filename))
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
main()
|
|
||||||
82
scripts/make-release.py
Normal file → Executable file
82
scripts/make-release.py
Normal file → Executable file
|
|
@ -1,23 +1,13 @@
|
||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
"""
|
|
||||||
make-release
|
|
||||||
~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Helper script that performs a release. Does pretty much everything
|
|
||||||
automatically for us.
|
|
||||||
|
|
||||||
:copyright: (c) 2015 by Armin Ronacher.
|
|
||||||
:license: BSD, see LICENSE for more details.
|
|
||||||
"""
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
from datetime import datetime, date
|
import sys
|
||||||
from subprocess import Popen, PIPE
|
from datetime import date, datetime
|
||||||
|
from subprocess import PIPE, Popen
|
||||||
|
|
||||||
_date_clean_re = re.compile(r'(\d+)(st|nd|rd|th)')
|
_date_strip_re = re.compile(r'(?<=\d)(st|nd|rd|th)')
|
||||||
|
|
||||||
|
|
||||||
def parse_changelog():
|
def parse_changelog():
|
||||||
|
|
@ -25,18 +15,27 @@ def parse_changelog():
|
||||||
lineiter = iter(f)
|
lineiter = iter(f)
|
||||||
for line in lineiter:
|
for line in lineiter:
|
||||||
match = re.search('^Version\s+(.*)', line.strip())
|
match = re.search('^Version\s+(.*)', line.strip())
|
||||||
|
|
||||||
if match is None:
|
if match is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
version = match.group(1).strip()
|
version = match.group(1).strip()
|
||||||
if lineiter.next().count('-') != len(match.group(0)):
|
|
||||||
|
if next(lineiter).count('-') != len(match.group(0)):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
while 1:
|
while 1:
|
||||||
change_info = lineiter.next().strip()
|
change_info = next(lineiter).strip()
|
||||||
|
|
||||||
if change_info:
|
if change_info:
|
||||||
break
|
break
|
||||||
|
|
||||||
match = re.search(r'released on (\w+\s+\d+\w+\s+\d+)'
|
match = re.search(
|
||||||
r'(?:, codename (.*))?(?i)', change_info)
|
r'released on (\w+\s+\d+\w+\s+\d+)(?:, codename (.*))?',
|
||||||
|
change_info,
|
||||||
|
flags=re.IGNORECASE
|
||||||
|
)
|
||||||
|
|
||||||
if match is None:
|
if match is None:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
@ -46,15 +45,16 @@ def parse_changelog():
|
||||||
|
|
||||||
def bump_version(version):
|
def bump_version(version):
|
||||||
try:
|
try:
|
||||||
parts = map(int, version.split('.'))
|
parts = [int(i) for i in version.split('.')]
|
||||||
except ValueError:
|
except ValueError:
|
||||||
fail('Current version is not numeric')
|
fail('Current version is not numeric')
|
||||||
|
|
||||||
parts[-1] += 1
|
parts[-1] += 1
|
||||||
return '.'.join(map(str, parts))
|
return '.'.join(map(str, parts))
|
||||||
|
|
||||||
|
|
||||||
def parse_date(string):
|
def parse_date(string):
|
||||||
string = _date_clean_re.sub(r'\1', string)
|
string = _date_strip_re.sub('', string)
|
||||||
return datetime.strptime(string, '%B %d %Y')
|
return datetime.strptime(string, '%B %d %Y')
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -65,9 +65,13 @@ def set_filename_version(filename, version_number, pattern):
|
||||||
before, old, after = match.groups()
|
before, old, after = match.groups()
|
||||||
changed.append(True)
|
changed.append(True)
|
||||||
return before + version_number + after
|
return before + version_number + after
|
||||||
|
|
||||||
with open(filename) as f:
|
with open(filename) as f:
|
||||||
contents = re.sub(r"^(\s*%s\s*=\s*')(.+?)(')(?sm)" % pattern,
|
contents = re.sub(
|
||||||
inject_version, f.read())
|
r"^(\s*%s\s*=\s*')(.+?)(')" % pattern,
|
||||||
|
inject_version, f.read(),
|
||||||
|
flags=re.DOTALL | re.MULTILINE
|
||||||
|
)
|
||||||
|
|
||||||
if not changed:
|
if not changed:
|
||||||
fail('Could not find %s in %s', pattern, filename)
|
fail('Could not find %s in %s', pattern, filename)
|
||||||
|
|
@ -81,8 +85,9 @@ def set_init_version(version):
|
||||||
set_filename_version('flask/__init__.py', version, '__version__')
|
set_filename_version('flask/__init__.py', version, '__version__')
|
||||||
|
|
||||||
|
|
||||||
def build_and_upload():
|
def build():
|
||||||
Popen([sys.executable, 'setup.py', 'release', 'sdist', 'bdist_wheel', 'upload']).wait()
|
cmd = [sys.executable, 'setup.py', 'sdist', 'bdist_wheel']
|
||||||
|
Popen(cmd).wait()
|
||||||
|
|
||||||
|
|
||||||
def fail(message, *args):
|
def fail(message, *args):
|
||||||
|
|
@ -95,7 +100,9 @@ def info(message, *args):
|
||||||
|
|
||||||
|
|
||||||
def get_git_tags():
|
def get_git_tags():
|
||||||
return set(Popen(['git', 'tag'], stdout=PIPE).communicate()[0].splitlines())
|
return set(
|
||||||
|
Popen(['git', 'tag'], stdout=PIPE).communicate()[0].splitlines()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def git_is_clean():
|
def git_is_clean():
|
||||||
|
|
@ -116,29 +123,40 @@ def main():
|
||||||
os.chdir(os.path.join(os.path.dirname(__file__), '..'))
|
os.chdir(os.path.join(os.path.dirname(__file__), '..'))
|
||||||
|
|
||||||
rv = parse_changelog()
|
rv = parse_changelog()
|
||||||
|
|
||||||
if rv is None:
|
if rv is None:
|
||||||
fail('Could not parse changelog')
|
fail('Could not parse changelog')
|
||||||
|
|
||||||
version, release_date, codename = rv
|
version, release_date, codename = rv
|
||||||
dev_version = bump_version(version) + '-dev'
|
dev_version = bump_version(version) + '.dev'
|
||||||
|
|
||||||
info('Releasing %s (codename %s, release date %s)',
|
info(
|
||||||
version, codename, release_date.strftime('%d/%m/%Y'))
|
'Releasing %s (codename %s, release date %s)',
|
||||||
|
version, codename, release_date.strftime('%d/%m/%Y')
|
||||||
|
)
|
||||||
tags = get_git_tags()
|
tags = get_git_tags()
|
||||||
|
|
||||||
if version in tags:
|
if version in tags:
|
||||||
fail('Version "%s" is already tagged', version)
|
fail('Version "%s" is already tagged', version)
|
||||||
|
|
||||||
if release_date.date() != date.today():
|
if release_date.date() != date.today():
|
||||||
fail('Release date is not today (%s != %s)',
|
fail(
|
||||||
release_date.date(), date.today())
|
'Release date is not today (%s != %s)',
|
||||||
|
release_date.date(), date.today()
|
||||||
|
)
|
||||||
|
|
||||||
if not git_is_clean():
|
if not git_is_clean():
|
||||||
fail('You have uncommitted changes in git')
|
fail('You have uncommitted changes in git')
|
||||||
|
|
||||||
|
try:
|
||||||
|
import wheel # noqa: F401
|
||||||
|
except ImportError:
|
||||||
|
fail('You need to install the wheel package.')
|
||||||
|
|
||||||
set_init_version(version)
|
set_init_version(version)
|
||||||
make_git_commit('Bump version number to %s', version)
|
make_git_commit('Bump version number to %s', version)
|
||||||
make_git_tag(version)
|
make_git_tag(version)
|
||||||
build_and_upload()
|
build()
|
||||||
set_init_version(dev_version)
|
set_init_version(dev_version)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
[aliases]
|
[aliases]
|
||||||
release = egg_info -RDb ''
|
release = egg_info -Db ''
|
||||||
|
|
||||||
[bdist_wheel]
|
[bdist_wheel]
|
||||||
universal = 1
|
universal = 1
|
||||||
|
|
|
||||||
65
setup.py
Normal file → Executable file
65
setup.py
Normal file → Executable file
|
|
@ -1,74 +1,27 @@
|
||||||
"""
|
#!/usr/bin/env python
|
||||||
Flask
|
import io
|
||||||
-----
|
|
||||||
|
|
||||||
Flask is a microframework for Python based on Werkzeug, Jinja 2 and good
|
|
||||||
intentions. And before you ask: It's BSD licensed!
|
|
||||||
|
|
||||||
Flask is Fun
|
|
||||||
````````````
|
|
||||||
|
|
||||||
Save in a hello.py:
|
|
||||||
|
|
||||||
.. code:: python
|
|
||||||
|
|
||||||
from flask import Flask
|
|
||||||
app = Flask(__name__)
|
|
||||||
|
|
||||||
@app.route("/")
|
|
||||||
def hello():
|
|
||||||
return "Hello World!"
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
app.run()
|
|
||||||
|
|
||||||
And Easy to Setup
|
|
||||||
`````````````````
|
|
||||||
|
|
||||||
And run it:
|
|
||||||
|
|
||||||
.. code:: bash
|
|
||||||
|
|
||||||
$ pip install Flask
|
|
||||||
$ python hello.py
|
|
||||||
* Running on http://localhost:5000/
|
|
||||||
|
|
||||||
Ready for production? `Read this first <http://flask.pocoo.org/docs/deploying/>`.
|
|
||||||
|
|
||||||
Links
|
|
||||||
`````
|
|
||||||
|
|
||||||
* `website <http://flask.pocoo.org/>`_
|
|
||||||
* `documentation <http://flask.pocoo.org/docs/>`_
|
|
||||||
* `development version
|
|
||||||
<https://github.com/pallets/flask/zipball/master#egg=Flask-dev>`_
|
|
||||||
|
|
||||||
"""
|
|
||||||
import re
|
import re
|
||||||
import ast
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
|
|
||||||
_version_re = re.compile(r'__version__\s+=\s+(.*)')
|
with io.open('README.rst', 'rt', encoding='utf8') as f:
|
||||||
|
readme = f.read()
|
||||||
|
|
||||||
with open('flask/__init__.py', 'rb') as f:
|
with io.open('flask/__init__.py', 'rt', encoding='utf8') as f:
|
||||||
version = str(ast.literal_eval(_version_re.search(
|
version = re.search(r'__version__ = \'(.*?)\'', f.read()).group(1)
|
||||||
f.read().decode('utf-8')).group(1)))
|
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='Flask',
|
name='Flask',
|
||||||
version=version,
|
version=version,
|
||||||
url='https://github.com/pallets/flask/',
|
url='https://www.palletsprojects.com/p/flask/',
|
||||||
license='BSD',
|
license='BSD',
|
||||||
author='Armin Ronacher',
|
author='Armin Ronacher',
|
||||||
author_email='armin.ronacher@active-4.com',
|
author_email='armin.ronacher@active-4.com',
|
||||||
description='A microframework based on Werkzeug, Jinja2 '
|
description='A simple framework for building complex web applications.',
|
||||||
'and good intentions',
|
long_description=readme,
|
||||||
long_description=__doc__,
|
|
||||||
packages=['flask', 'flask.json'],
|
packages=['flask', 'flask.json'],
|
||||||
include_package_data=True,
|
include_package_data=True,
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
platforms='any',
|
platforms='any',
|
||||||
python_requires='>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
|
||||||
install_requires=[
|
install_requires=[
|
||||||
'Werkzeug>=0.14',
|
'Werkzeug>=0.14',
|
||||||
'Jinja2>=2.10',
|
'Jinja2>=2.10',
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
tox
|
|
||||||
pytest
|
|
||||||
pytest-cov
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue