From f7e52f08848bed7e9081822ea010e7008856a599 Mon Sep 17 00:00:00 2001 From: Jon Wayne Parrott Date: Wed, 29 Jun 2016 10:08:42 -0700 Subject: [PATCH 1/4] Adding flask gae standard hello world. Change-Id: I52d66219e3400c0b6a0937f3156c0da766841497 --- .../standard/flask/hello_world/.gitignore | 1 + .../standard/flask/hello_world/README.md | 11 ++++++ appengine/standard/flask/hello_world/app.yaml | 7 ++++ .../flask/hello_world/appengine_config.py | 18 ++++++++++ appengine/standard/flask/hello_world/main.py | 34 +++++++++++++++++++ .../flask/hello_world/requirements.txt | 1 + 6 files changed, 72 insertions(+) create mode 100644 appengine/standard/flask/hello_world/.gitignore create mode 100644 appengine/standard/flask/hello_world/README.md create mode 100644 appengine/standard/flask/hello_world/app.yaml create mode 100644 appengine/standard/flask/hello_world/appengine_config.py create mode 100644 appengine/standard/flask/hello_world/main.py create mode 100644 appengine/standard/flask/hello_world/requirements.txt diff --git a/appengine/standard/flask/hello_world/.gitignore b/appengine/standard/flask/hello_world/.gitignore new file mode 100644 index 00000000000..a65b41774ad --- /dev/null +++ b/appengine/standard/flask/hello_world/.gitignore @@ -0,0 +1 @@ +lib diff --git a/appengine/standard/flask/hello_world/README.md b/appengine/standard/flask/hello_world/README.md new file mode 100644 index 00000000000..da0b396dcb9 --- /dev/null +++ b/appengine/standard/flask/hello_world/README.md @@ -0,0 +1,11 @@ +# App Engine Flask Hello World + +This sample shows how to use [Flask](http://flask.pocoo.org/) with Google App +Engine Standard. + +Before running or deploying this application, install the dependencies using +[pip](http://pip.readthedocs.io/en/stable/): + + pip install -t lib -r requirements.txt + +For more information, see the [App Engine Standard README](../../README.md) diff --git a/appengine/standard/flask/hello_world/app.yaml b/appengine/standard/flask/hello_world/app.yaml new file mode 100644 index 00000000000..f041d384c05 --- /dev/null +++ b/appengine/standard/flask/hello_world/app.yaml @@ -0,0 +1,7 @@ +runtime: python27 +api_version: 1 +threadsafe: true + +handlers: +- url: /.* + script: main.app diff --git a/appengine/standard/flask/hello_world/appengine_config.py b/appengine/standard/flask/hello_world/appengine_config.py new file mode 100644 index 00000000000..c903d9a0ac5 --- /dev/null +++ b/appengine/standard/flask/hello_world/appengine_config.py @@ -0,0 +1,18 @@ +# Copyright 2016 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from google.appengine.ext import vendor + +# Add any libraries installed in the "lib" folder. +vendor.add('lib') diff --git a/appengine/standard/flask/hello_world/main.py b/appengine/standard/flask/hello_world/main.py new file mode 100644 index 00000000000..6e5a9d82fd1 --- /dev/null +++ b/appengine/standard/flask/hello_world/main.py @@ -0,0 +1,34 @@ +# Copyright 2016 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START app] +import logging + +from flask import Flask + + +app = Flask(__name__) + + +@app.route('/') +def hello(): + return 'Hello World!' + + +@app.errorhandler(500) +def server_error(e): + # Log the error and stacktrace. + logging.exception('An error occurred during a request.') + return 'An internal error occurred.', 500 +# [END app] diff --git a/appengine/standard/flask/hello_world/requirements.txt b/appengine/standard/flask/hello_world/requirements.txt new file mode 100644 index 00000000000..c96594356e7 --- /dev/null +++ b/appengine/standard/flask/hello_world/requirements.txt @@ -0,0 +1 @@ +Flask==0.11 From 25b46c6e6a84a91a1343d7c90d1d123d91e77d1b Mon Sep 17 00:00:00 2001 From: Jon Wayne Parrott Date: Wed, 29 Jun 2016 10:22:00 -0700 Subject: [PATCH 2/4] Adding the flask gae tutorial app Change-Id: Id6f26c55937fb8061bab7c71cae47ecf68045862 --- .../standard/flask/hello_world/README.md | 2 +- appengine/standard/flask/tutorial/.gitignore | 1 + appengine/standard/flask/tutorial/README.md | 11 ++++ appengine/standard/flask/tutorial/app.yaml | 11 ++++ .../flask/tutorial/appengine_config.py | 18 ++++++ appengine/standard/flask/tutorial/main.py | 56 +++++++++++++++++++ .../standard/flask/tutorial/requirements.txt | 1 + .../standard/flask/tutorial/static/style.css | 3 + .../flask/tutorial/templates/form.html | 26 +++++++++ .../tutorial/templates/submitted_form.html | 23 ++++++++ 10 files changed, 151 insertions(+), 1 deletion(-) create mode 100644 appengine/standard/flask/tutorial/.gitignore create mode 100644 appengine/standard/flask/tutorial/README.md create mode 100644 appengine/standard/flask/tutorial/app.yaml create mode 100644 appengine/standard/flask/tutorial/appengine_config.py create mode 100644 appengine/standard/flask/tutorial/main.py create mode 100644 appengine/standard/flask/tutorial/requirements.txt create mode 100644 appengine/standard/flask/tutorial/static/style.css create mode 100644 appengine/standard/flask/tutorial/templates/form.html create mode 100644 appengine/standard/flask/tutorial/templates/submitted_form.html diff --git a/appengine/standard/flask/hello_world/README.md b/appengine/standard/flask/hello_world/README.md index da0b396dcb9..04ec9402ab1 100644 --- a/appengine/standard/flask/hello_world/README.md +++ b/appengine/standard/flask/hello_world/README.md @@ -1,4 +1,4 @@ -# App Engine Flask Hello World +# App Engine Standard Flask Hello World This sample shows how to use [Flask](http://flask.pocoo.org/) with Google App Engine Standard. diff --git a/appengine/standard/flask/tutorial/.gitignore b/appengine/standard/flask/tutorial/.gitignore new file mode 100644 index 00000000000..a65b41774ad --- /dev/null +++ b/appengine/standard/flask/tutorial/.gitignore @@ -0,0 +1 @@ +lib diff --git a/appengine/standard/flask/tutorial/README.md b/appengine/standard/flask/tutorial/README.md new file mode 100644 index 00000000000..46f841935ec --- /dev/null +++ b/appengine/standard/flask/tutorial/README.md @@ -0,0 +1,11 @@ +# App Engine Standard Flask Tutorial App + +This sample shows how to use [Flask](http://flask.pocoo.org/) to handle +requests, forms, templates, and static files on Google App Engine Standard. + +Before running or deploying this application, install the dependencies using +[pip](http://pip.readthedocs.io/en/stable/): + + pip install -t lib -r requirements.txt + +For more information, see the [App Engine Standard README](../../README.md) diff --git a/appengine/standard/flask/tutorial/app.yaml b/appengine/standard/flask/tutorial/app.yaml new file mode 100644 index 00000000000..862e62b5273 --- /dev/null +++ b/appengine/standard/flask/tutorial/app.yaml @@ -0,0 +1,11 @@ +runtime: python27 +api_version: 1 +threadsafe: true + +# [START handlers] +handlers: +- url: /static + static_dir: static +- url: /.* + script: main.app +# [END handlers] diff --git a/appengine/standard/flask/tutorial/appengine_config.py b/appengine/standard/flask/tutorial/appengine_config.py new file mode 100644 index 00000000000..c903d9a0ac5 --- /dev/null +++ b/appengine/standard/flask/tutorial/appengine_config.py @@ -0,0 +1,18 @@ +# Copyright 2016 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from google.appengine.ext import vendor + +# Add any libraries installed in the "lib" folder. +vendor.add('lib') diff --git a/appengine/standard/flask/tutorial/main.py b/appengine/standard/flask/tutorial/main.py new file mode 100644 index 00000000000..47d56209a2d --- /dev/null +++ b/appengine/standard/flask/tutorial/main.py @@ -0,0 +1,56 @@ +# Copyright 2016 Google Inc. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START app] +import logging + +# [START imports] +from flask import Flask, render_template, request +# [END imports] + +app = Flask(__name__) + + +# [START form] +@app.route('/form') +def form(): + return render_template('form.html') +# [END form] + + +# [START submitted] +@app.route('/submitted', methods=['POST']) +def submitted_form(): + name = request.form['name'] + email = request.form['email'] + site = request.form['site_url'] + comments = request.form['comments'] + + # [END submitted] + # [START render_template] + return render_template( + 'submitted_form.html', + name=name, + email=email, + site=site, + comments=comments) + # [END render_template] + + +@app.errorhandler(500) +def server_error(e): + # Log the error and stacktrace. + logging.exception('An error occurred during a request.') + return 'An internal error occurred.', 500 +# [END app] diff --git a/appengine/standard/flask/tutorial/requirements.txt b/appengine/standard/flask/tutorial/requirements.txt new file mode 100644 index 00000000000..c96594356e7 --- /dev/null +++ b/appengine/standard/flask/tutorial/requirements.txt @@ -0,0 +1 @@ +Flask==0.11 diff --git a/appengine/standard/flask/tutorial/static/style.css b/appengine/standard/flask/tutorial/static/style.css new file mode 100644 index 00000000000..378932a78f9 --- /dev/null +++ b/appengine/standard/flask/tutorial/static/style.css @@ -0,0 +1,3 @@ +.pagetitle { + color: #800080; +} diff --git a/appengine/standard/flask/tutorial/templates/form.html b/appengine/standard/flask/tutorial/templates/form.html new file mode 100644 index 00000000000..159752799e8 --- /dev/null +++ b/appengine/standard/flask/tutorial/templates/form.html @@ -0,0 +1,26 @@ + + + Submit a form + + + +
+
+

