Skip to content

Commit cd67ae1

Browse files
committed
First draft of App Engine Flex Flask - Storage/Vision Sample
1 parent f7179af commit cd67ae1

4 files changed

Lines changed: 132 additions & 0 deletions

File tree

appengine/flexible/vision/app.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
runtime: python
2+
env: flex
3+
entrypoint: gunicorn -b :$PORT main:app
4+
5+
runtime_config:
6+
python_version: 3

appengine/flexible/vision/key.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"type": "service_account",
3+
"project_id": "hackathon-sample-vision",
4+
"private_key_id": "bdbb9da93a4cb5181496f2faba51a74439aecd8f",
5+
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDh3WkLXSAEld4k\nhTnwBnnZA0nTdAWrM4j4r1LXhALwG+hHLtvtbH5z8DdHP9CkBHSDC878ZARup7Jk\nb8s3Dq9jKo7Eprxpq7g/Q39sFmuTZ/wbkyxM2V15NbWCSO5vF3dKu/91uJS3MYE6\nH6n4DiJ4QDfxuINu40xbRbimCSG2ayCxw1IMNB95d5OXm/deWgdSDuIVJN5X5Hhf\nKo0sY9rcPkIp/XmOWkFaCmXzSWEy+t5Md6naeAjlycGkpoSTes9P1slpISK+bfok\nb8siuJ1SloUgUxkjf39iT5TkXjc9mYFZONWpE9w28KB4mFhEU495G24bGu5cG2Bn\nZ+rYkETfAgMBAAECggEBAMVxUcR3UefwQtLWC8HBR37nmv/X6qSwVkpeqSJw6kiP\nfMvNMMAqGZisIwaLyI24v0lXZ0fG/wDkY9Pczl6A3dzodQl/YDFXxaa4EImiR8QC\nIKbSTuWXFllBFDyiGJzQfJ2+HiEAjDBgfEEdMO4BHSzVppIN5Adpd3RKTJIIZYoa\nEvgK2K7OFdehk1nJ4CyyFGhuNg5z1JpuQL9OzIvdnzNTaMWS4fbH/IS+SEZ1xXtG\n8jKraC6o4BlBvxqiPa/tFnCRRD9ZG0RWS5d5GqRnZzlpxpArGWEz1f1pDPsWElSN\nzgCHv8zBXbjU+jVTZOEYGx8NwZteuhQQRaDeZZA7lqECgYEA/NWteGboEHImjNjn\nrr+TvZtRsZftt8gPL3o76DKbXSrGYDN7EDYYg31aDmHOZHdsCTtTnlDSgfbtdp3j\ndg8DGrfqJZtlgJ2VvVtVIfBjnElU3rv3zV7qvn7YatCMBAZx4ZaDHexLxUMMPzFV\nLnT8On5yqtOi4wFOqt2KJC/aU7cCgYEA5LFLvvPU+G/onr03GDJyvXRX54QCD2n0\nUVCbZ+7hGUOaai0UiIcD7XmeZqaNunXP0MLT5z6JEX3TgaN+KPheME9JLcCSV3ig\nL1qz0o8mwb2i2UeLl+10ExORkkg2xUUT+BnovM1tDiz6fEaRKhf+k+iBGPZEFlEc\nQjXnOHEiqBkCgYBGXDiALzMZkIrF237uFIZK17RuVbdj05rWPY/6WEsALG00TF9M\n7aD4xqOPKQzEzK8WCpqEjj1myY7f2aR5MEhO4SuZ95rRpgkLvyT74uf1kDq8GVcm\noel1xdr4Lr0oSZrbioVGiIG1jakU1Oe9m/StWo8Slv7XaX+48RoGZALAFQKBgBV7\nQe4x4TNk76jZhS9Urcp1/zvT/o2MGlL5C1/75FEHNJ38lg0tAYVxAxwJUQ7OujKV\n2mnCSgXGl/N5dARNMCvBhtIxYI2u2v0XvARvRei083MNcWNX/qs8D1R6TArDrliD\ntoTllvTZ7L13s3MMxfEGyfmaSFMAU3M0tP9sQSEhAoGBAOV9uwpXJ2XBx4QMpmvU\nrw3WF450XMFasHP5BlukEbeWv6NbIRfu/9ix8b3nZ1v19d8LDJXMCk61xyTdt6bf\nFhFFEqDe65yCK2OcbNiFIxniCtZAHzEPO1+G8KSaaKxXI6kIvBQRHTQLxRU6Mwc1\n5Xl6zzg3+a/AUnIvJLVE+rQq\n-----END PRIVATE KEY-----\n",
6+
"client_email": "hackathon-sample-vision@appspot.gserviceaccount.com",
7+
"client_id": "108440335058605390261",
8+
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
9+
"token_uri": "https://accounts.google.com/o/oauth2/token",
10+
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
11+
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/hackathon-sample-vision%40appspot.gserviceaccount.com"
12+
}

