Browse Source

Merge branch 'master' of github.com:mitsuhiko/flask

pull/534/head
Armin Ronacher 13 years ago
parent
commit
2e816f554a
  1. 15
      .travis.yml
  2. 5
      docs/becomingbig.rst
  3. 13
      docs/deploying/cgi.rst
  4. 2
      docs/deploying/fastcgi.rst
  5. 8
      docs/extensiondev.rst
  6. 3
      docs/patterns/mongokit.rst
  7. 5
      docs/quickstart.rst
  8. 11
      examples/blueprintexample/blueprintexample.py
  9. 36
      examples/blueprintexample/blueprintexample_test.py
  10. 0
      examples/blueprintexample/simple_page/__init__.py
  11. 13
      examples/blueprintexample/simple_page/simple_page.py
  12. 5
      examples/blueprintexample/simple_page/templates/pages/hello.html
  13. 5
      examples/blueprintexample/simple_page/templates/pages/index.html
  14. 25
      examples/blueprintexample/simple_page/templates/pages/layout.html
  15. 5
      examples/blueprintexample/simple_page/templates/pages/world.html
  16. 2
      flask/app.py
  17. 2
      flask/ctx.py
  18. 24
      flask/helpers.py
  19. 23
      flask/testsuite/basic.py
  20. 19
      flask/testsuite/helpers.py
  21. 1
      scripts/flaskext_compat.py

15
.travis.yml

@ -0,0 +1,15 @@
language: python
python:
- 2.5
- 2.6
- 2.7
- pypy
before_install: pip install simplejson
script: python setup.py test
branches:
except:
- website

5
docs/becomingbig.rst

@ -25,8 +25,9 @@ The :ref:`api` docs are full of available overrides, hook points, and
response objects. Dig deeper on the APIs you use, and look for the
customizations which are available out of the box in a Flask release. Look for
ways in which your project can be refactored into a collection of utilities and
Flask extensions. Explore the many extensions in the community, and look for
patterns to build your own extensions if you do not find the tools you need.
Flask extensions. Explore the many `extensions
<http://flask.pocoo.org/extensions/>` in the community, and look for patterns to
build your own extensions if you do not find the tools you need.
Subclass.
---------

13
docs/deploying/cgi.rst

@ -35,12 +35,23 @@ Usually there are two ways to configure the server. Either just copy the
`.cgi` into a `cgi-bin` (and use `mod_rewrite` or something similar to
rewrite the URL) or let the server point to the file directly.
In Apache for example you can put a like like this into the config:
In Apache for example you can put something like this into the config:
.. sourcecode:: apache
ScriptAlias /app /path/to/the/application.cgi
On shared webhosting, though, you might not have access to your Apache config.
In this case, a file called `.htaccess`, sitting in the public directory you want
your app to be available, works too but the `ScriptAlias` directive won't
work in that case:
.. sourcecode:: apache
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f # Don't interfere with static files
RewriteRule ^(.*)$ /path/to/the/application.cgi/$1 [L]
For more information consult the documentation of your webserver.
.. _App Engine: http://code.google.com/appengine/

2
docs/deploying/fastcgi.rst

@ -102,7 +102,7 @@ Set yourapplication.fcgi::
def __call__(self, environ, start_response):
environ['SCRIPT_NAME'] = ''
return self.app(environ, start_response)
return self.app(environ, start_response)
app = ScriptNameStripper(app)

8
docs/extensiondev.rst

@ -47,10 +47,10 @@ registered on PyPI. Also the development checkout link should work so
that people can easily install the development version into their
virtualenv without having to download the library by hand.
Flask extensions must be licensed as BSD or MIT or a more liberal license
to be enlisted on the Flask Extension Registry. Keep in mind that the
Flask Extension Registry is a moderated place and libraries will be
reviewed upfront if they behave as required.
Flask extensions must be licensed under a BSD, MIT or more liberal license
to be able to be enlisted in the Flask Extension Registry. Keep in mind
that the Flask Extension Registry is a moderated place and libraries will
be reviewed upfront if they behave as required.
"Hello Flaskext!"
-----------------

3
docs/patterns/mongokit.rst