Submit a form

+
+
+
+ +
+ +
+ +
+ +
+ +
+
+
+ + diff --git a/appengine/standard/flask/tutorial/templates/submitted_form.html b/appengine/standard/flask/tutorial/templates/submitted_form.html new file mode 100644 index 00000000000..54c87766489 --- /dev/null +++ b/appengine/standard/flask/tutorial/templates/submitted_form.html @@ -0,0 +1,23 @@ + + + Submitted form + + + +
+
+

Form submitted

+
+
+

Thanks for your submission, {{name}}!

+

Here's a review of the information that you sent:

+

+ Name: {{name}}
+ Email: {{email}}
+ Website URL: {{site}}
+ Comments: {{comments}} +

+
+
+ + From 709f65267ef98d069312cc394560c74502cf20a4 Mon Sep 17 00:00:00 2001 From: Jon Wayne Parrott Date: Wed, 29 Jun 2016 10:38:18 -0700 Subject: [PATCH 3/4] Adding tests, fixing nox posargs Change-Id: Id1cb80d36bfe954a44055fb03ee9ecd106c313ae --- nox.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/nox.py b/nox.py index 806984bfe85..7980569104f 100644 --- a/nox.py +++ b/nox.py @@ -117,13 +117,12 @@ def run_tests_in_sesssion( if skip_flaky: pytest_args.append('-m not slow and not flaky') - if sample_directories is None: - # session.posargs is any leftover arguments from the command line, - # which allows users to run a particular test instead of all of them. - if session.posargs: - sample_directories = session.posargs - else: - sample_directories = collect_sample_dirs('.', TESTS_BLACKLIST) + # session.posargs is any leftover arguments from the command line, + # which allows users to run a particular test instead of all of them. + if session.posargs: + sample_directories = session.posargs + elif sample_directories is None: + sample_directories = collect_sample_dirs('.', TESTS_BLACKLIST) if changed_only: changed_files = get_changed_files() From 60294d8a9a4b4b78df76fed370ef2e2f0c0e5dd0 Mon Sep 17 00:00:00 2001 From: Jon Wayne Parrott Date: Wed, 29 Jun 2016 10:41:44 -0700 Subject: [PATCH 4/4] Actually adding tests. -.- Change-Id: I49c5230283b28b0e5025badcfb342eb36ed93ecc --- .../standard/flask/hello_world/main_test.py | 27 +++++++++++++ .../standard/flask/tutorial/main_test.py | 38 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 appengine/standard/flask/hello_world/main_test.py create mode 100644 appengine/standard/flask/tutorial/main_test.py diff --git a/appengine/standard/flask/hello_world/main_test.py b/appengine/standard/flask/hello_world/main_test.py new file mode 100644 index 00000000000..ab6db4fe5df --- /dev/null +++ b/appengine/standard/flask/hello_world/main_test.py @@ -0,0 +1,27 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + + +@pytest.fixture +def app(): + import main + main.app.testing = True + return main.app.test_client() + + +def test_index(app): + r = app.get('/') + assert r.status_code == 200 diff --git a/appengine/standard/flask/tutorial/main_test.py b/appengine/standard/flask/tutorial/main_test.py new file mode 100644 index 00000000000..9dbd16c9458 --- /dev/null +++ b/appengine/standard/flask/tutorial/main_test.py @@ -0,0 +1,38 @@ +# Copyright 2016 Google Inc. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import pytest + + +@pytest.fixture +def app(): + import main + main.app.testing = True + return main.app.test_client() + + +def test_form(app): + r = app.get('/form') + assert r.status_code == 200 + assert 'Submit a form' in r.data.decode('utf-8') + + +def test_submitted_form(app): + r = app.post('/submitted', data={ + 'name': 'Inigo Montoya', + 'email': 'inigo@example.com', + 'site_url': 'http://example.com', + 'comments': ''}) + assert r.status_code == 200 + assert 'Inigo Montoya' in r.data.decode('utf-8')