Skip to content

Commit 2742997

Browse files
Created files for Docs API. (#308)
Co-authored-by: himanshupr2627 <himanshupr@google.com>
1 parent 1fb1d92 commit 2742997

2 files changed

Lines changed: 102 additions & 48 deletions

File tree

docs/mail-merge/docs_mail_merge.py

Lines changed: 53 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14+
# pylint: disable=(consider-using-f-string)
1415

1516
"""
1617
docs-mail-merge.py (Python 2.x or 3.x)
@@ -22,17 +23,16 @@
2223

2324
import time
2425

25-
from googleapiclient import discovery
26-
from httplib2 import Http
27-
from oauth2client import client, file, tools
26+
import google.auth
27+
from googleapiclient.discovery import build
28+
from googleapiclient.errors import HttpError
2829

2930
# Fill-in IDs of your Docs template & any Sheets data source
30-
DOCS_FILE_ID = 'YOUR_TMPL_DOC_FILE_ID'
31-
SHEETS_FILE_ID = 'YOUR_SHEET_DATA_FILE_ID'
31+
DOCS_FILE_ID = "195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE"
32+
SHEETS_FILE_ID = "11pPEzi1vCMNbdpqaQx4N43rKmxvZlgEHE9GqpYoEsWw"
3233

3334
# authorization constants
34-
CLIENT_ID_FILE = 'credentials.json'
35-
TOKEN_STORE_FILE = 'token.json'
35+
3636
SCOPES = ( # iterable or space-delimited string
3737
'https://www.googleapis.com/auth/drive',
3838
'https://www.googleapis.com/auth/documents',
@@ -50,33 +50,27 @@
5050
'New York, NY 10011-4962'),
5151
)
5252

53-
54-
def get_http_client():
55-
"""Uses project credentials in CLIENT_ID_FILE along with requested OAuth2
56-
scopes for authorization, and caches API tokens in TOKEN_STORE_FILE.
57-
"""
58-
store = file.Storage(TOKEN_STORE_FILE)
59-
creds = store.get()
60-
if not creds or creds.invalid:
61-
flow = client.flow_from_clientsecrets(CLIENT_ID_FILE, SCOPES)
62-
creds = tools.run_flow(flow, store)
63-
return creds.authorize(Http())
64-
53+
creds, _ = google.auth.default()
54+
# pylint: disable=maybe-no-member
6555

6656
# service endpoints to Google APIs
67-
HTTP = get_http_client()
68-
DRIVE = discovery.build('drive', 'v3', http=HTTP)
69-
DOCS = discovery.build('docs', 'v1', http=HTTP)
70-
SHEETS = discovery.build('sheets', 'v4', http=HTTP)
57+
58+
DRIVE = build('drive', 'v2', credentials=creds)
59+
DOCS = build('docs', 'v1', credentials=creds)
60+
SHEETS = build('sheets', 'v4', credentials=creds)
7161

7262

7363
def get_data(source):
7464
"""Gets mail merge data from chosen data source.
7565
"""
76-
if source not in {'sheets', 'text'}:
77-
raise ValueError('ERROR: unsupported source %r; choose from %r' % (
78-
source, SOURCES))
79-
return SAFE_DISPATCH[source]()
66+
try:
67+
if source not in {'sheets', 'text'}:
68+
raise ValueError(f"ERROR: unsupported source {source}; "
69+
f"choose from {SOURCES}")
70+
return SAFE_DISPATCH[source]()
71+
except HttpError as error:
72+
print(f"An error occurred: {error}")
73+
return error
8074

8175

8276
def _get_text_data():
@@ -91,7 +85,9 @@ def _get_sheets_data(service=SHEETS):
9185
(header) row. Use any desired data range (in standard A1 notation).
9286
"""
9387
return service.spreadsheets().values().get(spreadsheetId=SHEETS_FILE_ID,
94-
range='Sheet1').execute().get('values')[1:] # skip header row
88+
range='Sheet1').execute().get(
89+
'values')[1:]
90+
# skip header row
9591

9692