appengine/flexible/vision/main.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# Copyright 2015 Google Inc. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
# [START app]
16+
import logging
17+
18+
from google.cloud import vision
19+
from google.cloud import storage
20+
21+
from flask import Flask, request, redirect
22+
23+
CLOUD_STORAGE_BUCKET = 'ryans-bucket-2017'
24+
25+
HEADER_MESSAGE = (
26+
'<h1>Google Cloud Platform - Face Detection Sample</h1>'
27+
'<p>This Python Flask application demonstrates App Engine Flexible, Google'
28+
' Cloud Storage, and the Cloud Vision API.</p><br>')
29+
30+
app = Flask(__name__)
31+
32+
33+
@app.route('/')
34+
def homepage():
35+
36+
# Format the header message and a form to submit images.
37+
html_string = HEADER_MESSAGE
38+
html_string += """
39+
<html><body>
40+
<form action="upload_photo" method="POST" enctype="multipart/form-data">
41+
Upload File: <input type="file" name="file"><br>
42+
<input type="submit" name="submit" value="Submit">
43+
</form> """
44+
45+
# Create a Cloud Storage client.
46+
storage_client = storage.Client()
47+
48+
# Get your Cloud Storage bucket.
49+
bucket = storage_client.get_bucket(CLOUD_STORAGE_BUCKET)
50+
51+
# Create a Cloud Vision client.
52+
vision_client = vision.Client()
53+
54+
# Loop through all items in your Cloud Storage bucket.
55+
for blob in bucket.list_blobs():
56+
57+
# Add HTML to display each image.
58+
blob_public_url = blob.public_url
59+
html_string += """<img src="{}" width=200 height=200>""".format(blob_public_url)
60+
61+
# Use the Cloud Vision client to detect a face for each image.
62+
media_link = blob.media_link
63+
image = vision_client.image(source_uri=media_link)
64+
faces = image.detect_faces(limit=1)
65+
66+
# If a face is detected, output HTML with the likelihood that the face
67+
# displays 'joy,' as determined by Google's Machine Learning algorithm.
68+
if len(faces) > 0:
69+
first_face = faces[0]
70+
first_face_happiness = first_face.emotions.joy
71+
html_string += """<p>Joy Likelihood for Face: {}</p>""".format(first_face_happiness)
72+
73+
html_string += """</body></html>"""
74+
return html_string
75+
76+
@app.route('/upload_photo', methods=['GET', 'POST'])
77+
def upload_photo():
78+
photo = request.files['file']
79+
80+
# Create a Cloud Storage client.
81+
storage_client = storage.Client()
82+
83+
# Get the bucket that the file will be uploaded to.
84+
bucket = storage_client.get_bucket(CLOUD_STORAGE_BUCKET)
85+
86+
# Create a new blob and upload the file's content.
87+
blob = bucket.blob(photo.filename)
88+
blob.upload_from_string(
89+
photo.read(), content_type=photo.content_type)
90+
91+
# Make the blob publicly viewable.
92+
blob.make_public()
93+
94+
# Redirect to the home page.
95+
return redirect('/')
96+
97+
@app.errorhandler(500)
98+
def server_error(e):
99+
logging.exception('An error occurred during a request.')
100+
return """
101+
An internal error occurred: <pre>{}</pre>
102+
See logs for full stacktrace.
103+
""".format(e), 500
104+
105+
106+
if __name__ == '__main__':
107+
# This is used when running locally. Gunicorn is used to run the
108+
# application on Google App Engine. See entrypoint in app.yaml.
109+
app.run(host='127.0.0.1', port=8080, debug=True)
110+
# [END app]
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Flask==0.12
2+
gunicorn==19.6.0
3+
google-cloud-vision==0.22.0
4+
google-cloud-storage==0.22.0

0 commit comments

Comments
 (0)