Using Machine Learning APIs

First, visit API console, choose "Credentials" on the left-hand menu. Choose "Create Credentials" and generate an API key for your application. You should probably restrict it by IP address to prevent abuse, but for now, just leave that field blank and delete the API key after trying out this demo.

Copy-paste your API Key here:

In [1]:
APIKEY="#####"  # Replace with your API key

Note: Make sure you generate an API Key and replace the value above. The sample key will not work.

From the same API console, choose "Dashboard" on the left-hand menu and "Enable API".

Enable the following APIs for your project (search for them) if they are not already enabled:

  1. Google Translate API
  2. Google Cloud Vision API
  3. Google Natural Language API
  4. Google Cloud Speech API

Finally, because we are calling the APIs from Python (clients in many other languages are available), let's install the Python package (it's not installed by default on Datalab)

In [2]:
!pip install --upgrade google-api-python-client
Collecting google-api-python-client
  Downloading https://files.pythonhosted.org/packages/bd/40/bc3b4e7c7c65f9548024dde5c7bad60e0e078b2d2a0ee8c426a5639c2cc9/google_api_python_client-1.7.3-py2.py3-none-any.whl (55kB)
    100% |████████████████████████████████| 61kB 1.8MB/s ta 0:00:011
Collecting six<2dev,>=1.6.1 (from google-api-python-client)
  Downloading https://files.pythonhosted.org/packages/67/4b/141a581104b1f6397bfa78ac9d43d8ad29a7ca43ea90a2d863fe3056e86a/six-1.11.0-py2.py3-none-any.whl
Collecting google-auth>=1.4.1 (from google-api-python-client)
  Downloading https://files.pythonhosted.org/packages/53/06/6e6d5bfa4d23ee40efd772d6b681a7afecd859a9176e564b8c329382370f/google_auth-1.5.0-py2.py3-none-any.whl (65kB)
    100% |████████████████████████████████| 71kB 1.5MB/s ta 0:00:01
Requirement already up-to-date: uritemplate<4dev,>=3.0.0 in /usr/local/envs/py2env/lib/python2.7/site-packages/uritemplate-3.0.0-py2.7.egg (from google-api-python-client)
Requirement already up-to-date: httplib2<1dev,>=0.9.2 in /usr/local/envs/py2env/lib/python2.7/site-packages (from google-api-python-client)
Requirement already up-to-date: google-auth-httplib2>=0.0.3 in /usr/local/envs/py2env/lib/python2.7/site-packages (from google-api-python-client)
Requirement already up-to-date: pyasn1-modules>=0.2.1 in /usr/local/envs/py2env/lib/python2.7/site-packages (from google-auth>=1.4.1->google-api-python-client)
Collecting cachetools>=2.0.0 (from google-auth>=1.4.1->google-api-python-client)
  Downloading https://files.pythonhosted.org/packages/0a/58/cbee863250b31d80f47401d04f34038db6766f95dea1cc909ea099c7e571/cachetools-2.1.0-py2.py3-none-any.whl
Requirement already up-to-date: rsa>=3.1.4 in /usr/local/envs/py2env/lib/python2.7/site-packages (from google-auth>=1.4.1->google-api-python-client)
Collecting pyasn1<0.5.0,>=0.4.1 (from pyasn1-modules>=0.2.1->google-auth>=1.4.1->google-api-python-client)
  Downloading https://files.pythonhosted.org/packages/a0/70/2c27740f08e477499ce19eefe05dbcae6f19fdc49e9e82ce4768be0643b9/pyasn1-0.4.3-py2.py3-none-any.whl (72kB)
    100% |████████████████████████████████| 81kB 3.6MB/s ta 0:00:011