@ -122,9 +122,6 @@ collection first, this is somewhat the same as a table in the SQL world.
>>> user = {'name': u'admin', 'email': u'admin@localhost'}
>>> collection.insert(user)
print list(collection.find())
print collection.find_one({'name': u'admin'})
MongoKit will automatically commit for us.
To query your database, you use the collection directly:

5
docs/quickstart.rst

@ -514,8 +514,9 @@ attributes mentioned above::
return log_the_user_in(request.form['username'])
else:
error = 'Invalid username/password'
# this is executed if the request method was GET or the
# credentials were invalid
# the code below this is executed if the request method
# was GET or the credentials were invalid
return render_template('login.html', error=error)
What happens if the key does not exist in the `form` attribute? In that
case a special :exc:`KeyError` is raised. You can catch it like a

11
examples/blueprintexample/blueprintexample.py

@ -0,0 +1,11 @@
from flask import Flask
from simple_page.simple_page import simple_page
app = Flask(__name__)
app.register_blueprint(simple_page)
# Blueprint can be registered many times
app.register_blueprint(simple_page, url_prefix='/pages')
if __name__ == '__main__':
app.run(debug=True)

36
examples/blueprintexample/blueprintexample_test.py

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
"""
Blueprint Example Tests
~~~~~~~~~~~~~~
Tests the Blueprint example app
"""
import blueprintexample
import unittest
class BlueprintExampleTestCase(unittest.TestCase):
def setUp(self):
self.app = blueprintexample.app.test_client()
def test_urls(self):
r = self.app.get('/')
self.assertEquals(r.status_code, 200)
r = self.app.get('/hello')
self.assertEquals(r.status_code, 200)
r = self.app.get('/world')
self.assertEquals(r.status_code, 200)
#second blueprint instance
r = self.app.get('/pages/hello')
self.assertEquals(r.status_code, 200)
r = self.app.get('/pages/world')
self.assertEquals(r.status_code, 200)
if __name__ == '__main__':
unittest.main()

0
examples/blueprintexample/simple_page/__init__.py

13
examples/blueprintexample/simple_page/simple_page.py

@ -0,0 +1,13 @@
from flask import Blueprint, render_template, abort
from jinja2 import TemplateNotFound
simple_page = Blueprint('simple_page', __name__,
template_folder='templates')
@simple_page.route('/', defaults={'page': 'index'})
@simple_page.route('/<page>')
def show(page):
try:
return render_template('pages/%s.html' % page)
except TemplateNotFound:
abort(404)

5
examples/blueprintexample/simple_page/templates/pages/hello.html

@ -0,0 +1,5 @@
{% extends "pages/layout.html" %}
{% block body %}
Hello
{% endblock %}

5
examples/blueprintexample/simple_page/templates/pages/index.html

@ -0,0 +1,5 @@
{% extends "pages/layout.html" %}
{% block body %}
Blueprint example page
{% endblock %}

25
examples/blueprintexample/simple_page/templates/pages/layout.html

@ -0,0 +1,25 @@
<!doctype html>
<title>Simple Page Blueprint</title>
<div class=page>
<h1>This is blueprint example</h1>
<p>
A simple page blueprint is registered under / and /pages<br/>
you can access it using this urls:
<ul>
<li><a href="{{ url_for('simple_page.show', page='hello') }}">/hello</a></li>
<li><a href="{{ url_for('simple_page.show', page='world') }}">/world</a></li>
</ul>
</p>
<p>
Also you can register the same blueprint under another path
<ul>
<li><a href="/pages/hello">/pages/hello</a></li>
<li><a href="/pages/world">/pages/world</a></li>
</ul>
</p>
{% block body %}
{% endblock %}
</div>

5
examples/blueprintexample/simple_page/templates/pages/world.html

@ -0,0 +1,5 @@
{% extends "pages/layout.html" %}
{% block body %}
World
{% endblock %}

2
flask/app.py