9793
# data source dispatch table [better alternative vs. eval()]
@@ -102,32 +98,41 @@ def _copy_template(tmpl_id, source, service):
10298
"""(private) Copies letter template document using Drive API then
10399
returns file ID of (new) copy.
104100
"""
105-
body = {'name': 'Merged form letter (%s)' % source}
106-
return service.files().copy(body=body, fileId=tmpl_id,
107-
fields='id').execute().get('id')
101+
try:
102+
body = {'name': 'Merged form letter (%s)' % source}
103+
return service.files().copy(body=body, fileId=tmpl_id,
104+
fields='id').execute().get('id')
105+
except HttpError as error:
106+
print(f"An error occurred: {error}")
107+
return error
108108

109109

110110
def merge_template(tmpl_id, source, service):
111111
"""Copies template document and merges data into newly-minted copy then
112112
returns its file ID.
113113
"""
114-
# copy template and set context data struct for merging template values
115-
copy_id = _copy_template(tmpl_id, source, service)
116-
context = merge.iteritems() if hasattr({}, 'iteritems') else merge.items()
117-
118-
# "search & replace" API requests for mail merge substitutions
119-
reqs = [{'replaceAllText': {
120-
'containsText': {
121-
'text': '{{%s}}' % key.upper(), # {{VARS}} are uppercase
122-
'matchCase': True,
123-
},
124-
'replaceText': value,
125-
}} for key, value in context]
126-
127-
# send requests to Docs API to do actual merge
128-
DOCS.documents().batchUpdate(body={'requests': reqs},
129-
documentId=copy_id, fields='').execute()
130-
return copy_id
114+
try:
115+
# copy template and set context data struct for merging template values
116+
copy_id = _copy_template(tmpl_id, source, service)
117+
context = merge.iteritems() if hasattr({},
118+
'iteritems') else merge.items()
119+
120+
# "search & replace" API requests for mail merge substitutions
121+
reqs = [{'replaceAllText': {
122+
'containsText': {
123+
'text': '{{%s}}' % key.upper(), # {{VARS}} are uppercase
124+
'matchCase': True,
125+
},
126+
'replaceText': value,
127+
}} for key, value in context]
128+
129+
# send requests to Docs API to do actual merge
130+
DOCS.documents().batchUpdate(body={'requests': reqs},
131+
documentId=copy_id, fields='').execute()
132+
return copy_id
133+
except HttpError as error:
134+
print(f"An error occurred: {error}")
135+
return error
131136

132137

133138
if __name__ == '__main__':

docs/output-json/output_json.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright ©2018-2019 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at 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+
"""
16+
ouput-json.py (Python 2.x or 3.x)
17+
Google Docs (REST) API output-json sample app
18+
"""
19+
# [START output_json_python]
20+
from __future__ import print_function
21+
22+
import json
23+
24+
import google.auth
25+
from googleapiclient.discovery import build
26+
from googleapiclient.errors import HttpError
27+
28+
# Set doc ID, as found at `https://docs.google.com/document/d/YOUR_DOC_ID/edit`
29+
DOCUMENT_ID = "195j9eDD3ccgjQRttHhJPymLJUCOUjs-jmwTrekvdjFE"
30+
31+
# Set the scopes and discovery info
32+
SCOPES = 'https://www.googleapis.com/auth/documents.readonly'
33+
DISCOVERY_DOC = ('https://docs.googleapis.com/$discovery/rest?'
34+
'version=v1')
35+
36+
# Initialize credentials and instantiate Docs API service
37+
creds, _ = google.auth.default()
38+
# pylint: disable=maybe-no-member
39+
try:
40+
service = build('docs', 'v1', credentials=creds)
41+
42+
# Do a document "get" request and print the results as formatted JSON
43+
44+
result = service.documents().get(documentId=DOCUMENT_ID).execute()
45+
print(json.dumps(result, indent=4, sort_keys=True))
46+
except HttpError as error:
47+
print(f"An error occurred: {error}")
48+
49+
# [END output_json_python]

0 commit comments

Comments
 (0)