diff --git a/appengine/flexible/scipy/.gitignore b/appengine/flexible/scipy/.gitignore new file mode 100644 index 00000000000..de724cf6213 --- /dev/null +++ b/appengine/flexible/scipy/.gitignore @@ -0,0 +1 @@ +assets/resized_google_logo.jpg diff --git a/appengine/flexible/scipy/README.md b/appengine/flexible/scipy/README.md new file mode 100644 index 00000000000..4f0df036549 --- /dev/null +++ b/appengine/flexible/scipy/README.md @@ -0,0 +1,4 @@ +# SciPy on App Engine Flexible + +This sample demonstrates how to use SciPy to resize an image on App Engine Flexible. + diff --git a/appengine/flexible/scipy/app.yaml b/appengine/flexible/scipy/app.yaml new file mode 100644 index 00000000000..00539c11722 --- /dev/null +++ b/appengine/flexible/scipy/app.yaml @@ -0,0 +1,6 @@ +runtime: python +vm: true +entrypoint: gunicorn -b :$PORT main:app + +runtime_config: + python_version: 3 diff --git a/appengine/flexible/scipy/assets/google_logo.jpg b/appengine/flexible/scipy/assets/google_logo.jpg new file mode 100644 index 00000000000..5538eaed2bd Binary files /dev/null and b/appengine/flexible/scipy/assets/google_logo.jpg differ diff --git a/appengine/flexible/scipy/assets/resized_google_logo.jpg b/appengine/flexible/scipy/assets/resized_google_logo.jpg new file mode 100644 index 00000000000..971fb566e15 Binary files /dev/null and b/appengine/flexible/scipy/assets/resized_google_logo.jpg differ diff --git a/appengine/flexible/scipy/fixtures/assets/resized_google_logo.jpg b/appengine/flexible/scipy/fixtures/assets/resized_google_logo.jpg new file mode 100644 index 00000000000..971fb566e15 Binary files /dev/null and b/appengine/flexible/scipy/fixtures/assets/resized_google_logo.jpg differ diff --git a/appengine/flexible/scipy/main.py b/appengine/flexible/scipy/main.py new file mode 100644 index 00000000000..612042c19de --- /dev/null +++ b/appengine/flexible/scipy/main.py @@ -0,0 +1,52 @@ +# 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 logging +import os + +from flask import Flask +import scipy.misc + +app = Flask(__name__) + + +# [START scipy] +@app.route('/') +def resize(): + """Demonstrates using scipy to resize an image.""" + app_path = os.path.dirname(os.path.realpath(__file__)) + image_path = os.path.join(app_path, 'assets/google_logo.jpg') + img = scipy.misc.imread(image_path) + img_tinted = scipy.misc.imresize(img, (300, 300)) + output_image_path = os.path.join( + app_path, 'assets/resized_google_logo.jpg') + # Write the tinted image back to disk + scipy.misc.imsave(output_image_path, img_tinted) + return "Image resized." +# [END scipy] + + +@app.errorhandler(500) +def server_error(e): + logging.exception('An error occurred during a request.') + return """ + An internal error occurred:
{}
+ See logs for full stacktrace. + """.format(e), 500 + + +if __name__ == '__main__': + # This is used when running locally. Gunicorn is used to run the + # application on Google App Engine. See entrypoint in app.yaml. + app.run(host='127.0.0.1', port=8080, debug=True) diff --git a/appengine/flexible/scipy/main_test.py b/appengine/flexible/scipy/main_test.py new file mode 100644 index 00000000000..7765f3bf450 --- /dev/null +++ b/appengine/flexible/scipy/main_test.py @@ -0,0 +1,35 @@ +# 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 filecmp +import os + +import main + + +def test_index(): + main.app.testing = True + client = main.app.test_client() + test_path = os.path.dirname(os.path.realpath(__file__)) + asset_path = os.path.join( + test_path, 'assets/resized_google_logo.jpg') + fixtured_path = os.path.join( + test_path, 'fixtures/assets/resized_google_logo.jpg') + try: + os.remove(asset_path) + except OSError: + pass # if doesn't exist + r = client.get('/') + assert filecmp.cmp(asset_path, fixtured_path) + assert r.status_code == 200 diff --git a/appengine/flexible/scipy/requirements.txt b/appengine/flexible/scipy/requirements.txt new file mode 100644 index 00000000000..ed88c85aa90 --- /dev/null +++ b/appengine/flexible/scipy/requirements.txt @@ -0,0 +1,4 @@ +Flask==0.11.1 +gunicorn==19.6.0 +scipy==0.18.0 +Pillow==3.3.1 diff --git a/requirements-dev.txt b/requirements-dev.txt index ff23415e98a..d6141d603ff 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -40,6 +40,7 @@ requests==2.11.1 requests[security]==2.11.1 responses==0.5.1 rsa==3.4.2 +scipy==0.18.0 sendgrid==3.2.10 simplejson==3.8.2 six==1.10.0