Exploring Google (Cloud) APIs
with Python & JavaScript
Wesley Chun
Developer Advocate
Google Cloud
Exploring Google (Cloud) APIs with Python & JavaScript
G Suite Dev Show
goo.gl/JpBQ40
About the speaker
● Developer Advocate, Google Cloud
● Mission: enable current & future developers to be successful using
Google Cloud and other Google developer tools, APIs, and platforms
● Videos: host of the G Suite Dev Show on YouTube
● Blogs: developers.googleblog.com & gsuite-developers.googleblog.com
● Twitters: @wescpy, @GCPcloud, @GoogleDevs, @GSuiteDevs
● Background
● Software engineer & architect for 20+ years
● One of the original Yahoo!Mail engineers
● Author of bestselling "Core Python" books (corepython.com)
● Teacher and technical instructor since 1983 (all ages)
● Fellow of the Python Software Foundation
● AB Mathematics & CMP Music, UC Berkeley; MSCS UC Santa Barbara
Agenda
● Introduction
● Getting started with Google API projects
● Google Cloud (HTTP-based) REST APIs
● Serverless (compute) platforms
● Miscellaneous & wrap-up
Part I: Introduction
BUT
... wait, there’s more...
Exploring Google (Cloud) APIs with Python & JavaScript
Part II: Getting Started with Google API projects
The first word on Security
Authentication ("authn") vs authorization ("authz")
● authn: you are who you say you are
○ login & passwd
○ handprint authentication
○ retina scan
● authz: okay, you are who you say you are, but can you haz data?
○ OAuth2 - mostly authz, but some authn
○ Mostly about 3rd-party access to data
○ Users must give YOUR app access to THEIR data
○ Most of the time when you see "auth", it refers to authz
Developers Console (devconsole)
Exploring Google (Cloud) APIs with Python & JavaScript
Exploring Google (Cloud) APIs with Python & JavaScript
Exploring Google (Cloud) APIs with Python & JavaScript
Exploring Google (Cloud) APIs with Python & JavaScript
OAuth2 scenarios
● Varies on application type (where apps located)
○ Web (server) applications
○ Installed (mobile & desktop computers) apps
○ Service accounts (cloud/server-to-server)
○ Client-side (JavaScript) apps
○ Limited-input devices (game consoles, printers, cameras, etc.)
○ developers.google.com/identity/protocols/OAuth2
○ TODAY: command-line script == "Installed"
Exploring Google (Cloud) APIs with Python & JavaScript
Exploring Google (Cloud) APIs with Python & JavaScript
Google APIs client
libraries for many
languages; demos in
developers.google.com/
api-client-library
Accessing API client libraries
● Python
○ pip install -U google-api-python-client
○ developers.google.com/api-client-library/
python/start/get_started
● JavaScript ("browser"/client-side)
○ Use gapi.client.request
○ developers.google.com/api-client-library/
javascript/start/start-js
● JavaScript (Node.js/server-side)
○ npm install googleapis
○ googleapis.github.io/google-api-nodejs-client
SIMPLE
AUTHORIZED
Which do you choose?
Simple API access
Google OAuth2 process
● Goal: valid access token == 3rd-party API data access
● How OAuth2 works (in general)
○ Step 1: Create OAuth2 credentials in DevConsole
○ Step 2: Send credentials to get access & refresh tokens
○ Step 3: Use access token to make authorized API calls
○ Step 4: Access tokens expire; use refresh to get new one
● developers.google.com/identity/protocols/OAuth2
● Other APIs will be similar with some differences
Authorized API access
OAuth2
HTTP-based REST APIs 1
HTTP
2
Google APIs request-response workflow
1. Application makes request
2. Request received by service
3. Process data, return response
4. Results sent to application
a.k.a. client-server model
Part III: Google Cloud REST APIs
Exploring Google (Cloud) APIs with Python & JavaScript
Compute
Big Data
BigQuery
Cloud
Pub/Sub
Cloud
Dataproc
Cloud
Datalab
Cloud
Pub/Sub
Genomics
Cloud AI
Cloud Machine
Learning Engine
Cloud
Vision API
Cloud
Speech-to-Text
Cloud Natural
Language API
Cloud
Translation
API
Cloud
Jobs API
Cloud
Dataprep
Cloud Video
Intelligence
API
Advanced
Solutions Lab
Compute
Engine
App
Engine
Kubernetes
Engine
GPU
Cloud
Functions
Container-
Optimized OS
Identity & Security
Cloud IAM
Cloud Resource
Manager
Cloud Security
Scanner
Key
Management
Service
BeyondCorp
Data Loss
Prevention API
Identity-Aware
Proxy
Security Key
Enforcement
Cloud
AutoML
Cloud
Text-to-Speech
Cloud TPU
Dialogflow
Enterprise
Edition
Data Transfer
Transfer
Appliance
Cloud
Composer
Cloud Security
Command
Center
Networking
Virtual
Private Cloud
Cloud Load
Balancing
Cloud
CDN
Dedicated
Interconnect
Cloud DNS
Cloud
Network
Cloud
External IP
Addresses
Cloud
Firewall Rules
Cloud
Routes
Cloud VPN
Management Tools
Stackdriver Monitoring Logging
Error
Reporting
Trace
Debugger
Cloud
Deployment
Manager
Cloud
Console
Cloud
Shell
Cloud Mobile
App
Cloud
Billing API
Cloud
APIs
Cloud
Router
Partner
Interconnect
Cloud Armor
Standard
Network Tier
Premium
Network Tier
Profiler
GCP products and
services without a
unique icon have a
generic hexagon.
Developer Tools
Cloud SDK
Cloud Source
Repositories
Maven App
Engine Plugin
Cloud Tools
for IntelliJ
Cloud
Tools for
PowerShell
Cloud
Tools for
Visual Studio
Container
Registry
Cloud Tools
for Eclipse
Cloud Build
API Platform & Ecosystems
API
Analytics
API
Monetization
Apigee API
Platform
Apigee
Sense
Cloud
Endpoints
Developer
Portal
Gradle App
Engine Plugin
IDE plugins
Internet of Things
Cloud IoT
Core
Storage & Databases
Cloud
Storage
Cloud
Bigtable
Cloud
Datastore
Cloud SQL
Cloud
Spanner
Persistent
Disk
Cloud
Memorystore
Cloud
Filestore
Cloud
Test Lab
Cloud IoT
Edge
G Suite APIs
Proprietary + Confidential
● Launched API v3 (Dec 2015)
○ v2 not deprecated (yet)
● WhatsApp and Google BigQuery
integrations (May 2016)
● Team Drives (Jun 2017)
Drive
Back up your file archives
Write your own or see github.com/gsuitedevs/drive-zipextractor (JS)
Automate photo albums
OR
List (first 100) files/folders in Google Drive
from __future__ import print_function
from apiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
SCOPES = 'https://www.googleapis.com/auth/drive.readonly.metadata'
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
creds = tools.run_flow(flow, store)
DRIVE = discovery.build('drive', 'v3', http=creds.authorize(Http()))
files = DRIVE.files().list().execute().get('files', [])
for f in files:
print(f['name'], f['mimeType'])
Listing your files
goo.gl/ZIgf8k
Proprietary + Confidential
● Launched API v4 (I/O 2016)
● Support text rotation (Mar 2017)
● Developer metadata (Sep 2017)
● Macro recorder (Apr 2018)
Sheets
Powerful API: expect UI features available programmatically
● Create new sheets within
spreadsheets
● Add data to sheets
● Create new spreadsheets
● Set frozen rows
● Text+number formatting
● Enforce cell validation
● Adjust column sizes
● Apply formulas
● Build pivot tables
● Create charts
● … and more!
BEFORE
(<= v3)
AFTER
(>= v4)
Import/Export: Customized reports, “database,” or both!
Try our Node.js customized reporting tool codelab:
g.co/codelabs/sheets
Migrate SQL data to a Sheet
# read SQL data then create new spreadsheet & add rows into it
FIELDS = ('ID', 'Customer Name', 'Product Code',
'Units Ordered', 'Unit Price', 'Status')
cxn = sqlite3.connect('db.sqlite')
cur = cxn.cursor()
rows = cur.execute('SELECT * FROM orders').fetchall()
cxn.close()
rows.insert(0, FIELDS)
DATA = {'properties': {'title': 'Customer orders'}}
SHEET_ID = SHEETS.spreadsheets().create(body=DATA,
fields='spreadsheetId').execute().get('spreadsheetId')
SHEETS.spreadsheets().values().update(spreadsheetId=SHEET_ID, range='A1',
body={'values': rows}, valueInputOption='RAW').execute()
Migrate SQL
data to Sheets
goo.gl/N1RPwC
Format cells (frozen & bold row)
requests = [
# freeze row 1
{'updateSheetProperties': {
'properties': {'gridProperties': {'frozenRowCount': 1}},
'fields': 'gridProperties.frozenRowCount',
}},
# bold row 1
{'repeatCell': {
'range': {'startRowIndex': 0, 'endRowIndex': 1},
'cell': {'userEnteredFormat': {'textFormat': {'bold': True}}},
'fields': 'userEnteredFormat.textFormat.bold',
}},
]
SHEETS.spreadsheets().batchUpdate(body={'requests': requests},
spreadsheetId=SHEET_ID, fields='').execute()
Formatting cells
goo.gl/U6Oljn
● API preview (I/O 2016)
● Launched API v1 (Nov 2016)
● Enhancements “v1.1” (Feb 2017)
● Apps Script support (Sep 2017)
Slides
Try our Node.js Markdown-to-Google-Slides generator:
github.com/googlesamples/md2googleslides
Replace text & images from template deck
requests = [
# (global) search-and-replace text
{'replaceAllText': {
'findText': '{{TITLE}}',
'replaceText': 'Hello World!',
}},
# replace text-based image placeholders (global)
{'replaceAllShapesWithImage': {
'imageUrl': IMG_URL, # link to product logo
'replaceMethod': 'CENTER_INSIDE',
'containsText': {'text': '{{LOGO}}'},
}},
]
SLIDES.presentations().batchUpdate(body={'requests': requests},
presentationId=DECK_ID, fields='').execute()
Replacing text
and images
goo.gl/o6EFwk
Proprietary + Confidential
● Settings endpoints launch (Jul 2016)
● New metadata scope (Nov 2016)
● Gmail Add-ons (Oct 2017)
● Admin SDK Email Settings
deprecation (Oct 2018)
Gmail
Display Gmail threads (& # of messages)
# get all "busy" mail threads & display (non-blank) Subject lines
threads = GMAIL.users().threads().list(userId='me',
fields='threads').execute().get('threads', [])
for thread in threads:
tdata = GMAIL.users().threads().get(userId='me', id=thread['id'],
format='metadata', metadataHeaders=['subject'],
fields='messages/payload/headers(name,value)').execute()
if 'messages' not in tdata:
continue
if len(tdata['messages']) > 10:
msg = tdata['messages'][0]['payload']
subject = ''
for header in msg['headers']:
if header['name'] == 'Subject':
subject = header['value']
break
if subject:
print('%2d message(s) in thread: %s' % (
len(tdata['messages']), subject))
Gmail threads
goo.gl/pFYUQ2
Proprietary + Confidential
● Events on Google Maps (Sep 2016)
● Find a time” on iOS (Sep 2016)
● New Calendar iOS app (Nov 2016)
● New Calendar UI (Oct 2017)
● Hangouts Meet integration in
Calendar API (Dec 2017)
Calendar
Create events in Calendar
# define event data, then create event
TIMEZONE = 'America/Los_Angeles'
EVENT = {
'summary': 'Dinner with friends',
'start': {'dateTime': '2017-06-14T19:00:00', 'timeZone': TIMEZONE},
'end': {'dateTime': '2017-06-14T22:00:00', 'timeZone': TIMEZONE},
'attendees': [
{'email': 'friend1@example.com'},
{'email': 'friend2@example.com'},
],
}
GCAL.events().insert(calendarId='primary', body=EVENT,
sendNotifications=True, fields='').execute()
Modifying and
recurring events
goo.gl/J2XkXc
Creating events
goo.gl/KuYMiq
Proprietary + Confidential
● Launched API v1 EAP (NEXT 2018)
○ developers.google.com/docs
Docs
Global search & replace from template doc
requests = [
# (global) search-and-replace text
{'replaceAllText': {
'containsText': {'text': '{{TITLE}}'},
'replaceText': 'Hello World!',
}},
]
DOCS.documents().batchUpdate(body={'requests': requests},
name='documents/'+DOC_ID, fields='').execute()
Google Cloud Platform
● Added support for Standard SQL
2011 (Sep 2016)
● Launched BigQuery Data Transfer
Service (Mar 2017)
BigQuery
Top 10 most common Shakespeare words
TITLE = "The top 10 most common words in all of Shakespeare's works"
QUERY = '''
SELECT LOWER(word) AS word, sum(word_count) AS count
FROM [bigquery-public-data:samples.shakespeare]
GROUP BY word ORDER BY count DESC LIMIT 10
'''
rsp = BQ.query(body={'query': QUERY}, projectId=PROJ_ID).execute()
print('n*** Results for %r:n' % TITLE)
for col in rsp['schema']['fields']: # HEADERS
print(col['name'].upper(), end='t')
print()
for row in rsp['rows']: # DATA
for col in row['f']:
print(col['v'], end='t')
print()
Google Cloud Platform
Top 10 most common Shakespeare words
$ python3 bq_shake.py
*** Results for "The most common words in all of Shakespeare's works":
WORD COUNT
the 29801
and 27529
i 21029
to 20957
of 18514
a 15370
you 14010
my 12936
in 11722
that 11519
Google Cloud Platform
Google Cloud Platform
● API v1 launch (Nov 2016)
● Extended sentiment entity analysis
& language support (May 2017)
● Automatic content classification
(Sep 2017)
● AutoML Natural Language Beta
release (Cloud NEXT 2018)
Cloud
Natural
Language
What is it, and how does it work?
● Cloud Natural Language API
○ ML algorithms: analyze unstructured text
○ Sentiment & Entity analysis: derive structure & meaning of text
○ Extract information about people, places, events, and more
○ cloud.google.com/natural-language
● Natural Language API requests & responses (JSON)
○ Request payload: content, type, language, encoding
○ Sentiment analysis score: -1.0 (negative) to 1.0 (positive) + magnitude
○ Entity analysis: entity types & metadata, salience, and mentions
○ Entity sentiment analysis: combination of above pair
○ Syntactic analysis: extract sentences and tokens from content
○ Content classification: identified content categories
Google Cloud Platform
[simple API/API key sample]
Simple sentiment & classification analysis
text = '''
Google, headquartered in Mountain View, unveiled the new Android
phone at the Consumer Electronics Show. Sundar Pichai said in
his keynote that users love their new Android phones.'''
data = {'type': 'PLAIN_TEXT', 'content': text}
NL = discovery.build('language', 'v1', developerKey=API_KEY)
sentiment = NL.documents().analyzeSentiment(
body={'document': data}).execute().get('documentSentiment')
print('TEXT:', text)
print('nSENTIMENT: score (%s), magnitude (%s)' % (
sentiment['score'], sentiment['magnitude']))
print('nCATEGORIES:')
categories = NL.documents().classifyText(
body={'document': data}).execute().get('categories')
for c in categories:
print ('* %s (%s)' % (c['name'][1:], c['confidence']))
PY
Sentiment & classification analysis output
$ python3 nl_sent_class.py
TEXT: Google, headquartered in Mountain View, unveiled the new Android
phone at the Consumer Electronics Show. Sundar Pichai said in
his keynote that users love their new Android phones.
SENTIMENT: score (0.3), magnitude (0.6)
CATEGORIES:
* Internet & Telecom (0.76)
* Computers & Electronics (0.64)
* News (0.56)
Google Proprietary + Confidential
● YouTube Data API updates & bug
fixes (Nov 2016)
YouTube
[simple API/API key sample]
Search YouTube for videos
from __future__ import print_function
from apiclient import discovery
from settings import API_KEY
QUERY = 'python -snake'
trim = lambda x, ct: ('%s%s' % (x[:ct],
'...' if len(x)>ct else '')).ljust(ct+3)
print('n** Searching for %r videos...' % QUERY)
YOUTUBE = discovery.build('youtube', 'v3', developerKey=API_KEY)
res = YOUTUBE.search().list(q=QUERY, type='video',
part='id,snippet').execute().get('items', [])
for item in res:
print('http://youtu.be/%st%s' % (
trim(item['id']['videoId'], 24),
trim(item['snippet']['title'], 48)))
Can use multiple APIs in same app
Simple, authorized, or a mix of both API types; re-use HTTP client
from __future__ import print_function
from apiclient import discovery
from httplib2 import Http
from oauth2client import file, client, tools
SCOPES = ( # iterable or space-delimited string
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/spreadsheets.readonly',
'https://www.googleapis.com/auth/presentations',
)
store = file.Storage('storage.json')
creds = store.get()
if not creds or creds.invalid:
flow = client.flow_from_clientsecrets('client_secret.json', SCOPES)
creds = tools.run_flow(flow, store)
HTTP = creds.authorize(Http())
DRIVE = discovery.build('drive', 'v3', http=HTTP)
SHEETS = discovery.build('sheets', 'v4', http=HTTP)
SLIDES = discovery.build('slides', 'v1', http=HTTP)
Part IV: Serverless (compute) platforms
Proprietary + Confidential
● Quizzes in Forms support (Apr 2017)
● Google Slides Service and Add-ons
(Sep 2017)
● Gmail Add-ons (Oct 2017)
● Command-line tool (CLASP), new
API, developer dashboard (Jan 2018)
● Sheets service upgrades (Apr 2018)
Apps
Script
(Sheets-bound) “Hello World!”
“Hello World!” results
Apps Script intro
goo.gl/1sXeuD
What can you do with this?
function sendMap() {
var sheet = SpreadsheetApp.getActiveSheet();
var address = sheet.getRange("A2").getValue();
var map = Maps.newStaticMap().addMarker(address);
MailApp.sendEmail(EMAIL, "Map", map.getMapUrl());
}
JS
Accessing maps from
spreadsheets?!?
goo.gl/oAzBN9
More than you think...
...with help from Google Maps and Gmail
Apps Script powers add-ons & integrations
- Extend functionality of G Suite editors
- Embed your app within ours!
- 2014: Google Docs, Sheets, Forms
- 2017 Q3: Google Slides
- 2017 Q4: Gmail
- 2018 Q1: Hangouts Chat bots
Generating Google Slides from images
Generating Google Slides from images
var NAME = "My favorite images";
var deck = SlidesApp.getActivePresentation();
function addImageSlide(link, index) {
var slide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK);
var image = slide.insertImage(link);
}
function main() {
var images = [
"http://www.google.com/services/images/phone-animation-results_2x.png",
"http://www.google.com/services/images/section-work-card-img_2x.jpg",
"http://gsuite.google.com/img/icons/product-lockup.png",
"http://gsuite.google.com/img/home-hero_2x.jpg",
];
var [title, subtitle] = deck.getSlides()[0].getPageElements();
title.asShape().getText().setText(NAME);
subtitle.asShape().getText().setText("Google Apps ScriptnSlides Service demo");
images.forEach(addImageSlide);
}
Introducing
Slides Add-ons
goo.gl/sYL5AM
Gmail Add-ons
‐ Expense reports
‐ Can't we do them
without leaving Gmail?
‐ On Web AND mobile?
Gmail Add-ons
‐ One place to do your expense report
ExpenseIt! Gmail Add-on
function createExpensesCard(opt_prefills, opt_status) {
var card = CardService.newCardBuilder();
card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense'));
var clearForm = CardService.newAction().setFunctionName('clearForm')
.setParameters({'Status': opt_status ? opt_status : ''});
var clearAction = CardService.newCardAction().setText('Clear form')
.setOnClickAction(clearForm);
card.addCardAction(clearAction);
:
var newSheetSection = CardService.newCardSection();
var sheetName = CardService.newTextInput().setFieldName('Sheet Name')
.setTitle('Sheet Name');
var createExpensesSheet = CardService.newAction()
.setFunctionName('createExpensesSheet');
var newSheetButton = CardService.newTextButton().setText('New Sheet')
.setOnClickAction(createExpensesSheet);
newSheetSection.addWidget(sheetName);
newSheetSection.addWidget(CardService.newButtonSet().addButton(newSheetButton));
card.addSection(formSection);
card.addSection(newSheetSection);
return card;
}
Expediting
expense reports
goo.gl/KUVCDu
Simple vote bot
function onMessage(e) {
return createMessage(e.user.displayName, 0);
}
function onCardClick(e) {
// Create a new vote card when 'NEW' button is clicked.
if (e.action.actionMethodName === 'newvote') {
return createMessage(e.user.displayName, 0);
}
// Updates the card in-place when '+1' or '-1' button is clicked.
var voteCount = +e.action.parameters[0].value;
e.action.actionMethodName === 'upvote' ? ++voteCount : --voteCount;
return createMessage(e.user.displayName, voteCount, true);
}
Vote bot interactive card
function createMessage(voter, voteCount, shouldUpdate) {
var parameters = [{key: 'count', value: voteCount.toString()}];
return {
actionResponse: {
type: shouldUpdate ? 'UPDATE_MESSAGE' : 'NEW_MESSAGE'
},
cards: [{
header: {
title: 'Last vote by ' + voter + '!'
},
sections: [{
widgets: [{
textParagraph: {
text: voteCount + ' votes!'
}
}, {
buttons: [{
textButton: {
text: '+1',
onClick: {
action: {
actionMethodName: 'upvote',
parameters: parameters
}
}
}
}, {
textButton: {
text: '-1',
onClick: {
action: {
actionMethodName: 'downvote',
parameters: parameters
}
}
}
}, {
textButton: {
text: 'NEW',
onClick: {
action: {
actionMethodName: 'newvote'
}
}
}
}]
}]
}]
}]
};
}
Build Hangouts
Chat bots
goo.gl/jt3FqK
Part V: Miscellaneous & wrap-up
● Hangouts Chat launch (Feb 2018)
○ Available to G Suite customers
○ Features bot framework and
API... build chat bots to:
■ Automate workflows
■ Query for information
■ Other heavy-lifting
○ Many development and
hosting options
Hangouts
Chat
Traditional API workflow
Traditional APIs vs. Bot architecture
OAuth2
Bot architecture
Hangouts Chat "echo bot" in Python/Flask
from flask import Flask, request, json
app = Flask(__name__)
@app.route('/', methods=['POST'])
def on_event():
event = request.get_json()
msg = {}
if event['type'] == 'MESSAGE':
text = 'Hi {}. You sent: {}'.format(
event['user']['displayName'], event['message']['text'])
msg = {'text': text}
return json.jsonify(msg)
PY
Hangouts Chat "echo bot" in Node.js/CF4FB
const functions = require('firebase-functions');
exports.echoBot = functions.https.onRequest((req, resp) => {
var msg = {};
if (req.body.type === 'MESSAGE') {
msg = {
text: 'Hi ' + req.body.user.displayName +
'. You sent: ' + req.body.message.text
};
}
return resp.send(msg).end();
});
JS
Other Google APIs & platforms
● Firebase
○ firebase.google.com
● Actions on Google
○ developers.google.com/actions
● YouTube
○ Data, Analytics, and Livestreaming APIs
○ developers.google.com/youtube
● Google Maps
○ Maps, Routes, and Places APIs
○ developers.google.com/maps
References
● Keep up-to-date
○ Blogs: cloud.google.com/blog, developers.googleblog.com,
gsuite-developers.googleblog.com, cloudplatform.googleblog.com
○ Twitters: @wescpy, @GoogleDevs, @GSuiteDevs, @GCPcloud, @GoogleCloud
● Get started today! (introductory hands-on, self-paced codelabs)
○ GCP codelabs: codelabs.developers.google.com/?cat=Cloud
○ G Suite (REST) APIs: g.co/codelabs/gsuite-apis-intro (Drive API)
○ Google Apps Script: g.co/codelabs/apps-script-intro
○ Other G Suite: codelabs.developers.google.com/?cat=Apps
● Read more
○ G Suite dev docs: developers.google.com/gsuite
○ GCP dev docs: cloud.google.com/docs
● NEXT '19 session: Build with All of Google Cloud: G Suite + GCP Interoperability
○ cloud.withgoogle.com/next/sf/sessions?session=DEV212
More references
● API developers console: console.developers.google.com
● GCP developers console: cloud.developers.google.com
● Google APIs Client Libraries: developers.google.com/api-client-library
○ Python: pip{,3} install -U google-api-python-client
○ Special versions for Django, Google App Engine
○ Node.js: npm install googleapis
● Developer video series
○ G Suite Dev Show: goo.gl/JpBQ40
○ Launchpad Online: goo.gl/kFMUa6
● Relevant videos
○ goo.gl/RbyTFD (new Google APIs project setup)
○ goo.gl/KMfbeK (common Python OAuth2 boilerplate code review)
○ goo.gl/ZIgf8k (APIs intro codelab [Drive API])
Thank you!
Questions?
Wesley Chun
Developer Advocate, Google Cloud
@wescpy & @GoogleDevs
twitter.com/{wescpy,googledevs}