Installing collected packages: six, cachetools, google-auth, google-api-python-client, pyasn1
  Found existing installation: six 1.10.0
    Uninstalling six-1.10.0:
      Successfully uninstalled six-1.10.0
  Found existing installation: cachetools 2.0.1
    Uninstalling cachetools-2.0.1:
      Successfully uninstalled cachetools-2.0.1
  Found existing installation: google-auth 1.4.1
    Uninstalling google-auth-1.4.1:
      Successfully uninstalled google-auth-1.4.1
  Found existing installation: google-api-python-client 1.6.2
    Uninstalling google-api-python-client-1.6.2:
      Successfully uninstalled google-api-python-client-1.6.2
  Found existing installation: pyasn1 0.4.2
    Uninstalling pyasn1-0.4.2:
      Successfully uninstalled pyasn1-0.4.2
Successfully installed cachetools-2.1.0 google-api-python-client-1.7.3 google-auth-1.5.0 pyasn1-0.4.3 six-1.11.0
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

Invoke Translate API

In [3]:
# running Translate API
from googleapiclient.discovery import build
service = build('translate', 'v2', developerKey=APIKEY)

# use the service
inputs = ['is it really this easy?', 'amazing technology', 'wow']
outputs = service.translations().list(source='en', target='fr', q=inputs).execute()
# print outputs
for input, output in zip(inputs, outputs['translations']):
  print u"{0} -> {1}".format(input, output['translatedText'])
is it really this easy? -> est-ce vraiment si simple?
amazing technology -> technologie étonnante
wow -> sensationnel

Invoke Vision API

The Vision API can work off an image in Cloud Storage or embedded directly into a POST message. I'll use Cloud Storage and do OCR on this image: . That photograph is from http://www.publicdomainpictures.net/view-image.php?image=15842

In [4]:
# Running Vision API
import base64
IMAGE="gs://cloud-training-demos/vision/sign2.jpg"
vservice = build('vision', 'v1', developerKey=APIKEY)
request = vservice.images().annotate(body={
        'requests': [{
                'image': {
                    'source': {
                        'gcs_image_uri': IMAGE
                    }
                },
                'features': [{
                    'type': 'TEXT_DETECTION',
                    'maxResults': 3,
                }]
            }],
        })
