mirror of https://github.com/mitsuhiko/flask.git
David Lord
7 years ago
21 changed files with 341 additions and 13 deletions
@ -0,0 +1,14 @@ |
|||||||
|
venv/ |
||||||
|
*.pyc |
||||||
|
__pycache__/ |
||||||
|
instance/ |
||||||
|
.cache/ |
||||||
|
.pytest_cache/ |
||||||
|
.coverage |
||||||
|
htmlcov/ |
||||||
|
dist/ |
||||||
|
build/ |
||||||
|
*.egg-info/ |
||||||
|
.idea/ |
||||||
|
*.swp |
||||||
|
*~ |
@ -0,0 +1,31 @@ |
|||||||
|
Copyright © 2010 by the Pallets team. |
||||||
|
|
||||||
|
Some rights reserved. |
||||||
|
|
||||||
|
Redistribution and use in source and binary forms of the software as |
||||||
|
well as documentation, with or without modification, are permitted |
||||||
|
provided that the following conditions are met: |
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, |
||||||
|
this list of conditions and the following disclaimer. |
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright |
||||||
|
notice, this list of conditions and the following disclaimer in the |
||||||
|
documentation and/or other materials provided with the distribution. |
||||||
|
|
||||||
|
* Neither the name of the copyright holder nor the names of its |
||||||
|
contributors may be used to endorse or promote products derived from |
||||||
|
this software without specific prior written permission. |
||||||
|
|
||||||
|
THIS SOFTWARE AND DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND |
||||||
|
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, |
||||||
|
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
||||||
|
COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, |
||||||
|
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
||||||
|
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
||||||
|
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
||||||
|
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||||
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
||||||
|
THIS SOFTWARE AND DOCUMENTATION, EVEN IF ADVISED OF THE POSSIBILITY OF |
||||||
|
SUCH DAMAGE. |
@ -0,0 +1,4 @@ |
|||||||
|
include LICENSE |
||||||
|
graft js_example/templates |
||||||
|
graft tests |
||||||
|
global-exclude *.pyc |
@ -0,0 +1,49 @@ |
|||||||
|
JavaScript Ajax Example |
||||||
|
======================= |
||||||
|
|
||||||
|
Demonstrates how to post form data and process a JSON response using |
||||||
|
JavaScript. This allows making requests without navigating away from the |
||||||
|
page. Demonstrates using |XMLHttpRequest|_, |fetch|_, and |
||||||
|
|jQuery.ajax|_. See the `Flask docs`_ about jQuery and Ajax. |
||||||
|
|
||||||
|
.. |XMLHttpRequest| replace:: ``XMLHttpRequest`` |
||||||
|
.. _XMLHttpRequest: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest |
||||||
|
|
||||||
|
.. |fetch| replace:: ``fetch`` |
||||||
|
.. _fetch: https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch |
||||||
|
|
||||||
|
.. |jQuery.ajax| replace:: ``jQuery.ajax`` |
||||||
|
.. _jQuery.ajax: https://api.jquery.com/jQuery.ajax/ |
||||||
|
|
||||||
|
.. _Flask docs: http://flask.pocoo.org/docs/patterns/jquery/ |
||||||
|
|
||||||
|
|
||||||
|
Install |
||||||
|
------- |
||||||
|
|
||||||
|
:: |
||||||
|
|
||||||
|
python3 -m venv venv |
||||||
|
. venv/bin/activate |
||||||
|
pip install -e . |
||||||
|
|
||||||
|
|
||||||
|
Run |
||||||
|
--- |
||||||
|
|
||||||
|
:: |
||||||
|
|
||||||
|
export FLASK_APP=js_example |
||||||
|
flask run |
||||||
|
|
||||||
|
Open http://127.0.0.1:5000 in a browser. |
||||||
|
|
||||||
|
|
||||||
|
Test |
||||||
|
---- |
||||||
|
|
||||||
|
:: |
||||||
|
|
||||||
|
pip install -e '.[test]' |
||||||
|
coverage run -m pytest |
||||||
|
coverage report |
@ -0,0 +1,5 @@ |
|||||||
|
from flask import Flask |
||||||
|
|
||||||
|
app = Flask(__name__) |
||||||
|
|
||||||
|
from js_example import views |
@ -0,0 +1,33 @@ |
|||||||
|
<!doctype html> |
||||||
|
<title>JavaScript Example</title> |
||||||
|
<link rel="stylesheet" href="https://unpkg.com/sakura.css@1.0.0/css/normalize.css"> |
||||||
|
<link rel="stylesheet" href="https://unpkg.com/sakura.css@1.0.0/css/sakura-earthly.css"> |
||||||
|
<style> |
||||||
|
ul { margin: 0; padding: 0; display: flex; list-style-type: none; } |
||||||
|
li > * { padding: 1em; } |
||||||
|
li.active > a { color: #5e5e5e; border-bottom: 2px solid #4a4a4a; } |
||||||
|
form { display: flex; } |
||||||
|
label > input { width: 3em; } |
||||||
|
form > * { padding-right: 1em; } |
||||||
|
#result { font-weight: bold; } |
||||||
|
</style> |
||||||
|
<ul> |
||||||
|
<li><span>Type:</span> |
||||||
|
<li class="{% if js == 'plain' %}active{% endif %}"> |
||||||
|
<a href="{{ url_for('index', js='plain') }}">Plain</a> |
||||||
|
<li class="{% if js == 'fetch' %}active{% endif %}"> |
||||||
|
<a href="{{ url_for('index', js='fetch') }}">Fetch</a> |
||||||
|
<li class="{% if js == 'jquery' %}active{% endif %}"> |
||||||
|
<a href="{{ url_for('index', js='jquery') }}">jQuery</a> |
||||||
|
</ul> |
||||||
|
<hr> |
||||||
|
<p>{% block intro %}{% endblock %}</p> |
||||||
|
<hr> |
||||||
|
<form> |
||||||
|
<label>a <input name="a"></label> |
||||||
|
<span>+</span> |
||||||
|
<label>b <input name="b"></label> |
||||||
|
<input type="submit" value="Calculate"> |
||||||
|
</form> |
||||||
|
<span>= <span id="result"></span></span> |
||||||
|
{% block script %}{% endblock %} |
@ -0,0 +1,35 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
|
||||||
|
{% block intro %} |
||||||
|
<a href="https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch"><code>fetch</code></a> |
||||||
|
is the <em>new</em> plain JavaScript way to make requests. It's |
||||||
|
supported in all modern browsers except IE, which requires a |
||||||
|
<a href="https://github.com/github/fetch">polyfill</a>. |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block script %} |
||||||
|
<script src="https://unpkg.com/promise-polyfill@7.1.2/dist/polyfill.min.js"></script> |
||||||
|
<script src="https://unpkg.com/whatwg-fetch@2.0.4/fetch.js"></script> |
||||||
|
<script> |
||||||
|
function addSubmit(ev) { |
||||||
|
ev.preventDefault(); |
||||||
|
fetch('{{ url_for('add') }}', { |
||||||
|
method: 'POST', |
||||||
|
body: new FormData(this) |
||||||
|
}) |
||||||
|
.then(parseJSON) |
||||||
|
.then(addShow); |
||||||
|
} |
||||||
|
|
||||||
|
function parseJSON(response) { |
||||||
|
return response.json(); |
||||||
|
} |
||||||
|
|
||||||
|
function addShow(data) { |
||||||
|
var span = document.getElementById('result'); |
||||||
|
span.innerText = data.result; |
||||||
|
} |
||||||
|
|
||||||
|
document.forms[0].addEventListener('submit', addSubmit); |
||||||
|
</script> |
||||||
|
{% endblock %} |
@ -0,0 +1,27 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
|
||||||
|
{% block intro %} |
||||||
|
<a href="https://jquery.com/">jQuery</a> is a popular library that |
||||||
|
adds cross browser APIs for common tasks. However, it requires loading |
||||||
|
an extra library. |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block script %} |
||||||
|
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script> |
||||||
|
<script> |
||||||
|
function addSubmit(ev) { |
||||||
|
ev.preventDefault(); |
||||||
|
$.ajax({ |
||||||
|
method: 'POST', |
||||||
|
url: '{{ url_for('add') }}', |
||||||
|
data: $(this).serialize() |
||||||
|
}).done(addShow); |
||||||
|
} |
||||||
|
|
||||||
|
function addShow(data) { |
||||||
|
$('#result').text(data.result); |
||||||
|
} |
||||||
|
|
||||||
|
$('form:first').on('submit', addSubmit); |
||||||
|
</script> |
||||||
|
{% endblock %} |
@ -0,0 +1,27 @@ |
|||||||
|
{% extends 'base.html' %} |
||||||
|
|
||||||
|
{% block intro %} |
||||||
|
<a href="https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest"><code>XMLHttpRequest</code></a> |
||||||
|
is the plain JavaScript way to make requests. It's natively supported |
||||||
|
by all browsers. |
||||||
|
{% endblock %} |
||||||
|
|
||||||
|
{% block script %} |
||||||
|
<script> |
||||||
|
function addSubmit(ev) { |
||||||
|
ev.preventDefault(); |
||||||
|
var request = new XMLHttpRequest(); |
||||||
|
request.addEventListener('load', addShow); |
||||||
|
request.open('POST', '{{ url_for('add') }}'); |
||||||
|
request.send(new FormData(this)); |
||||||
|
} |
||||||
|
|
||||||
|
function addShow() { |
||||||
|
var data = JSON.parse(this.responseText); |
||||||
|
var span = document.getElementById('result'); |
||||||
|
span.innerText = data.result; |
||||||
|
} |
||||||
|
|
||||||
|
document.forms[0].addEventListener('submit', addSubmit); |
||||||
|
</script> |
||||||
|
{% endblock %} |
@ -0,0 +1,16 @@ |
|||||||
|
from flask import jsonify, render_template, request |
||||||
|
|
||||||
|
from js_example import app |
||||||
|
|
||||||
|
|
||||||
|
@app.route('/', defaults={'js': 'plain'}) |
||||||
|
@app.route('/<any(plain, jquery, fetch):js>') |
||||||
|
def index(js): |
||||||
|
return render_template('{0}.html'.format(js), js=js) |
||||||
|
|
||||||
|
|
||||||
|
@app.route('/add', methods=['POST']) |
||||||
|
def add(): |
||||||
|
a = request.form.get('a', 0, type=float) |
||||||
|
b = request.form.get('b', 0, type=float) |
||||||
|
return jsonify(result=a + b) |
@ -0,0 +1,13 @@ |
|||||||
|
[metadata] |
||||||
|
license_file = LICENSE |
||||||
|
|
||||||
|
[bdist_wheel] |
||||||
|
universal = True |
||||||
|
|
||||||
|
[tool:pytest] |
||||||
|
testpaths = tests |
||||||
|
|
||||||
|
[coverage:run] |
||||||
|
branch = True |
||||||
|
source = |
||||||
|
js_example |
@ -0,0 +1,30 @@ |
|||||||
|
import io |
||||||
|
|
||||||
|
from setuptools import find_packages, setup |
||||||
|
|
||||||
|
with io.open('README.rst', 'rt', encoding='utf8') as f: |
||||||
|
readme = f.read() |
||||||
|
|
||||||
|
setup( |
||||||
|
name='js_example', |
||||||
|
version='1.0.0', |
||||||
|
url='http://flask.pocoo.org/docs/patterns/jquery/', |
||||||
|
license='BSD', |
||||||
|
maintainer='Pallets team', |
||||||
|
maintainer_email='contact@palletsprojects.com', |
||||||
|
description='Demonstrates making Ajax requests to Flask.', |
||||||
|
long_description=readme, |
||||||
|
packages=find_packages(), |
||||||
|
include_package_data=True, |
||||||
|
zip_safe=False, |
||||||
|
install_requires=[ |
||||||
|
'flask', |
||||||
|
], |
||||||
|
extras_require={ |
||||||
|
'test': [ |
||||||
|
'pytest', |
||||||
|
'coverage', |
||||||
|
'blinker', |
||||||
|
], |
||||||
|
}, |
||||||
|
) |
@ -0,0 +1,15 @@ |
|||||||
|
import pytest |
||||||
|
|
||||||
|
from js_example import app |
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(name='app') |
||||||
|
def fixture_app(): |
||||||
|
app.testing = True |
||||||
|
yield app |
||||||
|
app.testing = False |
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture |
||||||
|
def client(app): |
||||||
|
return app.test_client() |
@ -0,0 +1,28 @@ |
|||||||
|
import pytest |
||||||
|
|
||||||
|
from flask import template_rendered |
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(('path', 'template_name'), ( |
||||||
|
('/', 'plain.html'), |
||||||
|
('/plain', 'plain.html'), |
||||||
|
('/fetch', 'fetch.html'), |
||||||
|
('/jquery', 'jquery.html'), |
||||||
|
)) |
||||||
|
def test_index(app, client, path, template_name): |
||||||
|
def check(sender, template, context): |
||||||
|
assert template.name == template_name |
||||||
|
|
||||||
|
with template_rendered.connected_to(check, app): |
||||||
|
client.get(path) |
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(('a', 'b', 'result'), ( |
||||||
|
(2, 3, 5), |
||||||
|
(2.5, 3, 5.5), |
||||||
|
(2, None, 2), |
||||||
|
(2, 'b', 2), |
||||||
|
)) |
||||||
|
def test_add(client, a, b, result): |
||||||
|
response = client.post('/add', data={'a': a, 'b': b}) |
||||||
|
assert response.get_json()['result'] == result |
Loading…
Reference in new issue