@ -1490,7 +1490,7 @@ class Flask(_PackageBoundObject):
"""
funcs = self.url_default_functions.get(None, ())
if '.' in endpoint:
bp = endpoint.split('.', 1)[0]
bp = endpoint.rsplit('.', 1)[0]
funcs = chain(funcs, self.url_default_functions.get(bp, ()))
for func in funcs:
func(endpoint, values)

2
flask/ctx.py

@ -40,7 +40,7 @@ def after_this_request(f):
@app.route('/')
def index():
@after_this_request
def add_header():
def add_header(response):
response.headers['X-Foo'] = 'Parachute'
return response
return 'Hello World!'

24
flask/helpers.py

@ -118,31 +118,9 @@ def jsonify(*args, **kwargs):
information about this, have a look at :ref:`json-security`.
.. versionadded:: 0.2
.. versionadded:: 0.9
If the ``padded`` argument is true, the JSON object will be padded
for JSONP calls and the response mimetype will be changed to
``application/javascript``. By default, the request arguments ``callback``
and ``jsonp`` will be used as the name for the callback function.
This will work with jQuery and most other JavaScript libraries
by default.
If the ``padded`` argument is a string, jsonify will look for
the request argument with the same name and use that value as the
callback-function name.
"""
if __debug__:
_assert_have_json()
if 'padded' in kwargs:
if isinstance(kwargs['padded'], str):
callback = request.args.get(kwargs['padded']) or 'jsonp'
else:
callback = request.args.get('callback') or \
request.args.get('jsonp') or 'jsonp'
del kwargs['padded']
json_str = json.dumps(dict(*args, **kwargs), indent=None)
content = str(callback) + "(" + json_str + ")"
return current_app.response_class(content, mimetype='application/javascript')
return current_app.response_class(json.dumps(dict(*args, **kwargs),
indent=None if request.is_xhr else 2), mimetype='application/json')
@ -529,7 +507,7 @@ def send_file(filename_or_fp, mimetype=None, as_attachment=False,
rv.cache_control.public = True
if cache_timeout is None:
cache_timeout = current_app.get_send_file_max_age(filename)
if cache_timeout:
if cache_timeout is not None:
rv.cache_control.max_age = cache_timeout
rv.expires = int(time() + cache_timeout)

23
flask/testsuite/basic.py

@ -953,6 +953,29 @@ class BasicFunctionalityTestCase(FlaskTestCase):
self.assert_equal(c.get('/de/').data, '/de/about')
self.assert_equal(c.get('/de/about').data, '/foo')
self.assert_equal(c.get('/foo').data, '/en/about')
def test_inject_blueprint_url_defaults(self):
app = flask.Flask(__name__)
bp = flask.Blueprint('foo.bar.baz', __name__,
template_folder='template')
@bp.url_defaults
def bp_defaults(endpoint, values):
values['page'] = 'login'
@bp.route('/<page>')
def view(page): pass
app.register_blueprint(bp)
values = dict()
app.inject_url_defaults('foo.bar.baz.view', values)
expected = dict(page='login')
self.assert_equal(values, expected)
with app.test_request_context('/somepage'):
url = flask.url_for('foo.bar.baz.view')
expected = '/login'
self.assert_equal(url, expected)
def test_debug_mode_complains_after_first_request(self):
app = flask.Flask(__name__)

19
flask/testsuite/helpers.py

@ -73,28 +73,11 @@ class JSONTestCase(FlaskTestCase):
@app.route('/dict')
def return_dict():
return flask.jsonify(d)
@app.route("/unpadded")
def return_padded_false():
return flask.jsonify(d, padded=False)
@app.route("/padded")
def return_padded_true():
return flask.jsonify(d, padded=True)
@app.route("/padded_custom")
def return_padded_json_custom_callback():
return flask.jsonify(d, padded='my_func_name')
c = app.test_client()
for url in '/kw', '/dict', '/unpadded':
for url in '/kw', '/dict':
rv = c.get(url)
self.assert_equal(rv.mimetype, 'application/json')
self.assert_equal(flask.json.loads(rv.data), d)
for get_arg in 'callback=funcName', 'jsonp=funcName':
rv = c.get('/padded?' + get_arg)
self.assert_( rv.data.startswith("funcName(") )
self.assert_( rv.data.endswith(")") )
rv_json = rv.data.split('(')[1].split(')')[0]
self.assert_equal(flask.json.loads(rv_json), d)
rv = c.get('/padded_custom?my_func_name=funcName')
self.assert_( rv.data.startswith("funcName(") )
def test_json_attr(self):
app = flask.Flask(__name__)

1
scripts/flaskext_compat.py

@ -9,6 +9,7 @@
Usage::
import flaskext_compat
flaskext_compat.activate()
from flask.ext import foo
:copyright: (c) 2011 by Armin Ronacher.

Loading…
Cancel
Save