mirror of https://github.com/mitsuhiko/flask.git
zhiguan
7 years ago
committed by
GitHub
96 changed files with 1658 additions and 1236 deletions
@ -0,0 +1,23 @@ |
|||||||
|
environment: |
||||||
|
global: |
||||||
|
TOXENV: py |
||||||
|
|
||||||
|
matrix: |
||||||
|
- PYTHON: C:\Python36 |
||||||
|
- PYTHON: C:\Python27 |
||||||
|
|
||||||
|
init: |
||||||
|
- SET PATH=%PYTHON%;%PATH% |
||||||
|
|
||||||
|
install: |
||||||
|
- python -m pip install -U pip setuptools wheel tox |
||||||
|
|
||||||
|
build: false |
||||||
|
|
||||||
|
test_script: |
||||||
|
- python -m tox |
||||||
|
|
||||||
|
branches: |
||||||
|
only: |
||||||
|
- master |
||||||
|
- /^.*-maintenance$/ |
@ -1,39 +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 |
|
||||||
- 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 |
|
||||||
|
@ -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,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. |
|
||||||
|
|
||||||
|
|
@ -0,0 +1,63 @@ |
|||||||
|
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/ |
||||||
|
* Documentation: http://flask.pocoo.org/docs/ |
||||||
|
* 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/ |
Before Width: | Height: | Size: 136 KiB After Width: | Height: | Size: 17 KiB |
@ -1 +1 @@ |
|||||||
.. include:: ../CHANGES |
.. include:: ../CHANGES.rst |
||||||
|
@ -1,58 +1,53 @@ |
|||||||
.. _extensions: |
.. _extensions: |
||||||
|
|
||||||
Flask Extensions |
Extensions |
||||||
================ |
========== |
||||||
|
|
||||||
|
Extensions are extra packages that add functionality to a Flask |
||||||
|
application. For example, an extension might add support for sending |
||||||
|
email or connecting to a database. Some extensions add entire new |
||||||
|
frameworks to help build certain types of applications, like a ReST API. |
||||||
|
|
||||||
Flask extensions extend the functionality of Flask in various different |
|
||||||
ways. For instance they add support for databases and other common tasks. |
|
||||||
|
|
||||||
Finding Extensions |
Finding Extensions |
||||||
------------------ |
------------------ |
||||||
|
|
||||||
Flask extensions are listed on the `Flask Extension Registry`_ and can be |
Flask extensions are usually named "Flask-Foo" or "Foo-Flask". Many |
||||||
downloaded with :command:`easy_install` or :command:`pip`. If you add a Flask extension |
extensions are listed in the `Extension Registry`_, which can be updated |
||||||
as dependency to your :file:`requirements.txt` or :file:`setup.py` file they are |
by extension developers. You can also search PyPI for packages tagged |
||||||
usually installed with a simple command or when your application installs. |
with `Framework :: Flask <pypi_>`_. |
||||||
|
|
||||||
|
|
||||||
Using Extensions |
Using Extensions |
||||||
---------------- |
---------------- |
||||||
|
|
||||||
Extensions typically have documentation that goes along that shows how to |
Consult each extension's documentation for installation, configuration, |
||||||
use it. There are no general rules in how extensions are supposed to |
and usage instructions. Generally, extensions pull their own |
||||||
behave but they are imported from common locations. If you have an |
configuration from :attr:`app.config <flask.Flask.config>` and are |
||||||
extension called ``Flask-Foo`` or ``Foo-Flask`` it should be always |
passed an application instance during initialization. For example, |
||||||
importable from ``flask_foo``:: |
an extension caled "Flask-Foo" might be used like this:: |
||||||
|
|
||||||
import flask_foo |
from flask_foo import Foo |
||||||
|
|
||||||
Building Extensions |
foo = Foo() |
||||||
------------------- |
|
||||||
|
|
||||||
While `Flask Extension Registry`_ contains many Flask extensions, you may not find |
app = Flask(__name__) |
||||||
an extension that fits your need. If this is the case, you can always create your own. |
app.config.update( |
||||||
Consider reading :ref:`extension-dev` to develop your own Flask extension. |
FOO_BAR='baz', |
||||||
|
FOO_SPAM='eggs', |
||||||
|
) |
||||||
|
|
||||||
Flask Before 0.8 |
foo.init_app(app) |
||||||
---------------- |
|
||||||
|
|
||||||
If you are using Flask 0.7 or earlier the :data:`flask.ext` package will not |
|
||||||
exist, instead you have to import from ``flaskext.foo`` or ``flask_foo`` |
|
||||||
depending on how the extension is distributed. If you want to develop an |
|
||||||
application that supports Flask 0.7 or earlier you should still import |
|
||||||
from the :data:`flask.ext` package. We provide you with a compatibility |
|
||||||
module that provides this package for older versions of Flask. You can |
|
||||||
download it from GitHub: `flaskext_compat.py`_ |
|
||||||
|
|
||||||
And here is how you can use it:: |
Building Extensions |
||||||
|
------------------- |
||||||
import flaskext_compat |
|
||||||
flaskext_compat.activate() |
|
||||||
|
|
||||||
from flask.ext import foo |
|
||||||
|
|
||||||
Once the ``flaskext_compat`` module is activated the :data:`flask.ext` will |
While the `Extension Registry`_ contains many Flask extensions, you may |
||||||
exist and you can start importing from there. |
not find an extension that fits your need. If this is the case, you can |
||||||
|
create your own. Read :ref:`extension-dev` to develop your own Flask |
||||||
|
extension. |
||||||
|
|
||||||
|
|
||||||
.. _Flask Extension Registry: http://flask.pocoo.org/extensions/ |
.. _Extension Registry: http://flask.pocoo.org/extensions/ |
||||||
.. _flaskext_compat.py: https://raw.githubusercontent.com/pallets/flask/master/scripts/flaskext_compat.py |
.. _pypi: https://pypi.python.org/pypi?:action=browse&c=585 |
||||||
|
@ -1,23 +0,0 @@ |
|||||||
.. _python3-support: |
|
||||||
|
|
||||||
Python 3 Support |
|
||||||
================ |
|
||||||
|
|
||||||
Flask, its dependencies, and most Flask extensions support Python 3. |
|
||||||
You should start using Python 3 for your next project, |
|
||||||
but there are a few things to be aware of. |
|
||||||
|
|
||||||
You need to use Python 3.3 or higher. 3.2 and older are *not* supported. |
|
||||||
|
|
||||||
You should use the latest versions of all Flask-related packages. |
|
||||||
Flask 0.10 and Werkzeug 0.9 were the first versions to introduce Python 3 support. |
|
||||||
|
|
||||||
Python 3 changed how unicode and bytes are handled, which complicates how low |
|
||||||
level code handles HTTP data. This mainly affects WSGI middleware interacting |
|
||||||
with the WSGI ``environ`` data. Werkzeug wraps that information in high-level |
|
||||||
helpers, so encoding issues should not affect you. |
|
||||||
|
|
||||||
The majority of the upgrade work is in the lower-level libraries like |
|
||||||
Flask and Werkzeug, not the high-level application code. |
|
||||||
For example, all of the examples in the Flask repository work on both Python 2 and 3 |
|
||||||
and did not require a single line of code changed. |
|
@ -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() |
|
@ -1,112 +1,67 @@ |
|||||||
""" |
#!/usr/bin/env python |
||||||
Flask |
# -*- coding: utf-8 -*- |
||||||
----- |
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 ' |
maintainer='Pallets team', |
||||||
'and good intentions', |
maintainer_email='contact@palletsprojects.com', |
||||||
long_description=__doc__, |
description='A simple framework for building complex web applications.', |
||||||
|
long_description=readme, |
||||||
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', |
||||||
install_requires=[ |
install_requires=[ |
||||||
'Werkzeug>=0.9', |
'Werkzeug>=0.14', |
||||||
'Jinja2>=2.4', |
'Jinja2>=2.10', |
||||||
'itsdangerous>=0.21', |
'itsdangerous>=0.24', |
||||||
'click>=4.0', |
'click>=5.1', |
||||||
], |
], |
||||||
extras_require={ |
extras_require={ |
||||||
'dotenv': ['python-dotenv'], |
'dotenv': ['python-dotenv'], |
||||||
'dev': [ |
'dev': [ |
||||||
'blinker', |
|
||||||
'python-dotenv', |
|
||||||
'greenlet', |
|
||||||
'pytest>=3', |
'pytest>=3', |
||||||
'coverage', |
'coverage', |
||||||
'tox', |
'tox', |
||||||
'sphinx', |
'sphinx', |
||||||
'sphinxcontrib-log-cabinet' |
|
||||||
], |
], |
||||||
}, |
}, |
||||||
classifiers=[ |
classifiers=[ |
||||||
'Development Status :: 4 - Beta', |
'Development Status :: 5 - Production/Stable', |
||||||
'Environment :: Web Environment', |
'Environment :: Web Environment', |
||||||
|
'Framework :: Flask', |
||||||
'Intended Audience :: Developers', |
'Intended Audience :: Developers', |
||||||
'License :: OSI Approved :: BSD License', |
'License :: OSI Approved :: BSD License', |
||||||
'Operating System :: OS Independent', |
'Operating System :: OS Independent', |
||||||
'Programming Language :: Python', |
'Programming Language :: Python', |
||||||
'Programming Language :: Python :: 2', |
'Programming Language :: Python :: 2', |
||||||
'Programming Language :: Python :: 2.6', |
|
||||||
'Programming Language :: Python :: 2.7', |
'Programming Language :: Python :: 2.7', |
||||||
'Programming Language :: Python :: 3', |
'Programming Language :: Python :: 3', |
||||||
'Programming Language :: Python :: 3.3', |
|
||||||
'Programming Language :: Python :: 3.4', |
'Programming Language :: Python :: 3.4', |
||||||
'Programming Language :: Python :: 3.5', |
'Programming Language :: Python :: 3.5', |
||||||
'Programming Language :: Python :: 3.6', |
'Programming Language :: Python :: 3.6', |
||||||
'Topic :: Internet :: WWW/HTTP :: Dynamic Content', |
'Topic :: Internet :: WWW/HTTP :: Dynamic Content', |
||||||
'Topic :: Software Development :: Libraries :: Python Modules' |
'Topic :: Internet :: WWW/HTTP :: WSGI :: Application', |
||||||
|
'Topic :: Software Development :: Libraries :: Application Frameworks', |
||||||
|
'Topic :: Software Development :: Libraries :: Python Modules', |
||||||
], |
], |
||||||
entry_points=''' |
entry_points={ |
||||||
[console_scripts] |
'console_scripts': [ |
||||||
flask=flask.cli:main |
'flask = flask.cli:main', |
||||||
''' |
], |
||||||
|
}, |
||||||
) |
) |
||||||
|
Loading…
Reference in new issue