Skip to content

Commit 26eb8ce

Browse files
ryanmatsJon Wayne Parrott
authored andcommitted
Hackathon/Codelab vision sample (GoogleCloudPlatform#788)
1 parent e2c2e2a commit 26eb8ce

File tree

5 files changed

+268
-0
lines changed

5 files changed

+268
-0
lines changed

codelabs/flex_and_vision/README.md

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Python Google Cloud Vision sample for Google App Engine Flexible Environment
2+
3+
This sample demonstrates how to use the [Google Cloud Vision API](https://cloud.google.com/vision/), [Google Cloud Storage](https://cloud.google.com/storage/), and [Google Cloud Datastore](https://cloud.google.com/datastore/) on [Google App Engine Flexible Environment](https://cloud.google.com/appengine).
4+
5+
## Setup
6+
7+
Create a new project with the [Google Cloud Platform console](https://console.cloud.google.com/).
8+
Make a note of your project ID, which may be different than your project name.
9+
10+
Make sure to [Enable Billing](https://pantheon.corp.google.com/billing?debugUI=DEVELOPERS)
11+
for your project.
12+
13+
Download the [Google Cloud SDK](https://cloud.google.com/sdk/docs/) to your
14+
local machine. Alternatively, you could use the [Cloud Shell](https://cloud.google.com/shell/docs/quickstart), which comes with the Google Cloud SDK pre-installed.
15+
16+
Initialize the Google Cloud SDK (skip if using Cloud Shell):
17+
18+
gcloud init
19+
20+
Create your App Engine application:
21+
22+
gcloud app create
23+
24+
Set an environment variable for your project ID, replacing `[YOUR_PROJECT_ID]`
25+
with your project ID:
26+
27+
export PROJECT_ID=[YOUR_PROJECT_ID]
28+
29+
## Getting the sample code
30+
31+
Run the following command to clone the Github repository:
32+
33+
git clone https://github.com/GoogleCloudPlatform/python-docs-samples.git
34+
35+
Change directory to the sample code location:
36+
37+
cd python-docs-samples/codelabs/flex_and_vision
38+
39+
## Authentication
40+
41+
Enable the APIs:
42+
43+
gcloud service-management enable vision.googleapis.com
44+
gcloud service-management enable storage-component.googleapis.com
45+
gcloud service-management enable datastore.googleapis.com
46+
47+
Create a Service Account to access the Google Cloud APIs when testing locally:
48+
49+
gcloud iam service-accounts create hackathon \
50+
--display-name "My Hackathon Service Account"
51+
52+
Give your newly created Service Account appropriate permissions:
53+
54+
gcloud projects add-iam-policy-binding ${PROJECT_ID} \
55+
--member serviceAccount:hackathon@${PROJECT_ID}.iam.gserviceaccount.com \
56+
--role roles/owner
57+
58+
After creating your Service Account, create a Service Account key:
59+
60+
gcloud iam service-accounts keys create ~/key.json --iam-account \
61+
hackathon@${PROJECT_ID}.iam.gserviceaccount.com
62+
63+
Set the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to point to where
64+
you just put your Service Account key:
65+
66+
export GOOGLE_APPLICATION_CREDENTIALS="/home/${USER}/key.json"
67+
68+
## Running locally
69+
70+
Create a virtual environment and install dependencies:
71+
72+
virtualenv -p python3 env
73+
source env/bin/activate
74+
pip install -r requirements.txt
75+
76+
Create a Cloud Storage bucket. It is recommended that you name it the same as
77+
your project ID:
78+
79+
gsutil mb gs://${PROJECT_ID}
80+
81+
Set the environment variable `CLOUD_STORAGE_BUCKET`:
82+
83+
export CLOUD_STORAGE_BUCKET=${PROJECT_ID}
84+
85+
Start your application locally:
86+
87+
python main.py
88+
89+
Visit `localhost:8080` to view your application running locally. Press `Control-C`
90+
on your command line when you are finished.
91+
92+
When you are ready to leave your virtual environment:
93+
94+
deactivate
95+
96+
## Deploying to App Engine
97+
98+
Open `app.yaml` and replace <your-cloud-storage-bucket> with the name of your
99+
Cloud Storage bucket.
100+
101+
Deploy your application to App Engine using `gcloud`. Please note that this may
102+
take several minutes.
103+
104+
gcloud app deploy
105+
106+
Visit `https://[YOUR_PROJECT_ID].appspot.com` to view your deployed application.

codelabs/flex_and_vision/app.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
runtime: python
2+
env: flex
3+
entrypoint: gunicorn -b :$PORT main:app
4+
5+
runtime_config:
6+
python_version: 3
7+
8+
env_variables:
9+
CLOUD_STORAGE_BUCKET: <your-cloud-storage-bucket>

codelabs/flex_and_vision/main.py

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
# Copyright 2017 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+
from datetime import datetime
17+
import logging
18+
import os
19+
20+
from flask import Flask, redirect, render_template, request
21+
22+
from google.cloud import datastore
23+
from google.cloud import storage
24+
from google.cloud import vision
25+
26+
27+
CLOUD_STORAGE_BUCKET = os.environ.get('CLOUD_STORAGE_BUCKET')
28+
29+
30+
app = Flask(__name__)
31+
32+
33+
@app.route('/')
34+
def homepage():
35+
# Create a Cloud Datastore client.
36+
datastore_client = datastore.Client()
37+
38+
# Use the Cloud Datastore client to fetch information from Datastore about
39+
# each photo.
40+
query = datastore_client.query(kind='Faces')
41+
image_entities = list(query.fetch())
42+
43+
# Return a Jinja2 HTML template and pass in image_entities as a parameter.
44+
return render_template('homepage.html', image_entities=image_entities)
45+
46+
47+
@app.route('/upload_photo', methods=['GET', 'POST'])
48+
def upload_photo():
49+
photo = request.files['file']
50+
51+
# Create a Cloud Storage client.
52+
storage_client = storage.Client()
53+
54+
# Get the bucket that the file will be uploaded to.
55+
bucket = storage_client.get_bucket(CLOUD_STORAGE_BUCKET)
56+
57+
# Create a new blob and upload the file's content.
58+
blob = bucket.blob(photo.filename)
59+
blob.upload_from_string(
60+
photo.read(), content_type=photo.content_type)
61+
62+
# Make the blob publicly viewable.
63+
blob.make_public()
64+
65+
# Create a Cloud Vision client.
66+
vision_client = vision.Client()
67+
68+
# Use the Cloud Vision client to detect a face for our image.
69+
source_uri = 'gs://{}/{}'.format(CLOUD_STORAGE_BUCKET, blob.name)
70+
image = vision_client.image(source_uri=source_uri)
71+
faces = image.detect_faces(limit=1)
72+
73+
# If a face is detected, save to Datastore the likelihood that the face
74+
# displays 'joy,' as determined by Google's Machine Learning algorithm.
75+
if len(faces) > 0:
76+
face = faces[0]
77+
78+
# Convert the face.emotions.joy enum type to a string, which will be
79+
# something like 'Likelihood.VERY_LIKELY'. Parse that string by the
80+
# period to extract only the 'VERY_LIKELY' portion.
81+
face_joy = str(face.emotions.joy).split('.')[1]
82+
else:
83+
face_joy = 'Unknown'
84+
85+
# Create a Cloud Datastore client.
86+
datastore_client = datastore.Client()
87+
88+
# Fetch the current date / time.
89+
current_datetime = datetime.now()
90+
91+
# The kind for the new entity.
92+
kind = 'Faces'
93+
94+
# The name/ID for the new entity.
95+
name = blob.name
96+
97+
# Create the Cloud Datastore key for the new entity.
98+
key = datastore_client.key(kind, name)
99+
100+
# Construct the new entity using the key. Set dictionary values for entity
101+
# keys blob_name, storage_public_url, timestamp, and joy.
102+
entity = datastore.Entity(key)
103+
entity['blob_name'] = blob.name
104+
entity['image_public_url'] = blob.public_url
105+
entity['timestamp'] = current_datetime
106+
entity['joy'] = face_joy
107+
108+
# Save the new entity to Datastore.
109+
datastore_client.put(entity)
110+
111+
# Redirect to the home page.
112+
return redirect('/')
113+
114+
115+
@app.errorhandler(500)
116+
def server_error(e):
117+
logging.exception('An error occurred during a request.')
118+
return """
119+
An internal error occurred: <pre>{}</pre>
120+
See logs for full stacktrace.
121+
""".format(e), 500
122+
123+
124+
if __name__ == '__main__':
125+
# This is used when running locally. Gunicorn is used to run the
126+
# application on Google App Engine. See entrypoint in app.yaml.
127+
app.run(host='127.0.0.1', port=8080, debug=True)
128+
# [END app]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Flask==0.12
2+
gunicorn==19.6.0
3+
google-cloud-vision==0.22.0
4+
google-cloud-storage==0.22.0
5+
google-cloud-datastore==0.22.0
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<h1>Google Cloud Platform - Face Detection Sample</h1>
2+
3+
<p>This Python Flask application demonstrates App Engine Flexible, Google Cloud
4+
Storage, Datastore, and the Cloud Vision API.</p>
5+
6+
<br>
7+
8+
<html>
9+
<body>
10+
<form action="upload_photo" method="POST" enctype="multipart/form-data">
11+
Upload File: <input type="file" name="file"><br>
12+
<input type="submit" name="submit" value="Submit">
13+
</form>
14+
{% for image_entity in image_entities %}
15+
<img src="{{image_entity['image_public_url']}}" width=200 height=200>
16+
<p>{{image_entity['blob_name']}} was uploaded {{image_entity['timestamp']}}.</p>
17+
<p>Joy Likelihood for Face: {{image_entity['joy']}}</p>
18+
{% endfor %}
19+
</body>
20+
</html>

0 commit comments

Comments
 (0)