responses = request.execute(num_retries=3)
print responses
{u'responses': [{u'textAnnotations': [{u'locale': u'zh', u'description': u'\u8bf7\u60a8\u7231\u62a4\u548c\u4fdd\n\u62a4\u536b\u751f\u521b\u5efa\u4f18\n\u7f8e\u6c34\u73af\u5883\n', u'boundingPoly': {u'vertices': [{u'y': 104, u'x': 152}, {u'y': 104, u'x': 1082}, {u'y': 658, u'x': 1082}, {u'y': 658, u'x': 152}]}}, {u'description': u'\u8bf7', u'boundingPoly': {u'vertices': [{u'y': 104, u'x': 179}, {u'y': 104, u'x': 321}, {u'y': 243, u'x': 321}, {u'y': 243, u'x': 179}]}}, {u'description': u'\u60a8', u'boundingPoly': {u'vertices': [{u'y': 108, u'x': 329}, {u'y': 108, u'x': 471}, {u'y': 243, u'x': 471}, {u'y': 243, u'x': 329}]}}, {u'description': u'\u7231\u62a4', u'boundingPoly': {u'vertices': [{u'y': 108, u'x': 479}, {u'y': 108, u'x': 775}, {u'y': 243, u'x': 775}, {u'y': 243, u'x': 479}]}}, {u'description': u'\u548c', u'boundingPoly': {u'vertices': [{u'y': 111, u'x': 786}, {u'y': 111, u'x': 925}, {u'y': 243, u'x': 925}, {u'y': 243, u'x': 786}]}}, {u'description': u'\u4fdd', u'boundingPoly': {u'vertices': [{u'y': 104, u'x': 933}, {u'y': 104, u'x': 1079}, {u'y': 239, u'x': 1079}, {u'y': 239, u'x': 933}]}}, {u'description': u'\u62a4', u'boundingPoly': {u'vertices': [{u'y': 300, u'x': 165}, {u'y': 300, u'x': 312}, {u'y': 440, u'x': 312}, {u'y': 440, u'x': 165}]}}, {u'description': u'\u536b\u751f', u'boundingPoly': {u'vertices': [{u'y': 304, u'x': 316}, {u'y': 304, u'x': 619}, {u'y': 440, u'x': 619}, {u'y': 440, u'x': 316}]}}, {u'description': u'\u521b\u5efa', u'boundingPoly': {u'vertices': [{u'y': 304, u'x': 631}, {u'y': 304, u'x': 930}, {u'y': 444, u'x': 930}, {u'y': 444, u'x': 631}]}}, {u'description': u'\u4f18', u'boundingPoly': {u'vertices': [{u'y': 300, u'x': 938}, {u'y': 300, u'x': 1082}, {u'y': 440, u'x': 1082}, {u'y': 440, u'x': 938}]}}, {u'description': u'\u7f8e', u'boundingPoly': {u'vertices': [{u'y': 503, u'x': 158}, {u'y': 509, u'x': 304}, {u'y': 655, u'x': 297}, {u'y': 649, u'x': 152}]}}, {u'description': u'\u6c34', u'boundingPoly': {u'vertices': [{u'y': 501, u'x': 313}, {u'y': 508, u'x': 464}, {u'y': 653, u'x': 457}, {u'y': 647, u'x': 307}]}}, {u'description': u'\u73af\u5883', u'boundingPoly': {u'vertices': [{u'y': 499, u'x': 466}, {u'y': 512, u'x': 772}, {u'y': 658, u'x': 765}, {u'y': 645, u'x': 460}]}}], u'fullTextAnnotation': {u'text': u'\u8bf7\u60a8\u7231\u62a4\u548c\u4fdd\n\u62a4\u536b\u751f\u521b\u5efa\u4f18\n\u7f8e\u6c34\u73af\u5883\n', u'pages': [{u'width': 1280, u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}, u'blocks': [{u'boundingBox': {u'vertices': [{u'y': 104, u'x': 152}, {u'y': 104, u'x': 1082}, {u'y': 658, u'x': 1082}, {u'y': 658, u'x': 152}]}, u'blockType': u'TEXT', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}, u'paragraphs': [{u'boundingBox': {u'vertices': [{u'y': 104, u'x': 152}, {u'y': 104, u'x': 1082}, {u'y': 658, u'x': 1082}, {u'y': 658, u'x': 152}]}, u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}, u'words': [{u'boundingBox': {u'vertices': [{u'y': 104, u'x': 179}, {u'y': 104, u'x': 321}, {u'y': 243, u'x': 321}, {u'y': 243, u'x': 179}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 104, u'x': 179}, {u'y': 104, u'x': 321}, {u'y': 243, u'x': 321}, {u'y': 243, u'x': 179}]}, u'text': u'\u8bf7', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 108, u'x': 329}, {u'y': 108, u'x': 471}, {u'y': 243, u'x': 471}, {u'y': 243, u'x': 329}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 108, u'x': 329}, {u'y': 108, u'x': 471}, {u'y': 243, u'x': 471}, {u'y': 243, u'x': 329}]}, u'text': u'\u60a8', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 108, u'x': 479}, {u'y': 108, u'x': 775}, {u'y': 243, u'x': 775}, {u'y': 243, u'x': 479}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 108, u'x': 479}, {u'y': 108, u'x': 621}, {u'y': 243, u'x': 621}, {u'y': 243, u'x': 479}]}, u'text': u'\u7231', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 108, u'x': 633}, {u'y': 108, u'x': 775}, {u'y': 243, u'x': 775}, {u'y': 243, u'x': 633}]}, u'text': u'\u62a4', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 111, u'x': 786}, {u'y': 111, u'x': 925}, {u'y': 243, u'x': 925}, {u'y': 243, u'x': 786}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 111, u'x': 786}, {u'y': 111, u'x': 925}, {u'y': 243, u'x': 925}, {u'y': 243, u'x': 786}]}, u'text': u'\u548c', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 104, u'x': 933}, {u'y': 104, u'x': 1079}, {u'y': 239, u'x': 1079}, {u'y': 239, u'x': 933}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 104, u'x': 933}, {u'y': 104, u'x': 1079}, {u'y': 239, u'x': 1079}, {u'y': 239, u'x': 933}]}, u'text': u'\u4fdd', u'property': {u'detectedBreak': {u'type': u'EOL_SURE_SPACE'}, u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'ja'}]}}, {u'boundingBox': {u'vertices': [{u'y': 300, u'x': 165}, {u'y': 300, u'x': 312}, {u'y': 440, u'x': 312}, {u'y': 440, u'x': 165}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 300, u'x': 165}, {u'y': 300, u'x': 312}, {u'y': 440, u'x': 312}, {u'y': 440, u'x': 165}]}, u'text': u'\u62a4', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 304, u'x': 316}, {u'y': 304, u'x': 619}, {u'y': 440, u'x': 619}, {u'y': 440, u'x': 316}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 311, u'x': 316}, {u'y': 311, u'x': 460}, {u'y': 436, u'x': 460}, {u'y': 436, u'x': 316}]}, u'text': u'\u536b', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 304, u'x': 472}, {u'y': 304, u'x': 619}, {u'y': 440, u'x': 619}, {u'y': 440, u'x': 472}]}, u'text': u'\u751f', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 304, u'x': 631}, {u'y': 304, u'x': 930}, {u'y': 444, u'x': 930}, {u'y': 444, u'x': 631}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 304, u'x': 631}, {u'y': 304, u'x': 771}, {u'y': 444, u'x': 771}, {u'y': 444, u'x': 631}]}, u'text': u'\u521b', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 308, u'x': 786}, {u'y': 308, u'x': 930}, {u'y': 444, u'x': 930}, {u'y': 444, u'x': 786}]}, u'text': u'\u5efa', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 300, u'x': 938}, {u'y': 300, u'x': 1082}, {u'y': 440, u'x': 1082}, {u'y': 440, u'x': 938}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 300, u'x': 938}, {u'y': 300, u'x': 1082}, {u'y': 440, u'x': 1082}, {u'y': 440, u'x': 938}]}, u'text': u'\u4f18', u'property': {u'detectedBreak': {u'type': u'EOL_SURE_SPACE'}, u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 503, u'x': 158}, {u'y': 509, u'x': 304}, {u'y': 655, u'x': 297}, {u'y': 649, u'x': 152}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 503, u'x': 158}, {u'y': 509, u'x': 304}, {u'y': 655, u'x': 297}, {u'y': 649, u'x': 152}]}, u'text': u'\u7f8e', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 501, u'x': 313}, {u'y': 508, u'x': 464}, {u'y': 653, u'x': 457}, {u'y': 647, u'x': 307}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 501, u'x': 313}, {u'y': 508, u'x': 464}, {u'y': 653, u'x': 457}, {u'y': 647, u'x': 307}]}, u'text': u'\u6c34', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'ja'}]}}, {u'boundingBox': {u'vertices': [{u'y': 499, u'x': 466}, {u'y': 512, u'x': 772}, {u'y': 658, u'x': 765}, {u'y': 645, u'x': 460}]}, u'symbols': [{u'boundingBox': {u'vertices': [{u'y': 503, u'x': 465}, {u'y': 510, u'x': 623}, {u'y': 652, u'x': 617}, {u'y': 645, u'x': 459}]}, u'text': u'\u73af', u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}, {u'boundingBox': {u'vertices': [{u'y': 506, u'x': 620}, {u'y': 513, u'x': 771}, {u'y': 658, u'x': 764}, {u'y': 652, u'x': 614}]}, u'text': u'\u5883', u'property': {u'detectedBreak': {u'type': u'EOL_SURE_SPACE'}, u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}], u'property': {u'detectedLanguages': [{u'languageCode': u'zh-Hans'}]}}]}]}], u'height': 818}]}}]}
In [5]:
foreigntext = responses['responses'][0]['textAnnotations'][0]['description']
foreignlang = responses['responses'][0]['textAnnotations'][0]['locale']
print foreignlang, foreigntext
zh 请您爱护和保
护卫生创建优
美水环境