More Related Content

PDF
Using Google (Cloud) APIs
PDF
Power your apps with Gmail, Google Drive, Calendar, Sheets, Slides & more
PDF
Qt for beginners part 2 widgets
 
PDF
Gradle presentation
PDF
Convert Your Legacy OpenGL Code to Modern OpenGL with Qt
 
PDF
Gradle - time for a new build
PDF
Meet the Widgets: Another Way to Implement UI
 
Using Google (Cloud) APIs
Power your apps with Gmail, Google Drive, Calendar, Sheets, Slides & more
Qt for beginners part 2 widgets
 
Gradle presentation
Convert Your Legacy OpenGL Code to Modern OpenGL with Qt
 
Gradle - time for a new build
Meet the Widgets: Another Way to Implement UI
 

What's hot (20)

PPTX
Android presentation - Gradle ++
PPTX
The world of gradle - an introduction for developers
PDF
The Ring programming language version 1.7 book - Part 75 of 196
PDF
Gradle - the Enterprise Automation Tool
PPTX
Qt for beginners part 1 overview and key concepts
 
PDF
Rest application
PPTX
NuGet beyond Hello World - DotNext Piter 2017
PDF
The Ring programming language version 1.8 book - Part 77 of 202
PPTX
React inter3
PDF
Gradle plugin, take control of the build
PPTX
Gradle : An introduction
PDF
GDG Cloud Taipei: Meetup #52 - Istio Security: API Authorization
PDF
Gradle by Example
PDF
Making the Most of Your Gradle Builds
PDF
Coscup x ruby conf tw 2021 google cloud buildpacks 剖析與實踐
PDF
A friend in need - A JS indeed
PPTX
Android overview
PPTX
Exploring the power of Gradle in android studio - Basics & Beyond
PDF
Gradle plugins, take it to the next level
PDF
Dev fest 2020 taiwan how to debug microservices on kubernetes as a pros (ht...
Android presentation - Gradle ++
The world of gradle - an introduction for developers
The Ring programming language version 1.7 book - Part 75 of 196
Gradle - the Enterprise Automation Tool
Qt for beginners part 1 overview and key concepts
 
Rest application
NuGet beyond Hello World - DotNext Piter 2017
The Ring programming language version 1.8 book - Part 77 of 202
React inter3
Gradle plugin, take control of the build
Gradle : An introduction
GDG Cloud Taipei: Meetup #52 - Istio Security: API Authorization
Gradle by Example
Making the Most of Your Gradle Builds
Coscup x ruby conf tw 2021 google cloud buildpacks 剖析與實踐
A friend in need - A JS indeed
Android overview
Exploring the power of Gradle in android studio - Basics & Beyond
Gradle plugins, take it to the next level
Dev fest 2020 taiwan how to debug microservices on kubernetes as a pros (ht...
Ad

Similar to Exploring Google (Cloud) APIs with Python & JavaScript (20)

PDF
Introduction to serverless computing on Google Cloud
PDF
Exploring Google (Cloud) APIs & Cloud Computing overview
PDF
Build an AI/ML-driven image archive processing workflow: Image archive, analy...
PDF
Build an AI/ML-driven image archive processing workflow: Image archive, analy...
PDF
Build with ALL of Google Cloud
PDF
Exploring Google APIs 102: Cloud vs. non-GCP Google APIs
PDF
Image archive, analysis & report generation with Google Cloud
PDF
Accessing Google Cloud APIs
PDF
Introduction to Cloud Computing with Google Cloud
PDF
G Suite & Google APIs coding workshop
PDF
Serverless Computing with Google Cloud
PDF
From zero to Google APIs: Beyond search & AI... leverage all of Google
PDF
Exploring Google APIs with Python
PDF
Google Apps Script: Accessing G Suite & other Google services with JavaScript
PDF
Getting started using Google APIs (2019)
PDF
Powerful Google Cloud tools for your hack
PDF
Web App Prototypes with Google App Engine
PDF
Cloud computing overview & Technical intro to Google Cloud
PDF
Google... more than just a cloud
PDF
Exploring Google (Cloud) APIs with Python & JavaScript
Introduction to serverless computing on Google Cloud
Exploring Google (Cloud) APIs & Cloud Computing overview
Build an AI/ML-driven image archive processing workflow: Image archive, analy...
Build an AI/ML-driven image archive processing workflow: Image archive, analy...
Build with ALL of Google Cloud
Exploring Google APIs 102: Cloud vs. non-GCP Google APIs
Image archive, analysis & report generation with Google Cloud
Accessing Google Cloud APIs
Introduction to Cloud Computing with Google Cloud
G Suite & Google APIs coding workshop
Serverless Computing with Google Cloud
From zero to Google APIs: Beyond search & AI... leverage all of Google
Exploring Google APIs with Python
Google Apps Script: Accessing G Suite & other Google services with JavaScript
Getting started using Google APIs (2019)
Powerful Google Cloud tools for your hack
Web App Prototypes with Google App Engine
Cloud computing overview & Technical intro to Google Cloud
Google... more than just a cloud
Exploring Google (Cloud) APIs with Python & JavaScript
Ad

More from wesley chun (17)

PDF
Deploy Basic AI web apps with Serverless Computing from Google Cloud
PDF
Powerful Google developer tools for immediate impact! (2023-24 C)
PDF
Automating Google Workspace (GWS) & more with Apps Script
PDF
Easy path to machine learning (2023-2024)
PDF
Powerful Google developer tools for immediate impact! (2023-24 B)
PDF
Powerful Google developer tools for immediate impact! (2023-24 A)
PDF
Serverless Computing with Python
PDF
Easy path to machine learning (2022)
PDF
Serverless computing with Google Cloud
PDF
Designing flexible apps deployable to App Engine, Cloud Functions, or Cloud Run
PDF
Easy path to machine learning (Spring 2021)
PDF
Exploring Google APIs with Python
PDF
Run your code serverlessly on Google's open cloud
PDF
Serverless Computing with Python
PDF
Easy path to machine learning (Spring 2020)
PDF
Google Cloud @ Hackathons (2020)
PDF
Powerful Google Cloud tools for your hack (2020)
Deploy Basic AI web apps with Serverless Computing from Google Cloud
Powerful Google developer tools for immediate impact! (2023-24 C)
Automating Google Workspace (GWS) & more with Apps Script
Easy path to machine learning (2023-2024)
Powerful Google developer tools for immediate impact! (2023-24 B)
Powerful Google developer tools for immediate impact! (2023-24 A)
Serverless Computing with Python
Easy path to machine learning (2022)
Serverless computing with Google Cloud
Designing flexible apps deployable to App Engine, Cloud Functions, or Cloud Run
Easy path to machine learning (Spring 2021)
Exploring Google APIs with Python
Run your code serverlessly on Google's open cloud
Serverless Computing with Python
Easy path to machine learning (Spring 2020)
Google Cloud @ Hackathons (2020)
Powerful Google Cloud tools for your hack (2020)

Recently uploaded (20)

PPT
Ethics in Information System - Management Information System
PPTX
Reading as a good Form of Recreation
PPT
FIRE PREVENTION AND CONTROL PLAN- LUS.FM.MQ.OM.UTM.PLN.00014.ppt
PDF
Exploring VPS Hosting Trends for SMBs in 2025
PPTX
1402_iCSC_-_RESTful_Web_APIs_--_Josef_Hammer.pptx
PDF
simpleintnettestmetiaerl for the simple testint
PDF
Course Overview and Agenda cloud security
DOCX
Powerful Ways AIRCONNECT INFOSYSTEMS Pvt Ltd Enhances IT Infrastructure in In...
PDF
📍 LABUAN4D EXCLUSIVE SERVER STAR GAMING ASIA NO.1 TERPOPULER DI INDONESIA ! 🌟
PDF
The Ikigai Template _ Recalibrate How You Spend Your Time.pdf
PDF
Lean-Manufacturing-Tools-Techniques-and-How-To-Use-Them.pdf
PPTX
Cyber Hygine IN organizations in MSME or
PPT
250152213-Excitation-SystemWERRT (1).ppt
PDF
BIOCHEM CH2 OVERVIEW OF MICROBIOLOGY.pdf
PPT
12 Things That Make People Trust a Website Instantly
PPTX
AI_Cyberattack_Solutions AI AI AI AI .pptx
PPTX
Layers_of_the_Earth_Grade7.pptx class by
PPTX
Mathew Digital SEO Checklist Guidlines 2025
PPTX
t_and_OpenAI_Combined_two_pressentations
PDF
Alethe Consulting Corporate Profile and Solution Aproach
Ethics in Information System - Management Information System
Reading as a good Form of Recreation
FIRE PREVENTION AND CONTROL PLAN- LUS.FM.MQ.OM.UTM.PLN.00014.ppt
Exploring VPS Hosting Trends for SMBs in 2025
1402_iCSC_-_RESTful_Web_APIs_--_Josef_Hammer.pptx
simpleintnettestmetiaerl for the simple testint
Course Overview and Agenda cloud security
Powerful Ways AIRCONNECT INFOSYSTEMS Pvt Ltd Enhances IT Infrastructure in In...
📍 LABUAN4D EXCLUSIVE SERVER STAR GAMING ASIA NO.1 TERPOPULER DI INDONESIA ! 🌟
The Ikigai Template _ Recalibrate How You Spend Your Time.pdf
Lean-Manufacturing-Tools-Techniques-and-How-To-Use-Them.pdf
Cyber Hygine IN organizations in MSME or
250152213-Excitation-SystemWERRT (1).ppt
BIOCHEM CH2 OVERVIEW OF MICROBIOLOGY.pdf
12 Things That Make People Trust a Website Instantly
AI_Cyberattack_Solutions AI AI AI AI .pptx
Layers_of_the_Earth_Grade7.pptx class by
Mathew Digital SEO Checklist Guidlines 2025
t_and_OpenAI_Combined_two_pressentations
Alethe Consulting Corporate Profile and Solution Aproach

Exploring Google (Cloud) APIs with Python & JavaScript

  • 1. Exploring Google (Cloud) APIs with Python & JavaScript Wesley Chun Developer Advocate Google Cloud
  • 3. G Suite Dev Show goo.gl/JpBQ40 About the speaker ● Developer Advocate, Google Cloud ● Mission: enable current & future developers to be successful using Google Cloud and other Google developer tools, APIs, and platforms ● Videos: host of the G Suite Dev Show on YouTube ● Blogs: developers.googleblog.com & gsuite-developers.googleblog.com ● Twitters: @wescpy, @GCPcloud, @GoogleDevs, @GSuiteDevs ● Background ● Software engineer & architect for 20+ years ● One of the original Yahoo!Mail engineers ● Author of bestselling "Core Python" books (corepython.com) ● Teacher and technical instructor since 1983 (all ages) ● Fellow of the Python Software Foundation ● AB Mathematics & CMP Music, UC Berkeley; MSCS UC Santa Barbara
  • 4. Agenda ● Introduction ● Getting started with Google API projects ● Google Cloud (HTTP-based) REST APIs ● Serverless (compute) platforms ● Miscellaneous & wrap-up Part I: Introduction
  • 7. Part II: Getting Started with Google API projects
  • 8. The first word on Security Authentication ("authn") vs authorization ("authz") ● authn: you are who you say you are ○ login & passwd ○ handprint authentication ○ retina scan ● authz: okay, you are who you say you are, but can you haz data? ○ OAuth2 - mostly authz, but some authn ○ Mostly about 3rd-party access to data ○ Users must give YOUR app access to THEIR data ○ Most of the time when you see "auth", it refers to authz Developers Console (devconsole)
  • 13. OAuth2 scenarios ● Varies on application type (where apps located) ○ Web (server) applications ○ Installed (mobile & desktop computers) apps ○ Service accounts (cloud/server-to-server) ○ Client-side (JavaScript) apps ○ Limited-input devices (game consoles, printers, cameras, etc.) ○ developers.google.com/identity/protocols/OAuth2 ○ TODAY: command-line script == "Installed"
  • 16. Google APIs client libraries for many languages; demos in developers.google.com/ api-client-library Accessing API client libraries ● Python ○ pip install -U google-api-python-client ○ developers.google.com/api-client-library/ python/start/get_started ● JavaScript ("browser"/client-side) ○ Use gapi.client.request ○ developers.google.com/api-client-library/ javascript/start/start-js ● JavaScript (Node.js/server-side) ○ npm install googleapis ○ googleapis.github.io/google-api-nodejs-client
  • 17. SIMPLE AUTHORIZED Which do you choose? Simple API access
  • 18. Google OAuth2 process ● Goal: valid access token == 3rd-party API data access ● How OAuth2 works (in general) ○ Step 1: Create OAuth2 credentials in DevConsole ○ Step 2: Send credentials to get access & refresh tokens ○ Step 3: Use access token to make authorized API calls ○ Step 4: Access tokens expire; use refresh to get new one ● developers.google.com/identity/protocols/OAuth2 ● Other APIs will be similar with some differences Authorized API access
  • 19. OAuth2 HTTP-based REST APIs 1 HTTP 2 Google APIs request-response workflow 1. Application makes request 2. Request received by service 3. Process data, return response 4. Results sent to application a.k.a. client-server model Part III: Google Cloud REST APIs
  • 21. Compute Big Data BigQuery Cloud Pub/Sub Cloud Dataproc Cloud Datalab Cloud Pub/Sub Genomics Cloud AI Cloud Machine Learning Engine Cloud Vision API Cloud Speech-to-Text Cloud Natural Language API Cloud Translation API Cloud Jobs API Cloud Dataprep Cloud Video Intelligence API Advanced Solutions Lab Compute Engine App Engine Kubernetes Engine GPU Cloud Functions Container- Optimized OS Identity & Security Cloud IAM Cloud Resource Manager Cloud Security Scanner Key Management Service BeyondCorp Data Loss Prevention API Identity-Aware Proxy Security Key Enforcement Cloud AutoML Cloud Text-to-Speech Cloud TPU Dialogflow Enterprise Edition Data Transfer Transfer Appliance Cloud Composer Cloud Security Command Center Networking Virtual Private Cloud Cloud Load Balancing Cloud CDN Dedicated Interconnect Cloud DNS Cloud Network Cloud External IP Addresses Cloud Firewall Rules Cloud Routes Cloud VPN Management Tools Stackdriver Monitoring Logging Error Reporting Trace Debugger Cloud Deployment Manager Cloud Console Cloud Shell Cloud Mobile App Cloud Billing API Cloud APIs Cloud Router Partner Interconnect Cloud Armor Standard Network Tier Premium Network Tier Profiler GCP products and services without a unique icon have a generic hexagon.
  • 22. Developer Tools Cloud SDK Cloud Source Repositories Maven App Engine Plugin Cloud Tools for IntelliJ Cloud Tools for PowerShell Cloud Tools for Visual Studio Container Registry Cloud Tools for Eclipse Cloud Build API Platform & Ecosystems API Analytics API Monetization Apigee API Platform Apigee Sense Cloud Endpoints Developer Portal Gradle App Engine Plugin IDE plugins Internet of Things Cloud IoT Core Storage & Databases Cloud Storage Cloud Bigtable Cloud Datastore Cloud SQL Cloud Spanner Persistent Disk Cloud Memorystore Cloud Filestore Cloud Test Lab Cloud IoT Edge G Suite APIs
  • 23. Proprietary + Confidential ● Launched API v3 (Dec 2015) ○ v2 not deprecated (yet) ● WhatsApp and Google BigQuery integrations (May 2016) ● Team Drives (Jun 2017) Drive Back up your file archives Write your own or see github.com/gsuitedevs/drive-zipextractor (JS)
  • 24. Automate photo albums OR List (first 100) files/folders in Google Drive from __future__ import print_function from apiclient import discovery from httplib2 import Http from oauth2client import file, client, tools SCOPES = 'https://www.googleapis.com/auth/drive.readonly.metadata' store = file.Storage('storage.json') creds = store.get() if not creds or creds.invalid: flow = client.flow_from_clientsecrets('client_secret.json', SCOPES) creds = tools.run_flow(flow, store) DRIVE = discovery.build('drive', 'v3', http=creds.authorize(Http())) files = DRIVE.files().list().execute().get('files', []) for f in files: print(f['name'], f['mimeType']) Listing your files goo.gl/ZIgf8k
  • 25. Proprietary + Confidential ● Launched API v4 (I/O 2016) ● Support text rotation (Mar 2017) ● Developer metadata (Sep 2017) ● Macro recorder (Apr 2018) Sheets Powerful API: expect UI features available programmatically ● Create new sheets within spreadsheets ● Add data to sheets ● Create new spreadsheets ● Set frozen rows ● Text+number formatting ● Enforce cell validation ● Adjust column sizes ● Apply formulas ● Build pivot tables ● Create charts ● … and more! BEFORE (<= v3) AFTER (>= v4)
  • 26. Import/Export: Customized reports, “database,” or both! Try our Node.js customized reporting tool codelab: g.co/codelabs/sheets Migrate SQL data to a Sheet # read SQL data then create new spreadsheet & add rows into it FIELDS = ('ID', 'Customer Name', 'Product Code', 'Units Ordered', 'Unit Price', 'Status') cxn = sqlite3.connect('db.sqlite') cur = cxn.cursor() rows = cur.execute('SELECT * FROM orders').fetchall() cxn.close() rows.insert(0, FIELDS) DATA = {'properties': {'title': 'Customer orders'}} SHEET_ID = SHEETS.spreadsheets().create(body=DATA, fields='spreadsheetId').execute().get('spreadsheetId') SHEETS.spreadsheets().values().update(spreadsheetId=SHEET_ID, range='A1', body={'values': rows}, valueInputOption='RAW').execute() Migrate SQL data to Sheets goo.gl/N1RPwC
  • 27. Format cells (frozen & bold row) requests = [ # freeze row 1 {'updateSheetProperties': { 'properties': {'gridProperties': {'frozenRowCount': 1}}, 'fields': 'gridProperties.frozenRowCount', }}, # bold row 1 {'repeatCell': { 'range': {'startRowIndex': 0, 'endRowIndex': 1}, 'cell': {'userEnteredFormat': {'textFormat': {'bold': True}}}, 'fields': 'userEnteredFormat.textFormat.bold', }}, ] SHEETS.spreadsheets().batchUpdate(body={'requests': requests}, spreadsheetId=SHEET_ID, fields='').execute() Formatting cells goo.gl/U6Oljn ● API preview (I/O 2016) ● Launched API v1 (Nov 2016) ● Enhancements “v1.1” (Feb 2017) ● Apps Script support (Sep 2017) Slides
  • 28. Try our Node.js Markdown-to-Google-Slides generator: github.com/googlesamples/md2googleslides
  • 29. Replace text & images from template deck requests = [ # (global) search-and-replace text {'replaceAllText': { 'findText': '{{TITLE}}', 'replaceText': 'Hello World!', }}, # replace text-based image placeholders (global) {'replaceAllShapesWithImage': { 'imageUrl': IMG_URL, # link to product logo 'replaceMethod': 'CENTER_INSIDE', 'containsText': {'text': '{{LOGO}}'}, }}, ] SLIDES.presentations().batchUpdate(body={'requests': requests}, presentationId=DECK_ID, fields='').execute() Replacing text and images goo.gl/o6EFwk Proprietary + Confidential ● Settings endpoints launch (Jul 2016) ● New metadata scope (Nov 2016) ● Gmail Add-ons (Oct 2017) ● Admin SDK Email Settings deprecation (Oct 2018) Gmail
  • 30. Display Gmail threads (& # of messages) # get all "busy" mail threads & display (non-blank) Subject lines threads = GMAIL.users().threads().list(userId='me', fields='threads').execute().get('threads', []) for thread in threads: tdata = GMAIL.users().threads().get(userId='me', id=thread['id'], format='metadata', metadataHeaders=['subject'], fields='messages/payload/headers(name,value)').execute() if 'messages' not in tdata: continue if len(tdata['messages']) > 10: msg = tdata['messages'][0]['payload'] subject = '' for header in msg['headers']: if header['name'] == 'Subject': subject = header['value'] break if subject: print('%2d message(s) in thread: %s' % ( len(tdata['messages']), subject)) Gmail threads goo.gl/pFYUQ2 Proprietary + Confidential ● Events on Google Maps (Sep 2016) ● Find a time” on iOS (Sep 2016) ● New Calendar iOS app (Nov 2016) ● New Calendar UI (Oct 2017) ● Hangouts Meet integration in Calendar API (Dec 2017) Calendar
  • 31. Create events in Calendar # define event data, then create event TIMEZONE = 'America/Los_Angeles' EVENT = { 'summary': 'Dinner with friends', 'start': {'dateTime': '2017-06-14T19:00:00', 'timeZone': TIMEZONE}, 'end': {'dateTime': '2017-06-14T22:00:00', 'timeZone': TIMEZONE}, 'attendees': [ {'email': '[email protected]'}, {'email': '[email protected]'}, ], } GCAL.events().insert(calendarId='primary', body=EVENT, sendNotifications=True, fields='').execute() Modifying and recurring events goo.gl/J2XkXc Creating events goo.gl/KuYMiq Proprietary + Confidential ● Launched API v1 EAP (NEXT 2018) ○ developers.google.com/docs Docs
  • 32. Global search & replace from template doc requests = [ # (global) search-and-replace text {'replaceAllText': { 'containsText': {'text': '{{TITLE}}'}, 'replaceText': 'Hello World!', }}, ] DOCS.documents().batchUpdate(body={'requests': requests}, name='documents/'+DOC_ID, fields='').execute() Google Cloud Platform ● Added support for Standard SQL 2011 (Sep 2016) ● Launched BigQuery Data Transfer Service (Mar 2017) BigQuery
  • 33. Top 10 most common Shakespeare words TITLE = "The top 10 most common words in all of Shakespeare's works" QUERY = ''' SELECT LOWER(word) AS word, sum(word_count) AS count FROM [bigquery-public-data:samples.shakespeare] GROUP BY word ORDER BY count DESC LIMIT 10 ''' rsp = BQ.query(body={'query': QUERY}, projectId=PROJ_ID).execute() print('n*** Results for %r:n' % TITLE) for col in rsp['schema']['fields']: # HEADERS print(col['name'].upper(), end='t') print() for row in rsp['rows']: # DATA for col in row['f']: print(col['v'], end='t') print() Google Cloud Platform Top 10 most common Shakespeare words $ python3 bq_shake.py *** Results for "The most common words in all of Shakespeare's works": WORD COUNT the 29801 and 27529 i 21029 to 20957 of 18514 a 15370 you 14010 my 12936 in 11722 that 11519 Google Cloud Platform
  • 34. Google Cloud Platform ● API v1 launch (Nov 2016) ● Extended sentiment entity analysis & language support (May 2017) ● Automatic content classification (Sep 2017) ● AutoML Natural Language Beta release (Cloud NEXT 2018) Cloud Natural Language What is it, and how does it work? ● Cloud Natural Language API ○ ML algorithms: analyze unstructured text ○ Sentiment & Entity analysis: derive structure & meaning of text ○ Extract information about people, places, events, and more ○ cloud.google.com/natural-language ● Natural Language API requests & responses (JSON) ○ Request payload: content, type, language, encoding ○ Sentiment analysis score: -1.0 (negative) to 1.0 (positive) + magnitude ○ Entity analysis: entity types & metadata, salience, and mentions ○ Entity sentiment analysis: combination of above pair ○ Syntactic analysis: extract sentences and tokens from content ○ Content classification: identified content categories Google Cloud Platform
  • 35. [simple API/API key sample] Simple sentiment & classification analysis text = ''' Google, headquartered in Mountain View, unveiled the new Android phone at the Consumer Electronics Show. Sundar Pichai said in his keynote that users love their new Android phones.''' data = {'type': 'PLAIN_TEXT', 'content': text} NL = discovery.build('language', 'v1', developerKey=API_KEY) sentiment = NL.documents().analyzeSentiment( body={'document': data}).execute().get('documentSentiment') print('TEXT:', text) print('nSENTIMENT: score (%s), magnitude (%s)' % ( sentiment['score'], sentiment['magnitude'])) print('nCATEGORIES:') categories = NL.documents().classifyText( body={'document': data}).execute().get('categories') for c in categories: print ('* %s (%s)' % (c['name'][1:], c['confidence'])) PY Sentiment & classification analysis output $ python3 nl_sent_class.py TEXT: Google, headquartered in Mountain View, unveiled the new Android phone at the Consumer Electronics Show. Sundar Pichai said in his keynote that users love their new Android phones. SENTIMENT: score (0.3), magnitude (0.6) CATEGORIES: * Internet & Telecom (0.76) * Computers & Electronics (0.64) * News (0.56)
  • 36. Google Proprietary + Confidential ● YouTube Data API updates & bug fixes (Nov 2016) YouTube [simple API/API key sample] Search YouTube for videos from __future__ import print_function from apiclient import discovery from settings import API_KEY QUERY = 'python -snake' trim = lambda x, ct: ('%s%s' % (x[:ct], '...' if len(x)>ct else '')).ljust(ct+3) print('n** Searching for %r videos...' % QUERY) YOUTUBE = discovery.build('youtube', 'v3', developerKey=API_KEY) res = YOUTUBE.search().list(q=QUERY, type='video', part='id,snippet').execute().get('items', []) for item in res: print('http://youtu.be/%st%s' % ( trim(item['id']['videoId'], 24), trim(item['snippet']['title'], 48)))
  • 37. Can use multiple APIs in same app Simple, authorized, or a mix of both API types; re-use HTTP client from __future__ import print_function from apiclient import discovery from httplib2 import Http from oauth2client import file, client, tools SCOPES = ( # iterable or space-delimited string 'https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/spreadsheets.readonly', 'https://www.googleapis.com/auth/presentations', ) store = file.Storage('storage.json') creds = store.get() if not creds or creds.invalid: flow = client.flow_from_clientsecrets('client_secret.json', SCOPES) creds = tools.run_flow(flow, store) HTTP = creds.authorize(Http()) DRIVE = discovery.build('drive', 'v3', http=HTTP) SHEETS = discovery.build('sheets', 'v4', http=HTTP) SLIDES = discovery.build('slides', 'v1', http=HTTP) Part IV: Serverless (compute) platforms
  • 38. Proprietary + Confidential ● Quizzes in Forms support (Apr 2017) ● Google Slides Service and Add-ons (Sep 2017) ● Gmail Add-ons (Oct 2017) ● Command-line tool (CLASP), new API, developer dashboard (Jan 2018) ● Sheets service upgrades (Apr 2018) Apps Script (Sheets-bound) “Hello World!”
  • 39. “Hello World!” results Apps Script intro goo.gl/1sXeuD What can you do with this?
  • 40. function sendMap() { var sheet = SpreadsheetApp.getActiveSheet(); var address = sheet.getRange("A2").getValue(); var map = Maps.newStaticMap().addMarker(address); MailApp.sendEmail(EMAIL, "Map", map.getMapUrl()); } JS Accessing maps from spreadsheets?!? goo.gl/oAzBN9 More than you think... ...with help from Google Maps and Gmail
  • 41. Apps Script powers add-ons & integrations - Extend functionality of G Suite editors - Embed your app within ours! - 2014: Google Docs, Sheets, Forms - 2017 Q3: Google Slides - 2017 Q4: Gmail - 2018 Q1: Hangouts Chat bots Generating Google Slides from images
  • 42. Generating Google Slides from images var NAME = "My favorite images"; var deck = SlidesApp.getActivePresentation(); function addImageSlide(link, index) { var slide = deck.appendSlide(SlidesApp.PredefinedLayout.BLANK); var image = slide.insertImage(link); } function main() { var images = [ "http://www.google.com/services/images/phone-animation-results_2x.png", "http://www.google.com/services/images/section-work-card-img_2x.jpg", "http://gsuite.google.com/img/icons/product-lockup.png", "http://gsuite.google.com/img/home-hero_2x.jpg", ]; var [title, subtitle] = deck.getSlides()[0].getPageElements(); title.asShape().getText().setText(NAME); subtitle.asShape().getText().setText("Google Apps ScriptnSlides Service demo"); images.forEach(addImageSlide); } Introducing Slides Add-ons goo.gl/sYL5AM Gmail Add-ons ‐ Expense reports ‐ Can't we do them without leaving Gmail? ‐ On Web AND mobile?
  • 43. Gmail Add-ons ‐ One place to do your expense report ExpenseIt! Gmail Add-on function createExpensesCard(opt_prefills, opt_status) { var card = CardService.newCardBuilder(); card.setHeader(CardService.newCardHeader().setTitle('Log Your Expense')); var clearForm = CardService.newAction().setFunctionName('clearForm') .setParameters({'Status': opt_status ? opt_status : ''}); var clearAction = CardService.newCardAction().setText('Clear form') .setOnClickAction(clearForm); card.addCardAction(clearAction); : var newSheetSection = CardService.newCardSection(); var sheetName = CardService.newTextInput().setFieldName('Sheet Name') .setTitle('Sheet Name'); var createExpensesSheet = CardService.newAction() .setFunctionName('createExpensesSheet'); var newSheetButton = CardService.newTextButton().setText('New Sheet') .setOnClickAction(createExpensesSheet); newSheetSection.addWidget(sheetName); newSheetSection.addWidget(CardService.newButtonSet().addButton(newSheetButton)); card.addSection(formSection); card.addSection(newSheetSection); return card; } Expediting expense reports goo.gl/KUVCDu
  • 44. Simple vote bot function onMessage(e) { return createMessage(e.user.displayName, 0); } function onCardClick(e) { // Create a new vote card when 'NEW' button is clicked. if (e.action.actionMethodName === 'newvote') { return createMessage(e.user.displayName, 0); } // Updates the card in-place when '+1' or '-1' button is clicked. var voteCount = +e.action.parameters[0].value; e.action.actionMethodName === 'upvote' ? ++voteCount : --voteCount; return createMessage(e.user.displayName, voteCount, true); } Vote bot interactive card function createMessage(voter, voteCount, shouldUpdate) { var parameters = [{key: 'count', value: voteCount.toString()}]; return { actionResponse: { type: shouldUpdate ? 'UPDATE_MESSAGE' : 'NEW_MESSAGE' }, cards: [{ header: { title: 'Last vote by ' + voter + '!' }, sections: [{ widgets: [{ textParagraph: { text: voteCount + ' votes!' } }, { buttons: [{ textButton: { text: '+1', onClick: { action: { actionMethodName: 'upvote', parameters: parameters } } } }, { textButton: { text: '-1', onClick: { action: { actionMethodName: 'downvote', parameters: parameters } } } }, { textButton: { text: 'NEW', onClick: { action: { actionMethodName: 'newvote' } } } }] }] }] }] }; } Build Hangouts Chat bots goo.gl/jt3FqK
  • 45. Part V: Miscellaneous & wrap-up ● Hangouts Chat launch (Feb 2018) ○ Available to G Suite customers ○ Features bot framework and API... build chat bots to: ■ Automate workflows ■ Query for information ■ Other heavy-lifting ○ Many development and hosting options Hangouts Chat
  • 46. Traditional API workflow Traditional APIs vs. Bot architecture OAuth2 Bot architecture Hangouts Chat "echo bot" in Python/Flask from flask import Flask, request, json app = Flask(__name__) @app.route('/', methods=['POST']) def on_event(): event = request.get_json() msg = {} if event['type'] == 'MESSAGE': text = 'Hi {}. You sent: {}'.format( event['user']['displayName'], event['message']['text']) msg = {'text': text} return json.jsonify(msg) PY
  • 47. Hangouts Chat "echo bot" in Node.js/CF4FB const functions = require('firebase-functions'); exports.echoBot = functions.https.onRequest((req, resp) => { var msg = {}; if (req.body.type === 'MESSAGE') { msg = { text: 'Hi ' + req.body.user.displayName + '. You sent: ' + req.body.message.text }; } return resp.send(msg).end(); }); JS Other Google APIs & platforms ● Firebase ○ firebase.google.com ● Actions on Google ○ developers.google.com/actions ● YouTube ○ Data, Analytics, and Livestreaming APIs ○ developers.google.com/youtube ● Google Maps ○ Maps, Routes, and Places APIs ○ developers.google.com/maps
  • 48. References ● Keep up-to-date ○ Blogs: cloud.google.com/blog, developers.googleblog.com, gsuite-developers.googleblog.com, cloudplatform.googleblog.com ○ Twitters: @wescpy, @GoogleDevs, @GSuiteDevs, @GCPcloud, @GoogleCloud ● Get started today! (introductory hands-on, self-paced codelabs) ○ GCP codelabs: codelabs.developers.google.com/?cat=Cloud ○ G Suite (REST) APIs: g.co/codelabs/gsuite-apis-intro (Drive API) ○ Google Apps Script: g.co/codelabs/apps-script-intro ○ Other G Suite: codelabs.developers.google.com/?cat=Apps ● Read more ○ G Suite dev docs: developers.google.com/gsuite ○ GCP dev docs: cloud.google.com/docs ● NEXT '19 session: Build with All of Google Cloud: G Suite + GCP Interoperability ○ cloud.withgoogle.com/next/sf/sessions?session=DEV212 More references ● API developers console: console.developers.google.com ● GCP developers console: cloud.developers.google.com ● Google APIs Client Libraries: developers.google.com/api-client-library ○ Python: pip{,3} install -U google-api-python-client ○ Special versions for Django, Google App Engine ○ Node.js: npm install googleapis ● Developer video series ○ G Suite Dev Show: goo.gl/JpBQ40 ○ Launchpad Online: goo.gl/kFMUa6 ● Relevant videos ○ goo.gl/RbyTFD (new Google APIs project setup) ○ goo.gl/KMfbeK (common Python OAuth2 boilerplate code review) ○ goo.gl/ZIgf8k (APIs intro codelab [Drive API])
  • 49. Thank you! Questions? Wesley Chun Developer Advocate, Google Cloud @wescpy & @GoogleDevs twitter.com/{wescpy,googledevs}