Translate sign

In [6]:
inputs=[foreigntext]
outputs = service.translations().list(source=foreignlang, target='en', q=inputs).execute()
# print outputs
for input, output in zip(inputs, outputs['translations']):
  print u"{0} -> {1}".format(input, output['translatedText'])
请您爱护和保
护卫生创建优
美水环境
 -> Please love and protect hygiene to create a beautiful water environment

Sentiment analysis with Language API

Let's evaluate the sentiment of some famous quotes using Google Cloud Natural Language API.

In [7]:
lservice = build('language', 'v1beta1', developerKey=APIKEY)
quotes = [
  'To succeed, you must have tremendous perseverance, tremendous will.',
  'It’s not that I’m so smart, it’s just that I stay with problems longer.',
  'Love is quivering happiness.',
  'Love is of all passions the strongest, for it attacks simultaneously the head, the heart, and the senses.',
  'What difference does it make to the dead, the orphans and the homeless, whether the mad destruction is wrought under the name of totalitarianism or in the holy name of liberty or democracy?',
  'When someone you love dies, and you’re not expecting it, you don’t lose her all at once; you lose her in pieces over a long time — the way the mail stops coming, and her scent fades from the pillows and even from the clothes in her closet and drawers. '
]
for quote in quotes:
  response = lservice.documents().analyzeSentiment(
    body={
      'document': {
         'type': 'PLAIN_TEXT',
         'content': quote
      }
    }).execute()
  polarity = response['documentSentiment']['polarity']
  magnitude = response['documentSentiment']['magnitude']
  print('POLARITY=%s MAGNITUDE=%s for %s' % (polarity, magnitude, quote))
POLARITY=1 MAGNITUDE=0.9 for To succeed, you must have tremendous perseverance, tremendous will.
POLARITY=-1 MAGNITUDE=0.5 for It’s not that I’m so smart, it’s just that I stay with problems longer.
POLARITY=1 MAGNITUDE=0.9 for Love is quivering happiness.
POLARITY=1 MAGNITUDE=0.9 for Love is of all passions the strongest, for it attacks simultaneously the head, the heart, and the senses.
POLARITY=1 MAGNITUDE=0.2 for What difference does it make to the dead, the orphans and the homeless, whether the mad destruction is wrought under the name of totalitarianism or in the holy name of liberty or democracy?
POLARITY=-1 MAGNITUDE=0.4 for When someone you love dies, and you’re not expecting it, you don’t lose her all at once; you lose her in pieces over a long time — the way the mail stops coming, and her scent fades from the pillows and even from the clothes in her closet and drawers. 

Speech API

The Speech API can work on streaming data, audio content encoded and embedded directly into the POST message, or on a file on Cloud Storage. Here I'll pass in this audio file in Cloud Storage.

In [8]:
sservice = build('speech', 'v1beta1', developerKey=APIKEY)
response = sservice.speech().syncrecognize(
    body={
        'config': {
            'encoding': 'LINEAR16',
            'sampleRate': 16000
        },
        'audio': {
            'uri': 'gs://cloud-training-demos/vision/audio.raw'
            }
        }).execute()
print response
{u'results': [{u'alternatives': [{u'confidence': 0.98360395, u'transcript': u'how old is the Brooklyn Bridge'}]}]}
In [9]:
print response['results'][0]['alternatives'][0]['transcript']
print 'Confidence=%f' % response['results'][0]['alternatives'][0]['confidence']
how old is the Brooklyn Bridge
Confidence=0.983604

Clean up

Remember to delete the API key by visiting API console.

If necessary, commit all your notebooks to git.

If you are running Datalab on a Compute Engine VM or delegating to one, remember to stop or shut it down so that you are not charged.

Challenge Exercise

Here are a few portraits from the Metropolitan Museum of Art, New York (they are part of a BigQuery public dataset ):

  • gs://cloud-training-demos/images/met/APS6880.jpg
  • gs://cloud-training-demos/images/met/DP205018.jpg
  • gs://cloud-training-demos/images/met/DP290402.jpg
  • gs://cloud-training-demos/images/met/DP700302.jpg

Use the Vision API to identify which of these images depict happy people and which ones depict unhappy people.

Hint (highlight to see):

You will need to look for joyLikelihood and/or sorrowLikelihood from the response.

Copyright 2018 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.