profile
viewpoint

PR opened google/new-project

docs: Adds .github folder

docs: Adds .github folder

  • Creates a .github folder to keep the root directory clean.
  • Moves the CONTRIBUTING.md file to a .github folder.
  • Adds a standard ISSUE_TEMPLATE.md
  • Adds a simple, single PULL_REQUEST_TEMPLATE.md
+22 -0

0 comment

3 changed files

pr created time in 3 hours

push eventgrant/new-project

Grant Timmerman

commit sha 2d48950ac5b7642cf6f667d0c3fd05955dba4c42

docs: Adds .github folder

view details

push time in 3 hours

push eventgrant/new-project

Sergey "Shnatsel" Davidoff

commit sha 0c065f12cc4635baef9189e6bb6df246f1ef2cb2

Bump year to 2019

view details

push time in 4 hours

issue commentgoogleapis/google-api-python-client

Documentation not accessible.

With PR #706, I think we can close this and redirect developers to our new API docs/ pages! 🎉

https://github.com/googleapis/google-api-python-client/tree/master/docs

Pardon with the delay for moving these docs, and let up know if there's anything else we should do.

jerrythomas

comment created time in 4 hours

issue commentGoogleCloudPlatform/functions-framework-nodejs

`Validation failed` message when testing function locally from axios call

@QuantumInformation

  • Can you use Node 12?
  • Can you search for the source of that error message? Turn on verbose logging?
QuantumInformation

comment created time in 8 hours

issue commentgoogleapis/google-api-python-client

DevSite Import: Using OAuth 2.0 for Web Server Applications

I don't think this doc was fully imported into https://github.com/googleapis/google-api-python-client/blob/master/docs/oauth-web.md so I will leave it open until it is fully merged.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Python Client Home

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/


Easily access Google APIs from Python

Call Google APIs simply

Use the simple, clean library to make calls from Python to one of the many supported Google APIs. This example uses the Google+ API:

 # List my public Google+ activities.
 result = service.activities().list(userId='me', collection='public').execute()
 tasks = result.get('items', [])
 for task in tasks:
   print task['title']

Use the library with Google App Engine

App Engine-specific helpers make quick work of authenticated calls to APIs. No need to worry about exchanging code for tokens; get right down to writing the meat of your application.

 # Restrict access to users who've granted access to Calendar info.
 decorator = appengine.OAuth2DecoratorFromClientSecrets(
   'client_secrets.json',
   scope='https://www.googleapis.com/auth/calendar')

 class MainHandler(webapp.RequestHandler):
   @decorator.oauth_required
   def get(self):
     http = decorator.http()
     request = service.events().list(calendarId='primary')

Handle auth with fewer lines of code

The easy-to-use authentication library can reduce the code you have to write for OAuth 2.0. Sometimes a few lines is all you need.

 # Authorize server-to-server interactions from Google Compute Engine.
 import httplib2
 from oauth2client.contrib import gce

 credentials = gce.AppAssertionCredentials(
   scope='https://www.googleapis.com/auth/devstorage.read_write')
 http = credentials.authorize(httplib2.Http())

Use standard tools for installation

You can install the library using standard Python tools, and there are custom installs optimized for Google App Engine.

 $ pip install --upgrade google-api-python-client

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Python Client Home

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Support

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/support


Support

If you need help, found a bug, or want to request a feature, this page will direct you to the right place.

Getting help

If you have questions, problems, or comments not addressed by the documentation, visit the Google API Python Client Google Group. Before posting a new message, search the discussions for your topic. You may find that someone has already asked your question.

Support for Google APIs

Each Google API has its own support group. Please post API related questions to the individual support groups found on the API documentation. If you are unsure whether your issue is API or client library related, search both groups for your topic. If you cannot determine the correct group, post your question to the Google API Python Client Google Group.

Reporting bugs or feature requests

You can report bugs and feature requests using the issue tracker on the GitHub site for this library.

Contributing

This library is an open source project on GitHub. If you want to fix a problem or implement a feature yourself, become a contributor.

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Support

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Samples

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/samples/samples


Sample Applications

<section> <p> This page lists sources and information for sample scripts that demonstrate use of this library. </p> <p> Before diving into these samples, you should see the <a href="/api-client-library/python/start/get_started">Getting Started page</a>. It has basic examples covering API keys, OAuth 2.0, web applications, and installed applications. These scripts are thoroughly commented to explain every step. </p> <p> The Google APIs Client Library for Python is an open source project on Google Project Hosting. The library source code and many sample applications can be found there. Follow the instructions on the <a href="/api-client-library/python/start/installation">Installation page</a> to install these samples. The samples cover various application types, library features, platforms, and specific APIs. </p> <p> See the following page for a description of all available samples: <br>     <a href="https://github.com/google/google-api-python-client/blob/master/samples/README.md">Sample Applications page</a> </p> <h3>Running samples</h3> <p> Many of the samples use a client_secrets.json file described in the <a href="/api-client-library/python/guide/aaa_oauth#flow_from_clientsecrets">flow_from_clientsecrets()</a> section of the OAuth 2.0 page. Before running a sample script, you need to update this file. </p> <p> When running a command-line or Google App Engine script locally: </p> <ol>{% include "_shared/apis/console/_navigate-to-credentials.html" %} <li>Under <b>OAuth</b>, click <b>Create New Client ID</b>.</li> <li> Select <b>Installed Application</b> and <b>Other</b> and click <b>Create Client ID</b>.</li> <li>Copy the client ID and client secret values under <b>Client ID for native application</b> and paste into the <code>client_id</code> and <code>client_secret</code> fields in the downloaded client_secrets.json file. </li> </ol> <p> When running a script as a web application or deployed Google App Engine script: </p> <ol>{% include "_shared/apis/console/_navigate-to-credentials.html" %} <li>Under <b>OAuth</b>, click <b>Create New Client ID</b>.</li> <li> Select <b>Web application</b> and click <b>Create Client ID</b>.</li> <li>Copy the client ID and client secret values under <b>Client ID for web application</b> and paste into the <code>client_id</code> and <code>client_secret</code> fields in the downloaded client_secrets.json file. </li> </ol> </section>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Samples

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Interactive Help

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/reference/interactive_help


Interactive Help

<section> <p> You can use Python's <code>help()</code> function in an interactive Python shell to view PyDoc generated documentation at the command-line. This is particularly useful to explore API methods. To do this, construct a service object for the API you are interested in and call help on the objects you construct. </p> <p> From the command-line, start Python, build a service object, and get help on the service: </p> <pre> $ python Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) [GCC 4.4.3] on linux2 Type "help", "copyright", "credits" or "license" for more information.

from googleapiclient.discovery import build service = build("latitude", "v1") help(service)

Help on Resource in module googleapiclient.discovery object:

class Resource(builtin.object) | A class for interacting with a resource. | | Methods defined here: | | init(self) | | currentLocation = methodResource(self) | A collection resource. | | location = methodResource(self) | A collection resource.

Data descriptors defined here:
dict
dictionary for instance variables (if defined)
weakref
list of weak references to the object (if defined)</pre>

<p class="note"> <strong>Note</strong>: The <code>build()</code> function generates a service object at run time, so the initial help information describing an object is too generic to be useful. You can ignore the help header when looking for API-specific details. </p> <p> The help command above output lists <code>currentLocation</code> and <code>location</code> as collection resources. Get help on the <code>location</code> collection: </p> <pre>

help(service.location())

Help on Resource in module googleapiclient.discovery object:

class Resource(builtin.object) | A class for interacting with a resource. | | Methods defined here: | | init(self) | | delete = method(self, **kwargs) | Deletes a location from the user's location history. | | Args: | locationId: string, Timestamp of the location to delete (ms since epoch). (required) | | get = method(self, **kwargs) | Reads a location from the user's location history. | | Args: | locationId: string, Timestamp of the location to read (ms since epoch). (required) | granularity: string, Granularity of the location to return. | | Returns: | An object of the form | | { # A Location resource identifies a user's position at a particular time. It may include metadata about the user's position, such as a venue if the location was recorded at the time of a check-in. | "kind": "latitude#location", # Kind of this item. | "altitude": "", # Altitude of the location, in meters. Optional. | "longitude": "", # Longitude of the location, in decimal degrees. | "activityId": "", # Unique ID of the Buzz message that corresponds to the check-in associated with this location. Available only for check-in locations. Optional. | "latitude": "", # Latitude of the location, in decimal degrees. | "altitudeAccuracy": "", # Accuracy of the altitude value, in meters. Optional. | "timestampMs": "", # Timestamp of the Location Resource, in milliseconds since the epoch (UTC). This is also the Location Resource's unique id. | "speed": "", # Ground speed of the user at the time this location was recorded, in meters per second. Non-negative. Optional. | "heading": "", # Direction of travel of the user when this location was recorded. In degrees, clockwise relative to true north. Optional. | "accuracy": "", # Accuracy of the latitude and longitude coordinates, in non-negative meters. Optional. | } | ...

Data descriptors defined here:
dict
dictionary for instance variables (if defined)
weakref
list of weak references to the object (if defined)</pre>

<p> The help output lists <code>delete</code> as a method. Get help on the <code>delete</code> method: </p> <pre>

help(service.location().delete)

Help on method method in module googleapiclient.discovery:

method(self, **kwargs) method of googleapiclient.discovery.Resource instance Deletes a location from the user's location history.

Args:
  locationId: string, Timestamp of the location to delete (ms since epoch). (required)</pre>

<p> For each method, the arguments are listed along with their types and descriptions. For example, the <code>list</code> method has <code>min_time</code>, <code>max_results</code>, <code>max_time</code>, and <code>granularity</code> arguments. </p> <p> The <code>(required)</code> flag indicates that the argument must be supplied when calling the method; otherwise the argument is optional. </p> <p> Method arguments may also be flagged as <code>(repeated)</code> which indicates that you may pass in a Python list of values for that argument. </p> </section>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Interactive Help

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Installation

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/start/installation


Installation

<div class="devsite-article-body clearfix " itemprop="articleBody">

<section> <p> This page contains information about installing the Google APIs Client Library for Python. </p> </section>

<section id="requirements"> <h2 id="system-requirements"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>System requirements</h2> <ul> <li> <b>Operating systems</b>: <ul> <li>Linux</li> <li>Mac OS X</li> <li>Windows</li> </ul> </li> <li><b><a href="http://python.org/download/">Python 2.7, or 3.4 or higher</a></b></li> </ul> </section> <section id="installation"> <h2 id="installing-the-client-library"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Installing the client library</h2> <p>You can either use a package manager or download and install the Python client library manually:</p> <h3 id="managed-installation">Managed installation</h3> <p>Use pip or setuptools to manage your installation (you might need to run <code>sudo</code> first):</p> <ul> <li> <strong><a href="http://pypi.python.org/pypi/pip">pip</a></strong> (preferred): <pre><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div></div>$ pip install --upgrade google-api-python-client </pre> </li> <li> <strong><a href="http://pypi.python.org/pypi/setuptools">Setuptools</a></strong>: Use the <code>easy_install</code> tool included in the setuptools package: <pre><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div></div>$ easy_install --upgrade google-api-python-client </pre> </li> </ul> <h3 id="manual-installation">Manual installation</h3> <p> <a href="https://pypi.python.org/pypi/google-api-python-client/"> Download the latest client library for Python</a>, unpack the code, and run <code>python setup.py install</code></p> <h3 id="appengine">App Engine</h3> <p>Because the Python client libraries are not installed in the <a href="https://cloud.google.com/appengine/docs/python/">App Engine Python runtime environment</a>, they must be <a href="https://cloud.google.com/appengine/docs/python/tools/libraries27#vendoring"> vendored into your application</a> just like third-party libraries.</p> </section>

<section id="samples"> <h2 id="download-samples"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Download samples</h2> <p> After you have installed the library, you can optionally download and unpack <a href="https://github.com/google/google-api-python-client/tree/master/samples">samples</a>. The package names that start with <em>google-api-python-client-samples-</em> contain samples using this library in many scenarios. See the <a href="https://developers.google.com/api-client-library/python/samples/samples">Sample Applications</a> page for more information about these and other samples. </p> </section>

</div>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Installation

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Authentication Overview

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/aaa_overview


Authentication Overview

<div class="devsite-article-body clearfix " itemprop="articleBody">

<section> <p> This document is an overview of how authentication, authorization, and accounting are accomplished. For all API calls, your application needs to be authenticated. When an API accesses a user's private data, your application must also be authorized by the user to access the data. For example, accessing a public Google+ post would not require user authorization, but accessing a user's private calendar would. Also, for quota and billing purposes, all API calls involve accounting. This document summarizes the protocols used by Google APIs and provides links to more information. </p> </section>

<section id="types"> <h2 id="access-types"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Access types</h2>

<p> It is important to understand the basics of how API authentication and authorization are handled. All API calls must use either simple or authorized access (defined below). Many API methods require authorized access, but some can use either. Some API methods that can use either behave differently, depending on whether you use simple or authorized access. See the API's method documentation to determine the appropriate access type. </p> <h3 id="1-simple-api-access-api-keys">1. Simple API access (API keys)</h3> <p> These API calls do not access any private user data. Your application must authenticate itself as an application belonging to your Google API Console project. This is needed to measure project usage for accounting purposes. </p> <p> <strong>API key</strong>: To authenticate your application, use an <a href="https://developers.google.com/console/help/using-keys">API key</a> for your API Console project. Every simple access call your application makes must include this key. </p><aside class="warning"> <strong>Warning</strong>: Keep your API key private. If someone obtains your key, they could use it to consume your quota or incur charges against your API Console project. </aside> <p></p> <h3 id="2-authorized-api-access-oauth-20">2. Authorized API access (OAuth 2.0)</h3> <p> These API calls access private user data. Before you can call them, the user that has access to the private data must grant your application access. Therefore, your application must be authenticated, the user must grant access for your application, and the user must be authenticated in order to grant that access. All of this is accomplished with <a href="https://developers.google.com/accounts/docs/OAuth2">OAuth 2.0</a> and libraries written for it. </p> <p> <strong>Scope</strong>: Each API defines one or more scopes that declare a set of operations permitted. For example, an API might have read-only and read-write scopes. When your application requests access to user data, the request must include one or more scopes. The user needs to approve the scope of access your application is requesting. </p> <p> <strong>Refresh and access tokens</strong>: When a user grants your application access, the OAuth 2.0 authorization server provides your application with refresh and access tokens. These tokens are only valid for the scope requested. Your application uses access tokens to authorize API calls. Access tokens expire, but refresh tokens do not. Your application can use a refresh token to acquire a new access token. </p><aside class="warning"> <strong>Warning</strong>: Keep refresh and access tokens private. If someone obtains your tokens, they could use them to access private user data. </aside> <p></p> <p> <strong>Client ID and client secret</strong>: These strings uniquely identify your application and are used to acquire tokens. They are created for your project on the <a href="https://console.developers.google.com/">API Console</a>. There are three types of client IDs, so be sure to get the correct type for your application: </p><ul> <li><a href="https://developers.google.com/accounts/docs/OAuth2WebServer">Web application</a> client IDs</li> <li><a href="https://developers.google.com/accounts/docs/OAuth2InstalledApp">Installed application</a> client IDs</li> <li><a href="https://developers.google.com/accounts/docs/OAuth2ServiceAccount">Service Account</a> client IDs</li> </ul> <aside class="warning"> <strong>Warning</strong>: Keep your client secret private. If someone obtains your client secret, they could use it to consume your quota, incur charges against your Console project, and request access to user data. </aside> <p></p>

</section>

<section id="apikeys"> <h2 id="using-api-keys"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Using API keys</h2> <p> More information and examples for API keys are provided on the <a href="https://developers.google.com/api-client-library/python/guide/aaa_apikeys">API Keys</a> page. </p> </section>

<section id="oauth"> <h2 id="using-oauth-20"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Using OAuth 2.0</h2> <p> More information and examples for OAuth 2.0 are provided on the <a href="https://developers.google.com/api-client-library/python/guide/aaa_oauth">OAuth 2.0</a> page. </p> </section>

</div>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Authentication Overview

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Using API Keys

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/auth/api-keys


Using API Keys

<div class="devsite-article-body clearfix " itemprop="articleBody">

<section> <p>When calling APIs that do not access private user data, you can use simple API keys. These keys are used to authenticate your application for accounting purposes. The Google API Console documentation also describes <a href="https://developers.google.com/console/help/using-keys">API keys</a>.</p>

<p class="note"><strong>Note</strong>: If you <em>do</em> need to access private user data, you must use OAuth 2.0. See <a href="https://developers.google.com/api-client-library/python/auth/web-app">Using OAuth 2.0 for Web Server Applications</a>, <a href="https://developers.google.com/api-client-library/python/auth/installed-app">Using OAuth 2.0 for Installed Applications</a>, and <a href="https://developers.google.com/api-client-library/python/auth/service-accounts">Using OAuth 2.0 for Server to Server Applications</a> for more information.</p>

</section>

<section id="acquiring"> <h2 id="acquiring-api-keys"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Acquiring API keys</h2>

<ol>

<li>Open the <a href="https://console.developers.google.com/apis/credentials">Credentials page</a> in the API Console.</li>

<li>Click <b>Create credentials > API key</b> and select the appropriate key type.</li> </ol> <p>To keep your API keys secure, follow the <a href="https://support.google.com/cloud/answer/6310037">best practices for securely using API keys</a>.</p>

</section>

<section id="using"> <h2 id="using-api-keys"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Using API keys</h2>

<p>To use API keys, pass them to the <code><a href="https://google.github.io/google-api-python-client/docs/epy/googleapiclient.discovery-module.html#build">build()</a></code> function when creating service objects. For example:</p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="pln">books_service </span><span class="pun">=</span><span class="pln"> build</span><span class="pun">(</span><span class="str">'books'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'v1'</span><span class="pun">,</span><span class="pln"> developerKey</span><span class="pun">=</span><span class="str">'</span><span class="replaceable-credential" data-tooltip-align="b,c" data-tooltip="Click to insert your credentials" aria-label="Click to insert your credentials"><span class="str">api_key</span></span><span class="str">'</span><span class="pun">)</span></pre> <p>All calls made using that service object will include your API key.</p>

</section>

</div>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Using API Keys

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: OAuth 2.0

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/aaa_oauth


OAuth 2.0

<div class="devsite-article-body clearfix " itemprop="articleBody">

<section> <p> This document describes OAuth 2.0, when to use it, how to acquire client IDs, and how to use it with the Google APIs Client Library for Python. </p> </section>

<section id="oauth"> <h2 id="oauth-20-explained"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>OAuth 2.0 explained</h2> <p> OAuth 2.0 is the authorization protocol used by Google APIs. It is summarized on the <a href="https://developers.google.com/api-client-library/python/guide/aaa_overview">Authentication</a> page of this library's documentation, and there are other good references as well: </p> <ul> <li><a href="https://tools.ietf.org/html/rfc6749">The OAuth 2.0 Authorization Protocol</a></li> <li><a href="https://developers.google.com/accounts/docs/OAuth2">Using OAuth 2.0 to Access Google APIs</a></li> </ul> <div class="video-wrapper"> <iframe src="https://docs.google.com/presentation/embed?id=1KqevSqe6ygWVj4U-wlarKU7-SVR79x-vjpR4gEc4A9Q&start=false&loop=false&delayms=3000" autohide="1" showinfo="0" frameborder="0" allowfullscreen=""></iframe> </div> <p> The protocol is solving a complex problem, so it can be difficult to understand. This presentation explains the important concepts of the protocol, and introduces you to how the library is used at each step. </p> </section>

<section id="acquiring"> <h2 id="acquiring--client-ids-and-secrets"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Acquiring client IDs and secrets</h2> <p> You can get client IDs and secrets on the <a href="https://console.developers.google.com/apis/credentials">API Access pane</a> of the Google APIs Console. There are different types of client IDs, so be sure to get the correct type for your application: </p> <ul> <ul> <li>Web application client IDs</li> <li>Installed application client IDs</li> <li><a href="https://developers.google.com/accounts/docs/OAuth2ServiceAccount">Service Account</a> client IDs</li> </ul> </ul> <p class="warning"> <strong>Warning</strong>: Keep your client secret private. If someone obtains your client secret, they could use it to consume your quota, incur charges against your Google APIs Console project, and request access to user data. </p> </section>

<section id="oauth2client"> <h2 id="the-oauth2client-library"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>The oauth2client library</h2> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/index.html">oauth2client</a> library is included with the Google APIs Client Library for Python. It handles all steps of the OAuth 2.0 protocol required for making API calls. It is available as a separate <a href="https://pypi.python.org/pypi/oauth2client">package</a> if you only need an OAuth 2.0 library. The sections below describe important modules, classes, and functions of this library. </p> </section>

<section id="flows"> <h2 id="flows"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Flows</h2> <p> The purpose of a <code>Flow</code> class is to acquire credentials that authorize your application access to user data. In order for a user to grant access, OAuth 2.0 steps require your application to potentially redirect their browser multiple times. A <code>Flow</code> object has functions that help your application take these steps and acquire credentials. <code>Flow</code> objects are only temporary and can be discarded once they have produced credentials, but they can also be <a href="http://docs.python.org/library/pickle.html">pickled</a> and stored. This section describes the various methods to create and use <code>Flow</code> objects. </p> <p class="note"> <strong>Note</strong>: See the <a href="https://developers.google.com/api-client-library/python/guide/google_app_engine">Using Google App Engine</a> and <a href="https://developers.google.com/api-client-library/python/guide/django">Using Django</a> pages for platform-specific Flows. </p>

<h3 id="flow_from_clientsecrets">flow_from_clientsecrets()</h3> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.flow_from_clientsecrets">oauth2client.client.flow_from_clientsecrets()</a> method creates a <code>Flow</code> object from a <a href="https://developers.google.com/api-client-library/python/guide/aaa_client_secrets">client_secrets.json</a> file. This <a href="http://www.json.org/">JSON</a> formatted file stores your client ID, client secret, and other OAuth 2.0 parameters. </p><p> The following shows how you can use <code>flow_from_clientsecrets()</code> to create a <code>Flow</code> object: </p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> oauth2client</span><span class="pun">.</span><span class="pln">client </span><span class="kwd">import</span><span class="pln"> flow_from_clientsecrets<br></span><span class="pun">...</span><span class="pln"><br>flow </span><span class="pun">=</span><span class="pln"> flow_from_clientsecrets</span><span class="pun">(</span><span class="str">'</span><em><span class="str">path_to_directory</span></em><span class="str">/client_secrets.json'</span><span class="pun">,</span><span class="pln"><br>                               scope</span><span class="pun">=</span><span class="str">'https://www.googleapis.com/auth/calendar'</span><span class="pun">,</span><span class="pln"><br>                               redirect_uri</span><span class="pun">=</span><span class="str">'http://example.com/auth_return'</span><span class="pun">)</span></pre>

<h3 id="OAuth2WebServerFlow">OAuth2WebServerFlow</h3> <p> Despite its name, the <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.OAuth2WebServerFlow">oauth2client.client.OAuth2WebServerFlow</a> class is used for both installed and web applications. It is created by passing the client ID, client secret, and scope to its constructor: You provide the constructor with a <code>redirect_uri</code> parameter. This must be a URI handled by your application. </p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> oauth2client</span><span class="pun">.</span><span class="pln">client </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">OAuth2WebServerFlow</span><span class="pln"><br></span><span class="pun">...</span><span class="pln"><br>flow </span><span class="pun">=</span><span class="pln"> </span><span class="typ">OAuth2WebServerFlow</span><span class="pun">(</span><span class="pln">client_id</span><span class="pun">=</span><span class="str">'</span><em><span class="str">your_client_id</span></em><span class="str">'</span><span class="pun">,</span><span class="pln"><br>                           client_secret</span><span class="pun">=</span><span class="str">'</span><em><span class="str">your_client_secret</span></em><span class="str">'</span><span class="pun">,</span><span class="pln"><br>                           scope</span><span class="pun">=</span><span class="str">'https://www.googleapis.com/auth/calendar'</span><span class="pun">,</span><span class="pln"><br>                           redirect_uri</span><span class="pun">=</span><span class="str">'http://example.com/auth_return'</span><span class="pun">)</span></pre> <h3 id="step1_get_authorize_url">step1_get_authorize_url()</h3> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.OAuth2WebServerFlow.step1_get_authorize_url">step1_get_authorize_url()</a> function of the <code>Flow</code> class is used to generate the authorization server URI. Once you have the authorization server URI, redirect the user to it. The following is an example call to this function: </p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="pln">auth_uri </span><span class="pun">=</span><span class="pln"> flow</span><span class="pun">.</span><span class="pln">step1_get_authorize_url</span><span class="pun">()</span><span class="pln"><br></span><span class="com"># Redirect the user to auth_uri on your platform.</span></pre> <p> If the user has previously granted your application access, the authorization server immediately redirects again to <code>redirect_uri</code>. If the user has not yet granted access, the authorization server asks them to grant your application access. If they grant access, they get redirected to <code>redirect_uri</code> with a <code>code</code> query string parameter similar to the following: </p> <pre><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div></div>http://example.com/auth_return/?code=kACAH-1Ng1MImB...AA7acjdY9pTD9M</pre> <p> If they deny access, they get redirected to <code>redirect_uri</code> with an <code>error</code> query string parameter similar to the following: </p> <pre><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div></div>http://example.com/auth_return/?error=access_denied</pre>

<h3 id="step2_exchange">step2_exchange()</h3> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.OAuth2WebServerFlow.step2_exchange">step2_exchange()</a> function of the <code>Flow</code> class exchanges an authorization code for a <code>Credentials</code> object. Pass the <code>code</code> provided by the authorization server redirection to this function: </p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="pln">credentials </span><span class="pun">=</span><span class="pln"> flow</span><span class="pun">.</span><span class="pln">step2_exchange</span><span class="pun">(</span><span class="pln">code</span><span class="pun">)</span></pre>

</section>

<section id="credentials">

<h2 id="credentials"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Credentials</h2> <p> A <code>Credentials</code> object holds refresh and access tokens that authorize access to a single user's data. These objects are applied to <code>httplib2.Http</code> objects to authorize access. They only need to be applied once and can be stored. This section describes the various methods to create and use <code>Credentials</code> objects. </p> <p class="note"> <strong>Note</strong>: See the <a href="https://developers.google.com/api-client-library/python/guide/google_app_engine">Using Google App Engine</a> and <a href="https://developers.google.com/api-client-library/python/guide/django">Using Django</a> pages for platform-specific Credentials. </p>

<h3 id="OAuth2Credentials">OAuth2Credentials</h3> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.OAuth2Credentials">oauth2client.client.OAuth2Credentials</a> class holds OAuth 2.0 credentials that authorize access to a user's data. Normally, you do not create this object by calling its constructor. A <code>Flow</code> object can create one for you. </p>

<h3 id="ServiceAccountCredentials">ServiceAccountCredentials</h3> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.service_account.html">oauth2client.service_account.ServiceAccountCredentials</a> class is only used with <a href="https://developers.google.com/accounts/docs/OAuth2ServiceAccount">OAuth 2.0 Service Accounts</a>. No end-user is involved for these server-to-server API calls, so you can create this object directly without using a <code>Flow</code> object. </p>

<h3 id="AccessTokenCredentials">AccessTokenCredentials</h3> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.AccessTokenCredentials">oauth2client.client.AccessTokenCredentials</a> class is used when you have already obtained an access token by some other means. You can create this object directly without using a <code>Flow</code> object. </p>

<h3 id="authorize">authorize()</h3> <p> Use the <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.Credentials.authorize">authorize()</a> function of the <code>Credentials</code> class to apply necessary credential headers to all requests made by an <a href="http://bitworking.org/projects/httplib2/doc/html/libhttplib2.html#httplib2.Http">httplib2.Http</a> instance: </p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">import</span><span class="pln"> httplib2<br></span><span class="pun">...</span><span class="pln"><br>http </span><span class="pun">=</span><span class="pln"> httplib2</span><span class="pun">.</span><span class="typ">Http</span><span class="pun">()</span><span class="pln"><br>http </span><span class="pun">=</span><span class="pln"> credentials</span><span class="pun">.</span><span class="pln">authorize</span><span class="pun">(</span><span class="pln">http</span><span class="pun">)</span></pre> <p> Once an <code>httplib2.Http</code> object has been authorized, it is typically passed to the build function: </p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> apiclient</span><span class="pun">.</span><span class="pln">discovery </span><span class="kwd">import</span><span class="pln"> build<br></span><span class="pun">...</span><span class="pln"><br>service </span><span class="pun">=</span><span class="pln"> build</span><span class="pun">(</span><span class="str">'calendar'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'v3'</span><span class="pun">,</span><span class="pln"> http</span><span class="pun">=</span><span class="pln">http</span><span class="pun">)</span></pre>

</section>

<section id="storage"> <h2 id="storage"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Storage</h2> <p> A <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.Storage">oauth2client.client.Storage</a> object stores and retrieves <code>Credentials</code> objects. This section describes the various methods to create and use <code>Storage</code> objects. </p> <p class="note"> <strong>Note</strong>: See the <a href="https://developers.google.com/api-client-library/python/guide/google_app_engine">Using Google App Engine</a> and <a href="https://developers.google.com/api-client-library/python/guide/django">Using Django</a> pages for platform-specific Storage. </p> <h3 id="fileStorage">file.Storage</h3> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.file.html#oauth2client.file.Storage">oauth2client.file.Storage</a> class stores and retrieves a single <code>Credentials</code> object. The class supports locking such that multiple processes and threads can operate on a single store. The following shows how to open a file, save <code>Credentials</code> to it, and retrieve those credentials: </p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> oauth2client</span><span class="pun">.</span><span class="pln">file </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Storage</span><span class="pln"><br></span><span class="pun">...</span><span class="pln"><br>storage </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Storage</span><span class="pun">(</span><span class="str">'</span><em><span class="str">a_credentials_file</span></em><span class="str">'</span><span class="pun">)</span><span class="pln"><br>storage</span><span class="pun">.</span><span class="pln">put</span><span class="pun">(</span><span class="pln">credentials</span><span class="pun">)</span><span class="pln"><br></span><span class="pun">...</span><span class="pln"><br>credentials </span><span class="pun">=</span><span class="pln"> storage</span><span class="pun">.</span><span class="kwd">get</span><span class="pun">()</span></pre> <h3 id="multistore_file">multistore_file</h3> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.contrib.multistore_file.html">oauth2client.contrib.multistore_file</a> module allows multiple credentials to be stored. The credentials are keyed off of: </p> <ul> <li>client ID</li> <li>user agent</li> <li>scope</li> </ul>

<h3 id="keyring_storage">keyring_storage</h3> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.contrib.keyring_storage.html">oauth2client.contrib.keyring_storage</a> module allows a single <code>Credentials</code> object to be stored in a <a href="http://en.wikipedia.org/wiki/Password_manager">password manager</a> if one is available.

The credentials are keyed off of:

</p> <ul> <li>Name of the client application</li> <li>User name</li> </ul> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> oauth2client</span><span class="pun">.</span><span class="pln">contrib</span><span class="pun">.</span><span class="pln">keyring_storage </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">Storage</span><span class="pln"><br></span><span class="pun">...</span><span class="pln"><br>storage </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Storage</span><span class="pun">(</span><span class="str">'</span><em><span class="str">application name</span></em><span class="str">'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'</span><em><span class="str">user name</span></em><span class="str">'</span><span class="pun">)</span><span class="pln"><br>storage</span><span class="pun">.</span><span class="pln">put</span><span class="pun">(</span><span class="pln">credentials</span><span class="pun">)</span><span class="pln"><br></span><span class="pun">...</span><span class="pln"><br>credentials </span><span class="pun">=</span><span class="pln"> storage</span><span class="pun">.</span><span class="kwd">get</span><span class="pun">()</span></pre> </section>

<section id="commandline"> <h2 id="command-line-tools"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Command-line tools</h2> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.tools.html#oauth2client.tools.run_flow">oauth2client.tools.run_flow()</a> function can be used by command-line applications to acquire credentials. It takes a <code>Flow</code> argument and attempts to open an authorization server page in the user's default web browser. The server asks the user to grant your application access to the user's data. If the user grants access, the run() function returns new credentials. The new credentials are also stored in the <code>Storage</code> argument, which updates the file associated with the <code>Storage</code> object. </p> <p> The <a href="http://oauth2client.readthedocs.org/en/latest/source/oauth2client.tools.html#oauth2client.tools.run_flow">oauth2client.tools.run_flow()</a> function is controlled by command-line flags, and the Python standard library <a href="http://docs.python.org/dev/library/argparse.html">argparse</a> module must be initialized at the start of your program. Argparse is included in Python 2.7+, and is available as a <a href="https://pypi.python.org/pypi/argparse">separate package</a> for older versions. The following shows an example of how to use this function: </p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">import</span><span class="pln"> argparse<br></span><span class="kwd">from</span><span class="pln"> oauth2client </span><span class="kwd">import</span><span class="pln"> tools<br><br>parser </span><span class="pun">=</span><span class="pln"> argparse</span><span class="pun">.</span><span class="typ">ArgumentParser</span><span class="pun">(</span><span class="pln">parents</span><span class="pun">=[</span><span class="pln">tools</span><span class="pun">.</span><span class="pln">argparser</span><span class="pun">])</span><span class="pln"><br>flags </span><span class="pun">=</span><span class="pln"> parser</span><span class="pun">.</span><span class="pln">parse_args</span><span class="pun">()</span><span class="pln"><br></span><span class="pun">...</span><span class="pln"><br>credentials </span><span class="pun">=</span><span class="pln"> tools</span><span class="pun">.</span><span class="pln">run_flow</span><span class="pun">(</span><span class="pln">flow</span><span class="pun">,</span><span class="pln"> storage</span><span class="pun">,</span><span class="pln"> flags</span><span class="pun">)</span></pre>

</section>

</div>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: OAuth 2.0

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Using OAuth 2.0 for Installed Applications

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/auth/installed-app


DevSite Import: Using OAuth 2.0 for Installed Applications

<div class="devsite-article-body clearfix " itemprop="articleBody">

<section>

<p>The Google APIs Client Library for Python supports using OAuth 2.0 in applications that are installed on a device such as a computer, a cell phone, or a tablet. Installed apps are distributed to individual machines, and it is assumed that these apps cannot keep secrets. These apps might access a Google API while the user is present at the app, or when the app is running in the background.</p> <figure id="fig1"> If you are developing for Android or iOS, use Google+ Sign-In. </figure> <p>This document is for you if:</p> <ul> <li>You are writing an installed app for a platform other than Android or iOS, and</li> <li>Your installed app will run on devices that have a system browser and rich input capabilities, such as devices with full keyboards.</li> </ul> <p>If you are writing an app for Android or iOS, use <a href="https://developers.google.com/identity">Google Sign-In</a> to authenticate your users. The Google Sign-In button manages the OAuth 2.0 flow both for authentication and for obtaining authorization to Google APIs. To add the Google Sign-In button, follow the steps for <a href="https://developers.google.com/identity/sign-in/android">Android</a> or <a href="https://developers.google.com/identity/sign-in/ios">iOS</a>.</p> <p>If your app will run on devices that do not have access to a system browser, or devices with limited input capabilities (for example, if your app will run on game consoles, video cameras, or printers), then see <a href="https://developers.google.com/accounts/docs/OAuth2ForDevices">Using OAuth 2.0 for Devices</a>.</p>

</section>

<section>

<ol class="toc"> <li><a href="#overview">Overview</a></li> <li><a href="#creatingcred">Creating application credentials</a></li> <li><a href="#creatingclient">Configuring the client object</a> <ul> <li><a href="#choosingredirecturi">Choosing a redirect URI</a></li> </ul> </li> <li><a href="#sendingtogoogle">Sending users to to Google's OAuth 2.0 server</a></li> <li><a href="#handlingresponse">Handling the OAuth 2.0 server response</a></li> <li><a href="#callinganapi">Calling Google APIs</a></li> <li><a href="#example">Complete example</a></li> </ol>

</section>

<section>

<h2 id="overview"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Overview</h2> <p>To use OAuth 2.0 in a locally-installed application, first create application credentials for your project in the API Console.</p>

<p>Then, when your application needs to access a user's data with a Google API, your application sends the user to Google's OAuth 2.0 server. The OAuth 2.0 server authenticates the user and obtains consent from the user for your application to access the user's data.</p>

<p>Next, Google's OAuth 2.0 server sends a single-use authorization code to your application, either in the title bar of the browser or in the query string of an HTTP request to the local host. Your application exchanges this authorization code for an access token.</p>

<p>Finally, your application can use the access token to call Google APIs.</p>

<p>This flow is similar to the one shown in the <a href="https://developers.google.com/api-client-library/python/auth/web-app">Using OAuth 2.0 for Web Server Applications</a>, but with three differences:</p> <ul> <li>When creating a client ID, you specify that your application is an Installed application. This results in a different value for the <code>redirect_uri</code> parameter.</li> <li>The client ID and client secret obtained from the API Console are embedded in the source code of your application. In this context, the client secret is obviously not treated as a secret.</li> <li>The authorization code can be returned to your application in the title bar of the browser or in the query string of an HTTP request to the local host.</li> </ul>

</section>

<section>

<h2 id="creatingcred"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Creating application credentials</h2> <p>All applications that use OAuth 2.0 must have credentials that identify the application to the OAuth 2.0 server. Applications that have these credentials can access the APIs that you enabled for your project.</p> <p>To obtain application credentials for your project, complete these steps:</p> <ol>

<li>Open the <a href="https://console.developers.google.com/apis/credentials">Credentials page</a> in the API Console.</li>

<li>If you haven't done so already, create your OAuth 2.0 credentials by clicking <b>Create new Client ID</b> under the <b>OAuth</b> heading and selecting the <b>Installed application</b> type. Next, look for your application's client ID and client secret in the relevant table.</li> </ol> <p>Download the client_secrets.json file and securely store it in a location that only your application can access.</p> <aside class="note"><b>Important:</b> Do not store the client_secrets.json file in a publicly-accessible location, and if you share the source code to your application—for example, on GitHub—store the client_secrets.json file outside of your source tree to avoid inadvertently sharing your client credentials.</aside>

</section>

<section>

<h2 id="creatingclient"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Configuring the client object</h2> <p>Use the client application credentials that you created to configure a client object in your application. When you configure a client object, you specify the scopes your application needs to access, along with a redirect URI, which will handle the response from the OAuth 2.0 server.</p>

<section> <h3 id="choosingredirecturi">Choosing a redirect URI</h3> <p>When you create a client ID in the <a href="https://console.developers.google.com/">Google API Console</a>, two <code>redirect_uri</code> parameters are created for you: <code>urn:ietf:wg:oauth:2.0:oob</code> and <code>http://localhost</code>. The value your application uses determines how the authorization code is returned to your application.</p>

<h4>http://localhost</h4> <p>This value signals to the Google Authorization Server that the authorization code should be returned as a query string parameter to the web server on the client. You can specify a port number without changing the <a href="https://console.developers.google.com/">Google API Console</a> configuration. To receive the authorization code using this URI, your application must be listening on the local web server. This is possible on many, but not all, platforms. If your platform supports it, this is the recommended mechanism for obtaining the authorization code.</p> <p class="note"><b>Note</b>: In some cases, although it is possible to listen, other software (such as a Windows firewall) prevents delivery of the message without significant client configuration.</p>

<h4>urn:ietf:wg:oauth:2.0:oob</h4> <p>This value signals to the Google Authorization Server that the authorization code should be returned in the title bar of the browser, with the page text prompting the user to copy the code and paste it in the application. This is useful when the client (such as a Windows application) cannot listen on an HTTP port without significant client configuration.</p> <p>When you use this value, your application can then detect that the page has loaded, and can read the title of the HTML page to obtain the authorization code. It is then up to your application to close the browser window if you want to ensure that the user never sees the page that contains the authorization code. The mechanism for doing this varies from platform to platform.</p> <p>If your platform doesn't allow you to detect that the page has loaded or read the title of the page, you can have the user paste the code back to your application, as prompted by the text in the confirmation page that the OAuth 2.0 server generates.</p>

<h4>urn:ietf:wg:oauth:2.0:oob:auto </h4> <p>This is identical to urn:ietf:wg:oauth:2.0:oob, but the text in the confirmation page that the OAuth 2.0 server generates won't instruct the user to copy the authorization code, but instead will simply ask the user to close the window.</p> <p>This is useful when your application reads the title of the HTML page (by checking window titles on the desktop, for example) to obtain the authorization code, but can't close the page on its own.</p> </section>

<h3 id="creating-the-object">Creating the object</h3>

<p>To create a client object from the client_secrets.json file, use the <code>flow_from_clientsecrets</code> function. For example, to request read-only access to a user's Google Drive:</p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> google_auth_oauthlib</span><span class="pun">.</span><span class="pln">flow </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">InstalledAppFlow</span><span class="pln"><br><br>flow </span><span class="pun">=</span><span class="pln"> </span><span class="typ">InstalledAppFlow</span><span class="pun">.</span><span class="pln">from_client_secrets_file</span><span class="pun">(</span><span class="pln"><br>    </span><span class="str">'client_secret.json'</span><span class="pun">,</span><span class="pln"><br>    scopes</span><span class="pun">=[</span><span class="str">'https://www.googleapis.com/auth/drive.metadata.readonly'</span><span class="pun">])</span></pre>

<p>Your application uses the client object to perform OAuth 2.0 operations, such as generating authorization request URIs and applying access tokens to HTTP requests.</p>

</section>

<section>

<h2 id="sendingtogoogle"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Sending users to Google's OAuth 2.0 server</h2> <p>Use either the <code>run_console</code> or <code>run_local_server</code> function to direct the user to Google's OAuth 2.0 server:</p>

<ul> <li> <p>The <code>run_console</code> function instructs the user to open the authorization URL in their browser. After the user authorizes the application, the authorization server displays a web page with an authorization code, which the user then pastes into the application. The authorization library automatically exchanges the code for an access token.</p> <pre><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div></div>credentials = flow.run_console()</pre> </li> <li> <p>The <code>run_local_server</code> function attempts to open the authorization URL in the user's browser. It also starts a local web server to listen for the authorization response. After the user completes the auth flow, the authorization server redirects the user's browser to the local web server. That server gets the authorization code from the browser and shuts down, then exchanges the code for an access token.</p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="pln">credentials </span><span class="pun">=</span><span class="pln"> flow</span><span class="pun">.</span><span class="pln">run_local_server</span><span class="pun">(</span><span class="pln">host</span><span class="pun">=</span><span class="str">'localhost'</span><span class="pun">,</span><span class="pln"><br>    port</span><span class="pun">=</span><span class="lit">8080</span><span class="pun">,</span><span class="pln"> <br>    authorization_prompt_message</span><span class="pun">=</span><span class="str">'Please visit this URL: {url}'</span><span class="pun">,</span><span class="pln"> <br>    success_message</span><span class="pun">=</span><span class="str">'The auth flow is complete; you may close this window.'</span><span class="pun">,</span><span class="pln"><br>    open_browser</span><span class="pun">=</span><span class="kwd">True</span><span class="pun">)</span></pre> </li> </ul>

<p>Google's OAuth 2.0 server authenticates the user and obtains consent from the user for your application to access the requested scopes.</p>

</section>

<section>

</section>

<section>

<h2 id="callinganapi"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Calling Google APIs</h2>

<p>Use the authorized <code>Http</code> object to call Google APIs by completing the following steps:</p> <ol> <li>Build a service object for the API that you want to call. You build a a service object by calling the <code>build</code> function with the name and version of the API and the authorized <code>Http</code> object. For example, to call version 2 of the Drive API: <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> googleapiclient</span><span class="pun">.</span><span class="pln">discovery </span><span class="kwd">import</span><span class="pln"> build<br><br>drive_service </span><span class="pun">=</span><span class="pln"> build</span><span class="pun">(</span><span class="str">'drive'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'v3'</span><span class="pun">,</span><span class="pln"> credentials</span><span class="pun">=</span><span class="pln">credentials</span><span class="pun">)</span></pre></li> <li>Make requests to the API service using the <a href="https://developers.google.com/api-client-library/python/start/get_started#build">interface provided by the service object</a>. For example, to list the files in the authenticated user's Google Drive: <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="pln">files </span><span class="pun">=</span><span class="pln"> drive_service</span><span class="pun">.</span><span class="pln">files</span><span class="pun">().</span><span class="pln">list</span><span class="pun">().</span><span class="pln">execute</span><span class="pun">()</span></pre> </li> </ol>

</section>

<section>

<h2 id="example"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Complete example</h2> <p>The following example requests access to the user's Google Drive files. If the user grants access, the code retrieves and prints a JSON-formatted list of the five Drive files that were most recently modified by the user. </p> <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">import</span><span class="pln"> os<br></span><span class="kwd">import</span><span class="pln"> pprint<br><br></span><span class="kwd">import</span><span class="pln"> google</span><span class="pun">.</span><span class="pln">oauth2</span><span class="pun">.</span><span class="pln">credentials<br><br></span><span class="kwd">from</span><span class="pln"> googleapiclient</span><span class="pun">.</span><span class="pln">discovery </span><span class="kwd">import</span><span class="pln"> build<br></span><span class="kwd">from</span><span class="pln"> googleapiclient</span><span class="pun">.</span><span class="pln">errors </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">HttpError</span><span class="pln"><br></span><span class="kwd">from</span><span class="pln"> google_auth_oauthlib</span><span class="pun">.</span><span class="pln">flow </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">InstalledAppFlow</span><span class="pln"><br><br>pp </span><span class="pun">=</span><span class="pln"> pprint</span><span class="pun">.</span><span class="typ">PrettyPrinter</span><span class="pun">(</span><span class="pln">indent</span><span class="pun">=</span><span class="lit">2</span><span class="pun">)</span><span class="pln"><br><br></span><span class="com"># The CLIENT_SECRETS_FILE variable specifies the name of a file that contains</span><span class="pln"><br></span><span class="com"># the OAuth 2.0 information for this application, including its client_id and</span><span class="pln"><br></span><span class="com"># client_secret.</span><span class="pln"><br>CLIENT_SECRETS_FILE </span><span class="pun">=</span><span class="pln"> </span><span class="str">"client_secret.json"</span><span class="pln"><br><br></span><span class="com"># This access scope grants read-only access to the authenticated user's Drive</span><span class="pln"><br></span><span class="com"># account.</span><span class="pln"><br>SCOPES </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="str">'https://www.googleapis.com/auth/drive.metadata.readonly'</span><span class="pun">]</span><span class="pln"><br>API_SERVICE_NAME </span><span class="pun">=</span><span class="pln"> </span><span class="str">'drive'</span><span class="pln"><br>API_VERSION </span><span class="pun">=</span><span class="pln"> </span><span class="str">'v3'</span><span class="pln"><br><br></span><span class="kwd">def</span><span class="pln"> get_authenticated_service</span><span class="pun">():</span><span class="pln"><br>  flow </span><span class="pun">=</span><span class="pln"> </span><span class="typ">InstalledAppFlow</span><span class="pun">.</span><span class="pln">from_client_secrets_file</span><span class="pun">(</span><span class="pln">CLIENT_SECRETS_FILE</span><span class="pun">,</span><span class="pln"> SCOPES</span><span class="pun">)</span><span class="pln"><br>  credentials </span><span class="pun">=</span><span class="pln"> flow</span><span class="pun">.</span><span class="pln">run_console</span><span class="pun">()</span><span class="pln"><br>  </span><span class="kwd">return</span><span class="pln"> build</span><span class="pun">(</span><span class="pln">API_SERVICE_NAME</span><span class="pun">,</span><span class="pln"> API_VERSION</span><span class="pun">,</span><span class="pln"> credentials </span><span class="pun">=</span><span class="pln"> credentials</span><span class="pun">)</span><span class="pln"><br><br></span><span class="kwd">def</span><span class="pln"> list_drive_files</span><span class="pun">(</span><span class="pln">service</span><span class="pun">,</span><span class="pln"> </span><span class="pun"></span><span class="pln">kwargs</span><span class="pun">):</span><span class="pln"><br>  results </span><span class="pun">=</span><span class="pln"> service</span><span class="pun">.</span><span class="pln">files</span><span class="pun">().</span><span class="pln">list</span><span class="pun">(</span><span class="pln"><br>    </span><span class="pun"></span><span class="pln">kwargs<br>  </span><span class="pun">).</span><span class="pln">execute</span><span class="pun">()</span><span class="pln"><br><br>  pp</span><span class="pun">.</span><span class="pln">pprint</span><span class="pun">(</span><span class="pln">results</span><span class="pun">)</span><span class="pln"><br><br></span><span class="kwd">if</span><span class="pln"> name </span><span class="pun">==</span><span class="pln"> </span><span class="str">'main'</span><span class="pun">:</span><span class="pln"><br>  </span><span class="com"># When running locally, disable OAuthlib's HTTPs verification. When</span><span class="pln"><br>  </span><span class="com"># running in production do not leave this option enabled.</span><span class="pln"><br>  os</span><span class="pun">.</span><span class="pln">environ</span><span class="pun">[</span><span class="str">'OAUTHLIB_INSECURE_TRANSPORT'</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">'1'</span><span class="pln"><br>  service </span><span class="pun">=</span><span class="pln"> get_authenticated_service</span><span class="pun">()</span><span class="pln"><br>  list_drive_files</span><span class="pun">(</span><span class="pln">service</span><span class="pun">,</span><span class="pln"><br>                   orderBy</span><span class="pun">=</span><span class="str">'modifiedByMeTime desc'</span><span class="pun">,</span><span class="pln"><br>                   pageSize</span><span class="pun">=</span><span class="lit">5</span><span class="pun">)</span></pre>

</section>

</div>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Using OAuth 2.0 for Installed Applications

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Using OAuth 2.0 for Server to Server Applications

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/auth/service-accounts


Using OAuth 2.0 for Server to Server Applications

<div class="devsite-article-body clearfix " itemprop="articleBody">

<section>

<p>The Google APIs Client Library for Python supports using OAuth 2.0 for server-to-server interactions such as those between a web application and a Google service. For this scenario you need a <dfn>service account</dfn>, which is an account that belongs to your application instead of to an individual end user. Your application calls Google APIs on behalf of the service account, so users aren't directly involved. This scenario is sometimes called "two-legged OAuth," or "2LO." (The related term "three-legged OAuth" refers to scenarios in which your application calls Google APIs on behalf of end users, and in which user consent is sometimes required.)</p>

<p>Typically, an application uses a service account when the application uses Google APIs to work with its own data rather than a user's data. For example, an application that uses <a href="//cloud.google.com/datastore/">Google Cloud Datastore</a> for data persistence would use a service account to authenticate its calls to the Google Cloud Datastore API.</p>

<p>If you have a Google Apps domain—if you use <a href="//gsuite.google.com/">G Suite</a>, for example—an administrator of the Google Apps domain can authorize an application to access user data on behalf of users in the Google Apps domain. For example, an application that uses the <a href="//developers.google.com/google-apps/calendar/">Google Calendar API</a> to add events to the calendars of all users in a Google Apps domain would use a service account to access the Google Calendar API on behalf of users. Authorizing a service account to access data on behalf of users in a domain is sometimes referred to as "delegating domain-wide authority" to a service account.</p>

<aside class="note"><b>Note:</b> When you use <a href="//www.google.com/enterprise/marketplace/">Google Apps Marketplace</a> to install an application for your domain, the required permissions are automatically granted to the application. You do not need to manually authorize the service accounts that the application uses.</aside>

<aside class="note"><strong>Note:</strong> Although you can use service accounts in applications that run from a Google Apps domain, service accounts are not members of your Google Apps account and aren't subject to domain policies set by Google Apps administrators. For example, a policy set in the Google Apps admin console to restrict the ability of Apps end users to share documents outside of the domain would not apply to service accounts. </aside>

<p>This document describes how an application can complete the server-to-server OAuth 2.0 flow by using the Google APIs Client Library for Python.</p>

</section>

<section>

<ol class="toc"> <li><a href="#overview">Overview</a></li> <li><a href="#creatinganaccount">Creating a service account</a> <ol> <li><a href="#delegatingauthority">Delegating domain-wide authority to the service account</a></li> </ol> </li> <li><a href="#authorizingrequests">Preparing to make an authorized API call</a></li> <li><a href="#callinganapi">Calling Google APIs</a></li> <li><a href="#example">Complete example</a></li> </ol>

</section>

<section>

<h2 id="overview"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Overview</h2> <p>To support server-to-server interactions, first create a service account for your project in the API Console. If you want to access user data for users in your Google Apps domain, then delegate domain-wide access to the service account.</p>

<p>Then, your application prepares to make authorized API calls by using the service account's credentials to request an access token from the OAuth 2.0 auth server.</p>

<p>Finally, your application can use the access token to call Google APIs.</p>

</section>

<section>

<h2 id="creatinganaccount"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Creating a service account</h2> <p>A service account's credentials include a generated email address that is unique, a client ID, and at least one public/private key pair.</p> <p>If your application runs on Google App Engine, a service account is set up automatically when you create your project.</p>

<p>If your application runs on Google Compute Engine, a service account is also set up automatically when you create your project, but you must specify the scopes that your application needs access to when you create a Google Compute Engine instance. For more information, see <a href="//cloud.google.com/compute/docs/authentication#using">Preparing an instance to use service accounts</a>.</p>

<p>If your application doesn't run on Google App Engine or Google Compute Engine, you must obtain these credentials in the Google API Console. To generate service-account credentials, or to view the public credentials that you've already generated, do the following:</p>

<ol> <li>Open the <a href="https://console.developers.google.com/iam-admin/serviceaccounts"><b>Service accounts</b> page</a>. If prompted, select a project.</li> <li>Click <b>Create service account</b>.</li> <li>

In the <b>Create service account</b> window, type a name for the service
account, and select <b>Furnish a new private key</b>. If you want to
<a href="https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority">grant
G Suite domain-wide authority</a> to the service account, also select
<b>Enable G Suite Domain-wide Delegation</b>.

Then click <b>Save</b>.</li>

</ol> <p>Your new public/private key pair is generated and downloaded to your machine; it serves as the only copy of this key. You are responsible for storing it securely.</p>

<p>You can return to the <a href="https://console.developers.google.com/" target="_blank">API Console</a> at any time to view the client ID, email address, and public key fingerprints, or to generate additional public/private key pairs. For more details about service account credentials in the API Console, see <a href="https://developers.google.com/console/help/service-accounts">Service accounts</a> in the API Console help file.</p> <p>Take note of the service account's email address and store the service account's private key file in a location accessible to your application. Your application needs them to make authorized API calls.</p> <aside class="note"> <b>Note: </b>You must store and manage private keys securely in both development and production environments. Google does not keep a copy of your private keys, only your public keys. </aside>

<h3 id="delegatingauthority">Delegating domain-wide authority to the service account</h3> <p>If your application runs in a Google Apps domain and accesses user data, the service account that you created needs to be granted access to the user data that you want to access.</p> <p>The following steps must be performed by an administrator of the Google Apps domain:</p> <ol> <li>Go to your Google Apps domain’s <a href="http://admin.google.com">Admin console</a>.</li> <li>Select <b>Security</b> from the list of controls. If you don't see <b>Security</b> listed, select <b>More controls</b> from the gray bar at the bottom of the page, then select <b>Security</b> from the list of controls. If you can't see the controls, make sure you're signed in as an administrator for the domain.</li> <li>Select <b>Advanced settings</b> from the list of options.</li> <li>Select <b>Manage third party OAuth Client access</b> in the <b>Authentication</b> section.</li> <li>In the <b>Client name</b> field enter the service account's <b>Client ID</b>. </li><li>In the <b>One or More API Scopes</b> field enter the list of scopes that your application should be granted access to. For example, if your application needs domain-wide access to the Google Drive API and the Google Calendar API, enter: <kbd>https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar</kbd>. </li><li>Click <b>Authorize</b>. </li></ol> <p>Your application now has the authority to make API calls as users in your domain (to "impersonate" users). When you prepare to make authorized API calls, you specify the user to impersonate.</p>

</section>

<section>

<h2 id="authorizingrequests"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Preparing to make an authorized API call</h2>

<p>After you obtain the client email address and private key from the API Console, complete the following steps:</p> <ol>

<li>Install the required libraries: <pre><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div></div>pip install google-auth google-auth-httplib2 google-api-python-client </pre> </li>

<li><p>Create a <code>Credentials</code> object from the service account's credentials and the scopes your application needs access to. For example:

  </p><div class="devsite-table-wrapper"><table>
    <tbody><tr>
      <th>Platform</th>
      <th>Example Code</th>
    </tr>
    <tr>
      <td>Google App Engine standard environment</td>
      <td>

<pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> google</span><span class="pun">.</span><span class="pln">auth </span><span class="kwd">import</span><span class="pln"> app_engine<br><br>SCOPES </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="str">'https://www.googleapis.com/auth/sqlservice.admin'</span><span class="pun">]</span><span class="pln"><br><br>credentials </span><span class="pun">=</span><span class="pln"> app_engine</span><span class="pun">.</span><span class="typ">Credentials</span><span class="pun">(</span><span class="pln">scopes</span><span class="pun">=</span><span class="pln">SCOPES</span><span class="pun">)</span></pre>

        <aside class="note"><b>Note:</b> You can only use
        App Engine credential objects in
        applications that are running in a Google App Engine standard environment.
        If you need to run your application in other
        environments—for example, to test your application
        locally—you must detect this situation and use a different
        credential mechanism (see <a href="#jwtsample">Other platforms</a>).
        </aside>
        
      </td>
    </tr>
    <tr>
      <td>Google Compute Engine</td>
      <td>

<pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> google</span><span class="pun">.</span><span class="pln">auth </span><span class="kwd">import</span><span class="pln"> compute_engine<br><br>credentials </span><span class="pun">=</span><span class="pln"> compute_engine</span><span class="pun">.</span><span class="typ">Credentials</span><span class="pun">()</span></pre>

        <p>You must <a href="https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#changeserviceaccountandscopes">configure
        your Compute Engine instance to allow access to the necessary scopes</a>.</p>
        
        <aside class="note"><b>Note:</b> You can only use
        Compute Engine credential objects in
        applications that are running on Google
        Compute Engine. If you need to run your application in other
        environments—for example, to test your application
        locally—you must detect this situation and use a different
        credential mechanism (see <a href="#jwtsample">Other platforms</a>).
        
        You can use the
        <a href="https://developers.google.com/accounts/docs/application-default-credentials">application
        default credentials</a> to simplify this process.
        
        </aside>
        
      </td>
    </tr>
    <tr>
      <td id="jwtsample">Other platforms</td>
      <td>

<pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> google</span><span class="pun">.</span><span class="pln">oauth2 </span><span class="kwd">import</span><span class="pln"> service_account<br><br>SCOPES </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="str">'https://www.googleapis.com/auth/sqlservice.admin'</span><span class="pun">]</span><span class="pln"><br>SERVICE_ACCOUNT_FILE </span><span class="pun">=</span><span class="pln"> </span><span class="str">'/path/to/service.json'</span><span class="pln"><br><br>credentials </span><span class="pun">=</span><span class="pln"> service_account</span><span class="pun">.</span><span class="typ">Credentials</span><span class="pun">.</span><span class="pln">from_service_account_file</span><span class="pun">(</span><span class="pln"><br>        SERVICE_ACCOUNT_FILE</span><span class="pun">,</span><span class="pln"> scopes</span><span class="pun">=</span><span class="pln">SCOPES</span><span class="pun">)</span></pre>

      </td>
    </tr>
  </tbody></table></div>
  <p></p>

<p>If you have delegated domain-wide access to the service account and you want to impersonate a user account, use the <code>with_subject</code> method of an existing <code>service_account.Credentials</code> object. For example:

</p><pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="pln">delegated_credentials </span><span class="pun">=</span><span class="pln"> credentials</span><span class="pun">.</span><span class="pln">with_subject</span><span class="pun">(</span><span class="str">'user@example.org'</span><span class="pun">)</span></pre>

<p></p>

</li>

</ol>

<p>Use the <code>Credentials</code> object to call Google APIs in your application.</p>

</section>

<section>

<h2 id="callinganapi"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Calling Google APIs</h2>

<p>To call a Google API using the <code>Credentials</code> object, complete the following steps:</p> <ol> <li>Build a service object for the API that you want to call. You build a service object by calling the <code>build</code> function with the name and version of the API and the authorized <code>Http</code> object. For example, to call version 1beta3 of the <a href="//cloud.google.com/sql/docs/admin-api/">Cloud SQL Administration API</a>: <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">import</span><span class="pln"> googleapiclient</span><span class="pun">.</span><span class="pln">discovery<br><br>sqladmin </span><span class="pun">=</span><span class="pln"> googleapiclient</span><span class="pun">.</span><span class="pln">discovery</span><span class="pun">.</span><span class="pln">build</span><span class="pun">(</span><span class="str">'sqladmin'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'v1beta3'</span><span class="pun">,</span><span class="pln"> credentials</span><span class="pun">=</span><span class="pln">credentials</span><span class="pun">)</span></pre></li> <li>Make requests to the API service using the <a href="https://developers.google.com/api-client-library/python/start/get_started#build">interface provided by the service object</a>. For example, to list the instances of Cloud SQL databases in the example-123 project: <pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="pln">response </span><span class="pun">=</span><span class="pln"> sqladmin</span><span class="pun">.</span><span class="pln">instances</span><span class="pun">().</span><span class="pln">list</span><span class="pun">(</span><span class="pln">project</span><span class="pun">=</span><span class="str">'example-123'</span><span class="pun">).</span><span class="pln">execute</span><span class="pun">()</span></pre></li> </ol>

</section>

<section>

<h2 id="example"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Complete example</h2> <p>The following example prints a JSON-formatted list of Cloud SQL instances in a project.</p>

<pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> google</span><span class="pun">.</span><span class="pln">oauth2 </span><span class="kwd">import</span><span class="pln"> service_account<br></span><span class="kwd">import</span><span class="pln"> googleapiclient</span><span class="pun">.</span><span class="pln">discovery<br><br>SCOPES </span><span class="pun">=</span><span class="pln"> </span><span class="pun">[</span><span class="str">'https://www.googleapis.com/auth/sqlservice.admin'</span><span class="pun">]</span><span class="pln"><br>SERVICE_ACCOUNT_FILE </span><span class="pun">=</span><span class="pln"> </span><span class="str">'/path/to/service.json'</span><span class="pln"><br><br>credentials </span><span class="pun">=</span><span class="pln"> service_account</span><span class="pun">.</span><span class="typ">Credentials</span><span class="pun">.</span><span class="pln">from_service_account_file</span><span class="pun">(</span><span class="pln"><br>        SERVICE_ACCOUNT_FILE</span><span class="pun">,</span><span class="pln"> scopes</span><span class="pun">=</span><span class="pln">SCOPES</span><span class="pun">)</span><span class="pln"><br>sqladmin </span><span class="pun">=</span><span class="pln"> googleapiclient</span><span class="pun">.</span><span class="pln">discovery</span><span class="pun">.</span><span class="pln">build</span><span class="pun">(</span><span class="str">'sqladmin'</span><span class="pun">,</span><span class="pln"> </span><span class="str">'v1beta3'</span><span class="pun">,</span><span class="pln"> credentials</span><span class="pun">=</span><span class="pln">credentials</span><span class="pun">)</span><span class="pln"><br>response </span><span class="pun">=</span><span class="pln"> sqladmin</span><span class="pun">.</span><span class="pln">instances</span><span class="pun">().</span><span class="pln">list</span><span class="pun">(</span><span class="pln">project</span><span class="pun">=</span><span class="str">'exemplary-example-123'</span><span class="pun">).</span><span class="pln">execute</span><span class="pun">()</span><span class="pln"><br><br></span><span class="kwd">print</span><span class="pun">(</span><span class="pln">response</span><span class="pun">)</span></pre>

</section>

</div>


Part of HTML table doesn't render. It is screenshotted here:

Screen Shot 2019-06-06 at 14 31 33

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Using OAuth 2.0 for Server to Server Applications

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Client Secrets

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/aaa_client_secrets


Client Secrets

<div class="devsite-article-body clearfix " itemprop="articleBody">

<section> <p> The Google APIs Client Library for Python uses the client_secrets.json file format for storing the <code>client_id</code>, <code>client_secret</code>, and other OAuth 2.0 parameters. </p> </section>

<section id="client_secrets"> <p> The client_secrets.json file format is a <a href="http://www.json.org/">JSON</a> formatted file containing the client ID, client secret, and other OAuth 2.0 parameters. Here is an example client_secrets.json file for a web application: </p> <pre><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div></div>{ "web": { "client_id": "asdfjasdljfasdkjf", "client_secret": "1912308409123890", "redirect_uris": ["https://www.example.com/oauth2callback"], "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://accounts.google.com/o/oauth2/token" } }</pre> <p> Here is an example client_secrets.json file for an installed application: </p> <pre><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div></div>{ "installed": { "client_id": "837647042410-75ifg...usercontent.com", "client_secret":"asdlkfjaskd", "redirect_uris": ["http://localhost", "urn:ietf:wg:oauth:2.0:oob"], "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://accounts.google.com/o/oauth2/token" } }</pre> <p> The format defines one of two client ID types: </p> <ul> <li><code>web</code>: Web application.</li> <li><code>installed</code>: Installed application.</li> </ul> <p> The <code>web</code> and <code>installed</code> sub-objects have the following mandatory members: </p> <ul> <li> <code>client_id</code> (string): The client ID. </li> <li> <code>client_secret</code> (string): The client secret. </li> <li> <code>redirect_uris</code> (list of strings): A list of valid redirection endpoint URIs. This list should match the list entered for the client ID on the <a href="https://code.google.com/apis/console#:access">API Access pane</a> of the Google APIs Console. </li> <li> <code>auth_uri</code> (string): The authorization server endpoint URI. </li> <li> <code>token_uri</code> (string): The token server endpoint URI. </li> </ul>

<p>All of the above members are mandatory. The following optional parameters may appear:</p>

<ul> <li> <code>client_email</code> (string) The service account email associated with the client. </li> <li> <code>auth_provider_x509_cert_url</code> (string) The URL of the public x509 certificate, used to verify the signature on JWTs, such as ID tokens, signed by the authentication provider. </li> <li> <code>client_x509_cert_url</code> (string) The URL of the public x509 certificate, used to verify JWTs signed by the client. </li> </ul>

<p> The following examples show how use a <b>client_secrets.json</b> file to create a <code>Flow</code> object in either an installed application or a web application: </p> <section class="kd-tabbed-horz ui-datasection-main" id="client-secret-examples"><div class="kd-buttonbar kd-tabbar-horz"><header class="kd-tabbutton selected" kd-data-id=":Installed app" aria-label="Installed app, selected" role="button" tabindex="0" data-ds-scope="code">Installed app</header><header class="kd-tabbutton" kd-data-id=":Web server app" aria-label="Web server app" role="button" tabindex="0" data-ds-scope="code">Web server app</header><a class="devsite-overflow-menu-button kd-tabbutton" style="display: none;">More</a></div><article class="selected">

<pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">from</span><span class="pln"> google_auth_oauthlib</span><span class="pun">.</span><span class="pln">flow </span><span class="kwd">import</span><span class="pln"> </span><span class="typ">InstalledAppFlow</span><span class="pln"><br></span><span class="pun">...</span><span class="pln"><br>flow </span><span class="pun">=</span><span class="pln"> </span><span class="typ">InstalledAppFlow</span><span class="pun">.</span><span class="pln">from_client_secrets_file</span><span class="pun">(</span><span class="pln"><br>&nbsp; &nbsp; </span><span class="str">'</span><em><span class="str">path_to_directory</span></em><span class="str">/client_secret.json'</span><span class="pun">,</span><span class="pln"><br>&nbsp; &nbsp; scopes</span><span class="pun">=[</span><span class="str">'https://www.googleapis.com/auth/calendar'</span><span class="pun">])</span></pre>
</article><article>
  
<pre class="prettyprint"><div class="devsite-code-button-wrapper"><div class="devsite-code-button gc-analytics-event material-icons devsite-dark-code-button" data-category="Site-Wide Custom Events" data-label="Dark Code Toggle" track-type="exampleCode" track-name="darkCodeToggle" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Dark code theme" aria-label="Dark code theme" data-title="Dark code theme"></div><div class="devsite-code-button gc-analytics-event material-icons devsite-click-to-copy-button" data-category="Site-Wide Custom Events" data-label="Click To Copy" track-type="exampleCode" track-name="clickToCopy" tabindex="0" role="button" data-tooltip-align="b,c" data-tooltip="Click to copy" aria-label="Click to copy" data-title="Click to copy"></div></div><span class="kwd">import</span><span class="pln"> google</span><span class="pun">.</span><span class="pln">oauth2</span><span class="pun">.</span><span class="pln">credentials<br></span><span class="kwd">import</span><span class="pln"> google_auth_oauthlib</span><span class="pun">.</span><span class="pln">flow<br><br>flow </span><span class="pun">=</span><span class="pln"> google_auth_oauthlib</span><span class="pun">.</span><span class="pln">flow</span><span class="pun">.</span><span class="typ">Flow</span><span class="pun">.</span><span class="pln">from_client_secrets_file</span><span class="pun">(</span><span class="pln"><br>&nbsp; &nbsp; </span><span class="str">'</span><em><span class="str">path_to_directory</span></em><span class="str">/client_secret.json'</span><span class="pun">,</span><span class="pln"><br>&nbsp; &nbsp; scopes</span><span class="pun">=[</span><span class="str">'https://www.googleapis.com/auth/calendar'</span><span class="pun">])</span><span class="pln"><br><br>flow</span><span class="pun">.</span><span class="pln">redirect_uri </span><span class="pun">=</span><span class="pln"> </span><span class="str">'https://www.example.com/oauth2callback'</span></pre>
</article></section>

</section>

<section id="motivation"> <h2 id="motivation"><a href="#top_of_page" class="devsite-back-to-top-link material-icons" data-tooltip-align="b,c" data-tooltip="Back to top" aria-label="Back to top" data-title="Back to top"></a>Motivation</h2> <p> Traditionally providers of OAuth endpoints have relied upon cut-and-paste as the way users of their service move the client id and secret from a registration page into working code. That can be error prone, along with it being an incomplete picture of all the information that is needed to get OAuth 2.0 working, which requires knowing all the endpoints and configuring a Redirect Endpoint. If service providers start providing a downloadable client_secrets.json file for client information and client libraries start consuming client_secrets.json then a large amount of friction in implementing OAuth 2.0 can be reduced. </p> </section>

</div>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Client Secrets

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Logging

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/logging


Logging

This page provides logging tips to help you debug your applications.

Log Level

You can enable logging of key events in this library by configuring Python's standard logging module. You can set the logging level to one of the following:

  • CRITICAL (least amount of logging)
  • ERROR
  • WARNING
  • INFO
  • DEBUG (most amount of logging)

In the following code, the logging level is set to INFO, and the Google Translate API is called:

import logging
from apiclient.discovery import build

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def main():
  service = build('translate', 'v2', developerKey='your_api_key')
  print service.translations().list(
      source='en',
      target='fr',
      q=['flower', 'car']
    ).execute()

if __name__ == '__main__':
  main()

The output of this code should print basic logging info:

INFO:root:URL being requested: https://www.googleapis.com/discovery/v1/apis/translate/v2/rest
INFO:root:URL being requested: https://www.googleapis.com/language/translate/v2?q=flower&q=car&source=en&alt=json&target=fr&key=your_api_key
{u'translations': [{u'translatedText': u'fleur'}, {u'translatedText': u'voiture'}]}

HTTP Traffic

For even more detailed logging you can set the debug level of the httplib2 module used by this library. The following code snippet enables logging of all HTTP request and response headers and bodies:

import httplib2
httplib2.debuglevel = 4

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Logging

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Upload Media

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/media_upload


Media Upload

Some API methods support uploading media files in addition to a regular body. All of these methods have a parameter called media_body. For example, if we had a fictional Farm service that allowed managing animals on a farm, the insert method might allow you to upload an image of the animal when adding it to the collection of all animals. The documentation for this method could be:

insert = method(self, **kwargs)
Adds an animal to the farm.

Args:
  body: object, The request body. (required)
  media_body: string or MediaUpload, Picture of the animal.

In the following example, the filename of an image is supplied:

response = farm.animals().insert(media_body='pig.png', body={'name': 'Pig'}).execute()

Alternatively, if you want to explicitly control the MIME type of the file sent, use the googleapiclient.http.MediaFileUpload class for the media_body value:

media = MediaFileUpload('pig.png', mimetype='image/png')
response = farm.animals().insert(media_body=media, body={'name': 'Pig'}).execute()

Resumable media (chunked upload)

For large media files, you can use resumable media uploads to send files, which allows files to be uploaded in smaller chunks. This is especially useful if you are transferring large files, and the likelihood of a network interruption or some other transmission failure is high. It can also reduce your bandwidth usage in the event of network failures because you don't have to restart large file uploads from the beginning.

To use resumable media you must use a MediaFileUpload object and flag it as a resumable upload. You then repeatedly call next_chunk() on the googleapiclient.http.HttpRequest object until the upload is complete. In the following code, the status object reports the progress of the upload, and the response object is created once the upload is complete:

media = MediaFileUpload('pig.png', mimetype='image/png', resumable=True)
request = farm.animals().insert(media_body=media, body={'name': 'Pig'})
response = None
while response is None:
  status, response = request.next_chunk()
  if status:
    print "Uploaded %d%%." % int(status.progress() * 100)
print "Upload Complete!"

You can also change the default chunk size by using the chunksize parameter:

media = MediaFileUpload('pig.png', mimetype='image/png', chunksize=1048576, resumable=True)

Chunk size restriction: There are some chunk size restrictions based on the size of the file you are uploading. Files larger than 256 KB (256 * 1024 B) must have chunk sizes that are multiples of 256 KB. For files smaller than 256 KB, there are no restrictions. In either case, the final chunk has no limitations; you can simply transfer the remaining bytes.

If a request fails, an googleapiclient.errors.HttpError exception is thrown, which should be caught and handled. If the error is retryable, the upload can be resumed by continuing to call request.next_chunk(), but subsequent calls must use an exponential backoff strategy for retries. The retryable error status codes are:

  • 404 Not Found (must restart upload)
  • 500 Internal Server Error
  • 502 Bad Gateway
  • 503 Service Unavailable
  • 504 Gateway Timeout

The following is a good exception handling pattern for resumable media uploads:

except apiclient.errors.HttpError, e:
  if e.resp.status in [404]:
    # Start the upload all over again.
  elif e.resp.status in [500, 502, 503, 504]:
    # Call next_chunk() again, but use an exponential backoff for repeated errors.
  else:
    # Do not retry. Log the error and fail.

Extending MediaUpload

Your application may need to upload a media object that isn't a file. For example, you may create a large image on the fly from a data set. For such cases you can create a subclass of MediaUpload which provides the data to be uploaded. You must fully implement the MediaUpload interface. See the source for the MediaFileUpload, MediaIoBaseUpload, and MediaInMemoryUpload classes as examples.

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Upload Media

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Using Mocks

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/mocks


Using Mocks

<section> <p> The use of <a href= "http://en.wikipedia.org/wiki/Mock_object">Mock objects</a> is a standard testing methodology for Python and other object-oriented languages. This library defines Mock classes that simulate responses to API calls. You can use them to test how your code handles basic interactions with Google APIs. </p> <aside class="note"> <strong>Note:</strong> Many of the <a href= "https://github.com/google/google-api-python-client/tree/master/tests"> Python Client Library test scripts</a> use these classes. </aside> </section>

<section id="h2httpmock"> <h2>HttpMock</h2> <p> This class simulates the response to a single HTTP request. As arguments, the constructor for the <a href= "https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.HttpMock-class.html"> HttpMock</a> object takes a dictionary object representing the response header and the path to a file. When this resource built on this object is executed, it simply returns contents of the file. </p> <h3>Example</h3> <p> This example uses <code>HttpMock</code> to simulate the basic steps necessary to complete an API call to the <a href= "https://developers.google.com/apis-explorer/#p/books/v1/">Google Books API</a>. The first Mock HTTP returns a status code of 200 and a file named <code>books-discovery.json</code>, which is the discovery document that describes the Books API. This file is a necessary part of the building of the service object, which takes place in the next few lines. The actual request is executed using the second Mock object. This returns the contents of <code>books-android.json</code>, the simulated response. </p> <pre class="prettyprint"> from googleapiclient.discovery import build from googleapiclient.http import HttpMock import pprint

http = HttpMock('books-discovery.json', {'status': '200'}) api_key = '<span class="replaceable-credential">your_api_key</span>' service = build('books', 'v1', http=http, developerKey=api_key) request = service.volumes().list(source='public', q='android') http = HttpMock('books-android.json', {'status': '200'}) response = request.execute(http=http) pprint.pprint(response) </pre> <aside class="note"> <strong>Notes:</strong> <ul> <li>To run this sample, it would not be necessary to replace the placeholder <code>your_api_key</code> with an actual key, since the Mock object does not actually call the API. </li> <li>As you develop and test your application, it is a good idea to save actual API responses in files like <code>books-discovery.json</code> or <code>books-android.json</code> for use in testing. </li> <li>Notice that a second <code>HttpMock</code> is created to simulate the second HTTP call. </li> <li>The second use of the <code>execute</code> method demonstrates how you can re-use the request object by calling <code>execute</code> with another Mock object as an argument. (This would also work with an actual HTTP call.) </li> </ul> </aside> </section> <section id="h2httpmocksequence"> <h2>HttpMockSequence</h2> <p> The <a href= "https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.HttpMockSequence-class.html">HttpMockSequence</a> class simulates the sequence of HTTP responses. Each response consists of a header (a dictionary) and a content object (which can be a reference to a file, a JSON-like data structure defined inline, or one of the keywords listed below). When the resource built from this Mock object is executed, it returns the series of responses, one by one. </p> <h3>Special Values for simulated HTTP responses</h3> <p> Instead of a pre-defined object, your code can use one of the following keywords as the content object of a simulated HTTP response. At runtime, the Mock object returns the information described in the table. </p> <table> <tr> <th> Keyword </th> <th> Returns: </th> </tr> <tr> <td> <code>echo_request_headers</code> </td> <td> the complete request headers </td> </tr> <tr> <td> <code>echo_request_headers_as_json</code> </td> <td> the complete request headers as a json object </td> </tr> <tr> <td> <code>echo_request_body</code> </td> <td> the request body </td> </tr> <tr> <td> <code>echo_request_uri</code> </td> <td> the request uri </td> </tr> </table> <h3>Example</h3> <p> The following code snippet combines the two HTTP call simulations from the previous snippet into a single Mock object. The object created using <code>HttpMockSequence</code> simulates the return of the discovery document from the <code>books.volume.list</code> service, then the return of the result of the 'android' query (built in to the <code>request</code> object). You could add code to this snippet to print the contents of <code>response</code>, test that it returned successfully, etc. </p> </section>

from googleapiclient.discovery import build
from googleapiclient.http import HttpMockSequence

books_discovery = # Saved data from a build response
books_android = # Saved data from a request to list android volumes

http = HttpMockSequence([
    ({'status': '200'}, books_discovery),
    ({'status': '200'}, books_android)])
api_key = 'your_api_key'
service = build('books', 'v1',
                http=http,
                developerKey=your_api_key)
request = service.volumes().list(source='public', q='android')
response = request.execute()

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Using Mocks

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue commentgoogleapis/google-api-python-client

DevSite Import: Pagination

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Pagination

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/pagination


Pagination

<p> Some API methods may return very large lists of data. To reduce the response size, many of these API methods support pagination. With paginated results, your application can iteratively request and process large lists one page at a time. For API methods that support it, there exist similarly named methods with a "_next" suffix. For example, if a method is named <code>list()</code>, there may also be a method named <code>list_next()</code>. These methods can be found in the API's PyDoc documentation on the <a href="/api-client-library/python/apis/">Supported APIs page</a>. </p> <p> To process the first page of results, create a request object and call <code>execute()</code> as you normally would. For further pages, you call the corresponding <code><var>method_name</var>_next()</code> method, and pass it the previous request and response. Continue paging until <code><var>method_name</var>_next()</code> returns <code>None</code>. </p> <p> In the following code snippet, the paginated results of a Google Plus activities <code>list()</code> method are processed: </p>

activities = service.activities()
request = activities.list(userId='someUserId', collection='public')

while request is not None:
  activities_doc = request.execute(http=http)

  # Do something with the activities

  request = activities.list_next(request, activities_doc)

Note that you only call execute() on the request once inside the while loop.

closed time in 8 hours

grant

issue closedgoogleapis/google-api-python-client

DevSite Import: Performance Tips

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/performance


Performance Tips

<section> <p> This document covers techniques you can use to improve the performance of your application. The documentation for the specific API you are using should have a similar page with more detail on some of these topics. For example, see the <a href="/drive/performance">Performance Tips page for the Google Drive API</a>. </p> </section>

<section id="gzip"> <h2>About gzip</h2> <p> This client library requests gzip compression for all API responses and unzips the data for you. Although this requires additional CPU time to uncompress the results, the tradeoff with network costs usually makes it worthwhile. </p> </section>

<section id="fields"> <h2>Partial response (fields parameter)</h2> <p> By default, the server sends back the full representation of a resource after processing requests. For better performance, you can ask the server to send only the fields you really need and get a <em>partial response</em> instead. </p> <p> To request a partial response, add the standard <code>fields</code> parameter to any API method. The value of this parameter specifies the fields you want returned. You can use this parameter with any request that returns response data. </p> <p> In the following code snippet, the <code>list</code> method of a fictitious stamps API is called. The <code>cents</code> parameter is defined by the API to only return stamps with the given value. The value of the <code>fields</code> parameter is set to 'count,items/name'. The response will only contain stamps whose value is 5 cents, and the data returned will only include the number of stamps found along with the stamp names: </p> <pre class="prettyprint">response = service.stamps.list(cents=5, fields='count,items/name').execute()</pre> <p> Note how commas are used to delimit the desired fields, and slashes are used to indicate fields that are contained in parent fields. There are other formatting options for the <code>fields</code> parameter, and you should see the "Performance Tips" page in the documentation for the API you are using. </p> </section>

<section id="patch"> <h2>Partial update (patch)</h2> <p> If the API you are calling supports patch, you can avoid sending unnecessary data when modifying resources. For these APIs, you can call the <code>patch()</code> method and supply the arguments you wish to modify for the resource. If supported, the API's PyDoc will have documentation for the <code>patch()</code> method. </p> <p> For more information about patch semantics, see the "Performance Tips" page in the documentation for the API you are using. </p> </section>

<section id="cache"> <h2>Cache</h2> <p> You should turn on caching at the <code>httplib2</code> level. The cache will store <code>ETags</code> associated with a resource and use them during future fetches and updates of the same resource. </p> <p> To enable caching, pass in a cache implementation to the <code>httplib2.Http</code> constructor. In the simplest case, you can just pass in a directory name, and a cache will be built from that directory: </p> <pre class="prettyprint">http = httplib2.Http(cache=".cache")</pre> <p> On App Engine you can use <code>memcache</code> as a cache object: </p> <pre class="prettyprint"> from google.appengine.api import memcache

http = httplib2.Http(cache=memcache)</pre> </section>

<section id="batch"> <h2>Batch</h2> <p> If you are sending many small requests you may benefit from <a href="/api-client-library/python/guide/batch">batching</a>, which allows those requests to be bundled into a single HTTP request. </p> </section>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Performance Tips

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Thread Safety

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/thread_safety


Thread Safety

<section> <p> This page contains important information about the thread safety of this library. </p> </section>

<section> <h2>The httplib2.Http() objects are not thread-safe</h2> <p> The google-api-python-client library is built on top of the <a href="https://github.com/httplib2/httplib2">httplib2</a> library, which is not thread-safe. Therefore, if you are running as a multi-threaded application, each thread that you are making requests from must have its own instance of httplib2.Http(). </p> <p> The easiest way to provide threads with their own <code>httplib2.Http()</code> instances is to either override the construction of it within the service object or to pass an instance via the <code>http</code> argument to method calls. </p> </section>

# Create a new Http() object for every request
  def build_request(http, *args, **kwargs):
    new_http = httplib2.Http()
    return googleapiclient.http.HttpRequest(new_http, *args, **kwargs)
  service = build('api_name', 'api_version', requestBuilder=build_request)

  # Pass in a new Http() manually for every request
  service = build('api_name', 'api_version')
  http = httplib2.Http()
  service.stamps().list().execute(http=http)

<section> <h2>Credential Storage objects are thread-safe</h2> <p> All <a href="https://oauth2client.readthedocs.io/en/latest/source/oauth2client.client.html#oauth2client.client.Storage">Storage</a> objects defined in this library are thread-safe, and multiple processes and threads can operate on a single store. </p> <p> In some cases, this library automatically refreshes expired OAuth 2.0 tokens. When many threads are sharing the same set of credentials, the threads cooperate to minimize the total number of token refresh requests sent to the server. </p> </section>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Thread Safety

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Using Google App Engine

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/auth/api-keys


Using Google App Engine

<section> <p> The Google APIs Client Library for Python has special support for <a href="/appengine">Google App Engine</a> applications. In particular, there are decorators and classes that simplify the OAuth 2.0 protocol steps. Before reading this page, you should be familiar with the content on this library's <a href="/api-client-library/python/guide/aaa_oauth">OAuth 2.0</a> page. </p> </section>

<section id="Installation"> <h2>Installation</h2> <p>For information on installing the source for the library into your App Engine project, see the <a href="/api-client-library/python/start/installation#appengine">App Engine specific installation instructions</a>. </p> </section>

<section id="Decorators"> <h2>Decorators</h2> <p> The easiest way to handle OAuth 2.0 is to use the App Engine <a href="http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Decorators">Python decorators</a> supplied by this library. These decorators handle all of the OAuth 2.0 steps without you having to use any <code>Flow</code>, <code>Credentials</code>, or <code>Storage</code> objects. </p> <p> There are two decorator classes to choose from: </p> <ul> <li> <strong>OAuth2Decorator</strong>: Use the <a href="https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.appengine.html#oauth2client.contrib.appengine.OAuth2Decorator">OAuth2Decorator</a> class to contruct a decorator with your client ID and secret. </li> <li> <strong>OAuth2DecoratorFromClientSecrets</strong>: Use the <a href="https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.appengine.html#oauth2client.contrib.appengine.OAuth2DecoratorFromClientSecrets">OAuth2DecoratorFromClientSecrets</a> class to contruct a decorator using a <code>client_secrets.json</code> file described in the <a href="/api-client-library/python/guide/aaa_oauth#flow_from_clientsecrets">flow_from_clientsecrets()</a> section of the OAuth 2.0 page. </li> </ul> <p> There are also two decorator types to choose from: </p> <ul> <li> <strong>oauth_required</strong>: Any method decorated with <code>oauth_required</code> completes all OAuth 2.0 steps before entering the function. Within the body of the function, you can use the decorator's <code>http()</code> function to get an <code>Http</code> object that has already been authorized. </li> <li> <strong>oauth_aware</strong>: This decorator type requires a little more code than <code>oauth_required</code>, but it is preferred because it gives you control over the user experience. For example, you can display a page explaining why the user is being redirected to an authorization server. This decorator does not perform any OAuth 2.0 steps, but within the body of the decorated function you can call these convenient decorator functions: <ul> <li> <strong>has_credentials()</strong>: Returns <code>True</code> if there are valid access credentials for the logged in user. </li> <li> <strong>authorize_url()</strong>: Returns the first URL that starts the OAuth 2.0 steps. </li> </ul> </li> </ul> <p> When using these decorators, you need to add a specific URL handler to your application to handle the redirection from the authorization server back to your application. This handler takes care of the final OAuth 2.0 steps required to finish authorization, and it redirects the user back to the original path where your application first detected that authorization was needed. </p> </section>

def main():
  application = webapp.WSGIApplication(
      [
        ('/', MainHandler),
        ('/about', AboutHandler),
        <strong>(decorator.callback_path, decorator.callback_handler()),</strong>
      ],
      debug=True)
  run_wsgi_app(application)

<p> In the following code snippet, the <code>OAuth2Decorator</code> class is used to create an <code>oauth_required</code> decorator, and the decorator is applied to a function that accesses the <a href="/google-apps/calendar/">Google Calendar API</a>: </p>

from googleapiclient.discovery import build
from google.appengine.ext import webapp
from oauth2client.contrib.appengine import OAuth2Decorator

decorator = OAuth2Decorator(
  client_id='<em>your_client_id</em>',
  client_secret='<em>your_client_secret</em>',
  scope='https://www.googleapis.com/auth/calendar')

service = build('calendar', 'v3')

class MainHandler(webapp.RequestHandler):

  @decorator.oauth_required
  def get(self):
    # Get the authorized Http object created by the decorator.
    http = decorator.http()
    # Call the service using the authorized Http object.
    request = service.events().list(calendarId='primary')
    response = request.execute(http=http)
    ... 

<p> In the following code snippet, the <code>OAuth2DecoratorFromClientSecrets</code> class is used to create an <code>oauth_aware</code> decorator, and the decorator is applied to a function that accesses the <a href="/google-apps/tasks/">Google Tasks API</a>: </p>

import os
from googleapiclient.discovery import build
from google.appengine.ext import webapp
from oauth2client.contrib.appengine import OAuth2DecoratorFromClientSecrets

decorator = OAuth2DecoratorFromClientSecrets(
  os.path.join(os.path.dirname(__file__), 'client_secrets.json'),
  'https://www.googleapis.com/auth/tasks.readonly')

service = build('tasks', 'v1')

class MainHandler(webapp.RequestHandler):

  @decorator.oauth_aware
  def get(self):
    if decorator.has_credentials():
      response = service.tasks().list(tasklist='@default').execute(decorator.http())
      # Write the task data
      ...
    else:
      url = decorator.authorize_url()
      # Write a page explaining why authorization is needed,
      # and provide the user with a link to the url to proceed.
      # When the user authorizes, they get redirected back to this path,
      # and has_credentials() returns True.
      ...

<section id="ServiceAccounts"> <h2>Service Accounts</h2> <p> If your App Engine application needs to call an API to access data owned by the application's project, you can simplify OAuth 2.0 by using <a href="/accounts/docs/OAuth2ServiceAccount">Service Accounts</a>. These server-to-server interactions do not involve a user, and only your application needs to authenticate itself. Use the <a href="https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.appengine.html#oauth2client.contrib.appengine.AppAssertionCredentials">AppAssertionCredentials</a> class to create a <code>Credentials</code> object without using a <code>Flow</code> object. </p> <p> In the following code snippet, a <code>Credentials</code> object is created and an <code>Http</code> object is authorized: </p> <pre class="prettyprint"> import httplib2 from google.appengine.api import memcache from oauth2client.contrib.appengine import AppAssertionCredentials ... credentials = AppAssertionCredentials(scope='https://www.googleapis.com/auth/devstorage.read_write') http = credentials.authorize(httplib2.Http(memcache))</pre> <p> Once you have an authorized <code>Http</code> object, you can pass it to the <a href="https://google.github.io/google-api-python-client/docs/epy/googleapiclient.discovery-module.html#build">build()</a> or <a href="https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.HttpRequest-class.html#execute">execute()</a> functions as you normally would. </p> </section>

<section id="Flows"> <h2>Flows</h2> <p> Use App Engine's <a href="/appengine/docs/python/memcache/usingmemcache">Memcache</a> to store <code>Flow</code> objects. When your application is simultaneously going through OAuth 2.0 steps for many users, it's normally best to store per-user <code>Flow</code> objects before the first redirection. This way, your redirection handlers can retrieve the <code>Flow</code> object already created for the user. In the following code snippet, <code>Memcache</code> is used to store and retrieve <code>Flow</code> objects keyed by user ID: </p> </section>

import pickle
from google.appengine.api import memcache
from google.appengine.api import users
from oauth2client.client import OAuth2WebServerFlow
...
flow = OAuth2WebServerFlow(...)
user = users.get_current_user()
memcache.set(user.user_id(), pickle.dumps(flow))
...
flow = pickle.loads(memcache.get(user.user_id()))

<section id="Credentials"> <h2>Credentials</h2> <p> Use the <a href="https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.appengine.html#oauth2client.contrib.appengine.CredentialsProperty">oauth2client.contrib.appengine.CredentialsProperty</a> class as an <a href="/appengine/docs/python/datastore/overview">App Engine Datastore</a> <code>Property</code>. Creating a <code>Model</code> with this <code>Property</code> simplifies storing <code>Credentials</code> as explained in the <a href="#Storage">Storage</a> section below. In the following code snippet, a <code>Model</code> class is defined using this <code>Property</code>. </p> </section>

from google.appengine.ext import db
from oauth2client.contrib.appengine import CredentialsProperty
...
class CredentialsModel(db.Model):
  credentials = CredentialsProperty()</pre>

<section id="Storage"> <h2>Storage</h2> <p> Use the <a href="https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.appengine.html#oauth2client.contrib.appengine.StorageByKeyName">oauth2client.contrib.appengine.StorageByKeyName</a> class to store and retrieve <code>Credentials</code> objects to and from the <a href="/appengine/docs/python/datastore/overview">App Engine Datastore</a>. You pass the model, key value, and property name to its constructor. The following shows how to create, read, and write <code>Credentials</code> objects using the example <code>CredentialsModel</code> class above: </section>

from google.appengine.api import users
from oauth2client.contrib.appengine import StorageByKeyName
...
user = users.get_current_user()
storage = StorageByKeyName(CredentialsModel, user.user_id(), 'credentials')
credentials = storage.get()
...
storage.put(credentials)

<section id="Samples"> <h2>Samples</h2> <p> To see how these classes work together in a full application, see the <a href="https://github.com/google/google-api-python-client/tree/master/samples/appengine">App Engine sample applications</a> section of this library’s open source project page. </p> </section>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Using Google App Engine

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Using Django

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/django


Using Django

<section> <p> The Google APIs Client Library for Python has special support for the <a href="https://www.djangoproject.com/">Django</a> web framework. In particular, there are classes that simplify the OAuth 2.0 protocol steps. This document describes the Django-specific classes available for working with <a href="/api-client-library/python/guide/aaa_oauth#flows">Flow</a>, <a href="/api-client-library/python/guide/aaa_oauth#credentials">Credentials</a>, and <a href="/api-client-library/python/guide/aaa_oauth#storage">Storage</a> objects. </p> </section>

<section id="Flows"> <h2>Flows</h2> <p> Use the <a href="https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.django_orm.html#oauth2client.contrib.django_orm.FlowField">oauth2client.contrib.django_orm.FlowField</a> class as a Django model field so that <code>Flow</code> objects can easily be stored. When your application is simultaneously going through OAuth 2.0 steps for many users, it's normally best to store per-user <code>Flow</code> objects before the first redirection. This way, your redirection handlers can retrieve the <code>Flow</code> object already created for the user. In the following code, a model is defined that allows <code>Flow</code> objects to be stored and keyed by <code>User</code>: </p> <pre class="prettyprint"> from django.contrib.auth.models import User from django.db import models from oauth2client.contrib.django_orm import FlowField ... class FlowModel(models.Model): id = models.ForeignKey(User, primary_key=True) flow = FlowField()</pre> </section>

<section id="Credentials"> <h2>Credentials</h2> <p> Use the <a href="https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.django_orm.html#oauth2client.contrib.django_orm.CredentialsField">oauth2client.contrib.django_orm.CredentialsField</a> class as a Django model field so that <code>Credentials</code> objects can easily be stored. Similar to <code>Flow</code> objects, it's normally best to store per-user <code>Credentials</code> objects. In the following code, a model is defined that allows <code>Credentials</code> objects to be stored and keyed by <code>User</code>: </p> <pre class="prettyprint"> from django.contrib.auth.models import User from django.db import models from oauth2client.contrib.django_orm import CredentialsField ... class CredentialsModel(models.Model): id = models.ForeignKey(User, primary_key=True) credential = CredentialsField()</pre> </section>

<section id="Storage"> <h2>Storage</h2> <p> Use the <a href="https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.django_orm.html#oauth2client.contrib.django_orm.Storage">oauth2client.contrib.django_orm.Storage</a> class to store and retrieve <code>Credentials</code> objects using a model defined with a <code>CredentialsField</code> object. You pass the model, field name for the model key, value for the model key, and field name to the <code>CredentialsField</code> constructor. The following shows how to create, read, and write <code>Credentials</code> objects using the example <code>CredentialsModel</code> class above: </p> <pre class="prettyprint"> from django.contrib.auth.models import User from oauth2client.contrib.django_orm import Storage from your_project.your_app.models import CredentialsModel ... user = # A User object usually obtained from request. storage = Storage(CredentialsModel, 'id', user, 'credential') credential = storage.get() ... storage.put(credential)</pre> </section>

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Using Django

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

issue closedgoogleapis/google-api-python-client

DevSite Import: Batch

Notice: This DevSite page will soon be deleted per b/133171590. Please add this sample to GitHub if it is relevant still:

https://developers.google.com/api-client-library/python/guide/batch


Batch

<section> <p> Each HTTP connection that your application makes results in a certain amount of overhead. This library supports batching, to allow your application to put several API calls into a single HTTP request. Examples of situations when you might want to use batching: </p> <ul> <li> You have many small requests to make and would like to minimize HTTP request overhead. </li> <li> A user made changes to data while your application was offline, so your application needs to synchronize its local data with the server by sending a lot of updates and deletes. </li> </ul> <p class="note"> <strong>Note</strong>: You're limited to 1000 calls in a single batch request. If you need to make more calls than that, use multiple batch requests. </p> <p class="note"> <strong>Note</strong>: You cannot use a <a href="/api-client-library/python/guide/media_upload">media upload</a> object in a batch request. </p> </section>

<section> <h2>Details</h2> <p> You create batch requests by calling <code>new_batch_http_request()</code> on your service object, which returns a <a href="https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.BatchHttpRequest-class.html">BatchHttpRequest</a> object, and then calling <code>add()</code> for each request you want to execute. You may pass in a callback with each request that is called with the response to that request. The callback function arguments are: a unique request identifier for each API call, a response object which contains the API call response, and an exception object which may be set to an exception raised by the API call. After you've added the requests, you call <code>execute()</code> to make the requests. The <code>execute()</code> function blocks until all callbacks have been called. </p> <p> In the following code snippet, two API requests are batched to a single HTTP request, and each API request is supplied a callback: </p> <pre class="prettyprint"> See below</pre> <p> You can also supply a single callback that gets called for each response: </p> <pre class="prettyprint">See below</pre> <p> The <a href="https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.BatchHttpRequest-class.html#add">add()</a> method also allows you to supply a <code>request_id</code> parameter for each request. These IDs are provided to the callbacks. If you don't supply one, the library creates one for you. The IDs must be unique for each API request, otherwise <code>add()</code> raises an exception. </p> <p> If you supply a callback to both <code>new_batch_http_request()</code> and <code>add()</code>, they both get called. </p> </section>


def list_animals(request_id, response, exception):
  if exception is not None:
    # Do something with the exception
    pass
  else:
    # Do something with the response
    pass

def list_farmers(request_id, response):
  """Do something with the farmers list response."""
  pass

service = build('farm', 'v2')

batch = service.new_batch_http_request()

batch.add(service.animals().list(), callback=list_animals)
batch.add(service.farmers().list(), callback=list_farmers)
batch.execute(http=http)

def insert_animal(request_id, response, exception):
  if exception is not None:
    # Do something with the exception
    pass
  else:
    # Do something with the response
    pass

service = build('farm', 'v2')

batch = service.new_batch_http_request(callback=insert_animal)

batch.add(service.animals().insert(name="sheep"))
batch.add(service.animals().insert(name="pig"))
batch.add(service.animals().insert(name="llama"))
batch.execute(http=http)

closed time in 8 hours

grant

issue commentgoogleapis/google-api-python-client

DevSite Import: Batch

The docs are now added to the docs/ folder. Fixed with #706.

grant

comment created time in 8 hours

PR opened googleapis/google-api-python-client

docs: Adds docs folder

docs: Adds docs folder

This PR adds all guides that used to live on https://developers.google.com/api-client-library/python/ to this repo. The content is not changed besides change the HTML into md. Note: Some of content may be out of date since most of it was authored in 2015.

Details

  • Moves the API guides from the old site to this repo.
  • Formats all docs in markdown (instead of HTML) for easy manipulation
  • All docs are now open source, meaning anybody can comment and fix them!
  • Adds a link to the homepage to the docs folder.
  • Adds a docs/README.md navigation homepage.

See #669 #670 #671 #672 #673 #674 #675 #676 #677 #678 #679 #680 #681 #682 #683 #684 #685 #686 #687 #688 #689 #690 #693.

+1690 -8

0 comment

18 changed files

pr created time in a day

create barnchgrant/google-api-python-client

branch : grant_docs

created branch time in a day

delete branch grant/schemastore

delete branch : grant_appsscript_defaults

delete time in a day

PR opened SchemaStore/schemastore

appsscript.json Add more properties

Adds more add-on properties for autocompletion.

+173 -0

0 comment

1 changed file

pr created time in a day

push eventgrant/schemastore

Grant Timmerman

commit sha cc82541da1688f2bfad033883a26ba4dd8ea58e1

feat: Add more appsscript.json properties

view details

push time in a day

push eventgrant/schemastore

Grant Timmerman

commit sha 82926a1152b1658161f445420aa5d3a75028fbe6

appsscript.json: Add defaults and misc fixes (#660) * Add .clasp.json schema. Fix appsscript.json schema title * Fix libraries array * For appsscript.json, add dataStudio * Improve defaults for appsscript.json. Misc improvements * Add defaults and misc fixes to appsscript.json

view details

Ryan Cavanaugh

commit sha a5475fe8cfd4df521cb6f5f3419cc7cdeee890b4

Add `incremental` option (#661)

view details

Arne Peirs

commit sha ec73ed001b25523d1f984f6bd490cfca6660f437

Update CKAN schema to v1.26 (#662) * Update CKAN.schema * Rename file

view details

Benjamin Vincent

commit sha d45c55a5ece707ad0008df1228ff8e838a31d044

adding: tsBuildInfoFile included in TypeScript 3.4 (#663) { "issue": { "asPer": [ "https://devblogs.microsoft.com/typescript/announcing-typescript-3-4/", "https://www.typescriptlang.org/docs/handbook/compiler-options.html" ], "option": "--tsBuildInfoFile", "type": "string", "default": ".tsbuildinfo", "description": "Specify what file to store incremental build information in." }, "problems": [ { "description": "for the moment receiving this error message:", "when": "using : tsc -d --tsBuildInfoFile './build/lib/.tsbuildinfo'", "message": "error TS6064: Option 'tsBuildInfoFile' can only be specified in 'tsconfig.json' file." }, { "description": "and then this error message if in tsconfig.json:", "when": "unsing : '\"tsBuildInfoFile\": \"./build/lib/.tsbuildinfo\",' ", "message": "'Option de compilateur 'tsBuildInfoFile' inconnue.' (unknown option)" } ], "more": [ " By default with these settings, when we run tsc, TypeScript will look for a file called .tsbuildinfo in the output directory (./lib). If ./lib/.tsbuildinfo doesn’t exist, it’ll be generated. But if it does, tsc will try to use that file to incrementally type-check and update our output files.", " These .tsbuildinfo files can be safely deleted and don’t have any impact on our code at runtime – they’re purely used to make compilations faster. We can also name them anything that we want, and place them anywhere we want using the --tsBuildInfoFile flag.", { "where": "front-end.tsconfig.json", "compilerOptions": { "incremental": true, "tsBuildInfoFile": "./buildcache/front-end", "outDir": "./lib" }, "include": ["./src"] } ] }

view details

Brett Samblanet

commit sha ab10f81d1b6435746a1454a5352625b86eab96bb

updating eventhub sections in host.json schema (#665)

view details

Vlad Volkov

commit sha d79eb08162e81b8145b9149dc5ab3b4d893e3216

Updated with 2.6 and 2.7 ansible schemas (#666)

view details

Benjamin Vincent

commit sha ce7a2b904f326ba95cd6f0ae091e8ac57d0eed4c

fixing (#572) "licenses" property in package.json is deprecated (#667) * "licenses" property deprecated #572 [fixing #572: "licenses" property in package.json is deprecated](https://github.com/SchemaStore/schemastore/issues/572) * preferGlobal is also deprecated **DEPRECATED** [preferGlobal](https://docs.npmjs.com/files/package.json#preferglobal) This option used to trigger an npm warning, but it will no longer warn. It is purely there for informational purposes. It is now recommended that you install any binaries as local devDependencies wherever possible.

view details

Mads Kristensen

commit sha 458a9080685633f09ed66c1348da8d535e19017d

Added .vsconfig schema

view details

Sergio Schvezov

commit sha e56a38b2197172851ae0754f86a130cfc5169056

Add snapcraft to the catalog (#668) Signed-off-by: Sergio Schvezov <sergio.schvezov@ubuntu.com>

view details

Jeremiah Small

commit sha 90becc64189d41456c435a67fdd3a93a0e347aad

Add Carafe to catalog.json (#669)

view details

Varun Puranik

commit sha 29d5d6e126cc20fd4eaf42e4dba4a749093e1dec

Allow environment variable value to be number, string or boolean (#670)

view details

Lucas Azzola

commit sha c92d2d43e9da74db71c171f8fb64977383e74c8a

Allow prettierrc to be a string (#671)

view details

Aaron Meyers

commit sha af144ac902687e55f38f8669386ba836601c83eb

lsdlschema-1.0 (#672)

view details

Fedor Korotkov

commit sha 7ef855eff585535ceee10f709640022922ff6cc5

Update Cirrus CI Schema (#674) * Update Cirrus CI Schema Regular update of the schema. It was generated from the internal parser. * Add more GCP zones

view details

Søren Louv-Jansen

commit sha 43578cbd7cfd26ef992dc356e8c0e2b9f2dd3818

Add schema for .backportrc.json configuration (#675) * Update catalog.json * Create backportrc.json * Update catalog.json * Fixed required props

view details

mellison

commit sha 5e59df49b65a315ead50ea9a99fb78af66117b83

added groups node to tslint configuration (#676)

view details

Charlie Jonas

commit sha 0cb6d67f30b56324586c8baf06474c89cab1e2e0

Add tsforceconfig schema (#677) * added schema for ts-force-config (npm@ts-force-gen) * removed reference to @schema in test

view details

Bernardo Kuri

commit sha 37e5cbc881898efdffb9ab06f8e7efdb41bce18b

add missing rules and default levels; misc fixes (#679)

view details

Renlong Tu

commit sha 0055cf2b07a2f7a81a37e64d6145c4a5f895ed3b

Update iot edge deployment (template) json schema to 1.1 (#682) * Update iot edge (deployment) template to 1.1 * Update catalog.json

view details

James Strachan

commit sha 732d37c29068d59b3640de2d0c33f75634e2e93d

fix: add Jenkins X Schema (#683) for background see: https://jenkins-x.io/architecture/jenkins-x-pipelines/#editing-in-vs-code

view details

push time in a day

push eventgrant/google-api-python-client

Grant Timmerman

commit sha df70cca186e0cfd369f7fd2d6a2774194f596c25

Delete Credentials.png (#541) This png is not used and is outdated.

view details

Chaz Reid

commit sha e8e6c73ff1fd70e2fdf0c25321ce80719eb5ac89

Update groupsettings.py (#504) Update groupsettings sample to use non-deprecated oauth2client API.

view details

Chris McDonough

commit sha c7533a0ad2c90ab9c0974aa8869625b5993140d4

Better docs links in readme (#544) take suggestion by @charlesreid1 about better places to point to docs

view details

Chris McDonough

commit sha bbaad28fa716ef73c8c67c8d04c95b679144fbc9

prevent stray imports of older 'apiclient' alias from raising an ImportError Prevent stray imports of older 'apiclient' alias from raising an ImportError if oauth2client is not installed, unless sample_tools.init is actually called. Closes #524

view details

Chris McDonough

commit sha 3cf5e60dac0553f2db5529dae8af2c5b537c8155

Under Python 3; fix bug that caused invalid Content-ID header when custom request_id supplied (#545) Fixes bug under Python 3 caused by incorrect RFC2822 Content-ID header folding (see #164, #536) Allows custom request ids to contain the '+' character also. Closes #164 Closes #536

view details

Chris McDonough

commit sha 0dc81bf4d772f09223dba4a349ebb9003479ea7c

Respect custom headers set on the request supplied to MediaIoBaseDownload within each call to next_chunk (#546) Closes #207

view details

Chris McDonough

commit sha 781de4c8dd700a4a2cc820b2cdbf5ba31241bd6b

add copyright header, closes #216 (#550)

view details

Bu Sun Kim

commit sha 3d177a82309ec0a2731821f9e320452bd129a12a

Use kokoro for testing (#580) * Use kokoro for testing * Remove coveralls

view details

Justin Beckwith

commit sha cf1ad3eeb444847229e9d4a8f9c949c0b10d469a

Update github issue templates (#584)

view details

Bu Sun Kim

commit sha 61cd9257ea53fc934768b6c806d6127ef8557de4

Run tests with Python 3.7 (#590) * Run tests with Python 3.7 * Update setup.py * Remove travis

view details

Bu Sun Kim

commit sha 1b010a3aefd48bba4a782763c82277251a3887d9

Remove django sample (#591)

view details

Arunpn

commit sha 9d779cc2497e12cf23695b57b45d35bdf1ae9d91

Fix the client to respect the passed in developerKey and credentials (#593) * Fix googleapiclient to respect the passed in developerKey and credentials * Fix tests to consider developerKey and credentials

view details

Bu Sun Kim

commit sha fef743a41e8f0e533469d621567f322a5f8465be

Release v1.7.5 (#594)

view details

Xinan Lin

commit sha e2dccec0c3087809ff3a045b2d1032f655a59004

Add client-side limit for batch requests (#585)

view details

Bu Sun Kim

commit sha b27435570ba195ae664d2f168eee8dd7bf8b9b7a

Release v1.7.6 (#599)

view details

Sean O'Keefe

commit sha 912a812d6f46092f748334f1f045eba9419c4c8e

Adding example for searchAppearance (#414)

view details

smstone

commit sha a04b3c52e61712b31f7a480af01a1b636d8b3cb9

Typo in http.py exception message. (#602)

view details

Bu Sun Kim

commit sha eb4b3e0bc889088cffa474f5c16537e2c6411b74

Change xrange to range (#601)

view details

Corey Schaf

commit sha b1b16fd0c1aa90a3110beaaba90f13d55544293d

Updates documentation for stopping channel subscriptions (#598)

view details

Sander Brauwers

commit sha 729d9ae542bfc78cd9e6202246f1e2d5f4dd6f22

Add badges (#455)

view details

push time in a day

push eventgoogle/clasp

Grant Timmerman

commit sha d2ebcac952bd7c9c877307e6fa5d25e9fd2b5b71

Update typescript.md

view details

push time in 2 days

delete branch GoogleCloudPlatform/nodejs-docs-samples

delete branch : mas

delete time in 2 days

create barnchGoogleCloudPlatform/nodejs-docs-samples

branch : mas

created branch time in 2 days

PR opened DefinitelyTyped/DefinitelyTyped

[@types/gapi] Update Docs with updated Google API Client webpage/owner

[@types/gapi] Update Docs with updated Google API Client webpage/owner

This change removes the link Google Code (a deprecated project) and adds grant as a maintainer of the types (currently maintainer of the client).

https://github.com/google/google-api-javascript-client


  • [x] Use a meaningful title for the pull request. Include the name of the package modified.
  • [x] Test the change in your own code. (Compile and run.)

If changing an existing definition:

  • [x] Provide a URL to documentation or source code which provides context for the suggested changes: https://github.com/google/google-api-javascript-client
  • [x] Increase the version number in the header if appropriate.
  • [x] If you are making substantial changes, consider adding a tslint.json containing { "extends": "dtslint/dt.json" }.
+3 -3

0 comment

1 changed file

pr created time in 2 days

push eventgrant/DefinitelyTyped

Grant Timmerman

commit sha 29b1aaa0da80fd0631942118394ec2f3e943837b

[@types/gapi] Update Docs with updated Google API Client webpage/owner

view details

push time in 2 days

push eventgoogle/google-api-javascript-client

Grant Timmerman

commit sha daeac6b8de38b7a407d577cd0a6550d67ceed69a

docs: Mention TypeScript types

view details

push time in 2 days

pull request commentGoogleCloudPlatform/nodejs-docs-samples

[WIP] Remove emulator + shims from testing samples

Are those two samples ones that we really should support in the long-term? I've looked into them a little bit, and they may be samples that are better for a community repo. Perhaps we should cut-off testing with the emulator with them.

ace-n

comment created time in 2 days

delete branch GoogleCloudPlatform/functions-framework-nodejs

delete branch : grant-docs

delete time in 2 days

push eventGoogleCloudPlatform/functions-framework-nodejs

Grant Timmerman

commit sha c24fd7095563a5b19826c645344890b3def058ca

Create docs/ README.md (#46) * Create README.md * docs: Add TODOs

view details

push time in 2 days

PR merged GoogleCloudPlatform/functions-framework-nodejs

Create docs/ README.md cla: yes

Empty for now.

See https://github.com/GoogleCloudPlatform/functions-framework-nodejs/pull/40#issuecomment-502903362.

+11 -0

0 comment

2 changed files

grant

pr closed time in 2 days

delete branch GoogleCloudPlatform/functions-framework-nodejs

delete branch : grant-docs-folder

delete time in 2 days

push eventGoogleCloudPlatform/functions-framework-nodejs

Grant Timmerman

commit sha 00919bcca0e094eb8722f776213462ce48aebf8e

docs: Add TODOs

view details

push time in 2 days

PR closed GoogleCloudPlatform/functions-framework-nodejs

Create `docs/` folder/README.md cla: yes

Create a docs/ folder/README for guides that shouldn't clutter up the main README of this repo.

+5 -0

0 comment

1 changed file

grant

pr closed time in 2 days

issue commentgoogle/google-api-dotnet-client-samples

THe Readme should to be converted...

FYI @jskeet @google/yoshi-dotnet.

StingyJack

comment created time in 2 days

pull request commentGoogleCloudPlatform/functions-framework-nodejs

Inline Dockerfile and gcloud commands.

@stew-r Up to you. I think critical docs should be part of the repo, like how to configure a Dockerfile to use this module, should be in this repo rather than our community docs.

For example in @google/clasp, the docs/ folder is useful for advanced features not meant in the README and is maintained by the community. https://github.com/google/clasp/tree/master/docs

josephburnett

comment created time in 2 days

create barnchGoogleCloudPlatform/functions-framework-nodejs

branch : grant-docs

created branch time in 2 days

pull request commentGoogleCloudPlatform/functions-framework-nodejs

Inline Dockerfile and gcloud commands.

@AndreiIgna Please link or re-open the issues if you think we should add them in docs.

josephburnett

comment created time in 2 days

delete branch GoogleCloudPlatform/nodejs-docs-samples

delete branch : grant-patch-1

delete time in 5 days

push eventGoogleCloudPlatform/nodejs-docs-samples

Grant Timmerman

commit sha bda5a4dfbef146143dd1e486afe3b6966524cf99

fix: Make functions_http_method consistent with other samples (#1376)

view details

push time in 5 days

PR merged GoogleCloudPlatform/nodejs-docs-samples

fix: Make functions_http_method consistent with other samples cla: yes

Inline function handlers like in Go and Python. It looks weird (and is unnecessary) having standalone functions.

See: https://cloud.google.com/functions/docs/writing/http#handling_http_methods

+2 -12

0 comment

1 changed file

grant

pr closed time in 5 days

Pull request review commentGoogleCloudPlatform/nodejs-docs-samples

functions/datastore Node 8 upgrade

 const VALUE = { const errorMsg = msg =>   `${msg} not provided. Make sure you have a "${msg.toLowerCase()}" property in your request`; -it('set: Fails without a value', () => {-  const req = {-    body: {},-  };-  assert.throws(() => {-    program.set(req, null);-  }, errorMsg('Value!'));-});+const handleLinuxFailures = async proc => {+  try {+    // Terminate the FF if it hasn't timed out+    // WARNING: mangles returned stdout/stderr values+    return await proc;+  } catch (err) {+    // Timeouts always cause errors on Linux, so catch them+    if (!err.name || err.name !== 'ChildProcessError') {+      throw err;+    } else {+      return proc;+    }+  }+}; -it('set: Fails without a key', () => {-  const req = {-    body: {-      value: VALUE,-    },-  };-  assert.throws(() => {-    program.set(req, null);-  }, errorMsg('Key!'));-});+describe('functions/datastore', () => {+  describe('set', () => {+    let ffProc; -it('set: Fails without a kind', () => {-  const req = {-    body: {-      key: NAME,-      value: VALUE,-    },-  };-  assert.throws(-    () => {-      program.set(req, null);-    },-    Error,-    errorMsg('Kind')-  );-});+    before(() => {+      ffProc = execPromise(+        `functions-framework --target=set --signature-type=http`,+        {timeout: FF_TIMEOUT, shell: true, cwd}+      );+    });++    after(async () => {+      await handleLinuxFailures(ffProc);+    });++    it('set: Fails without a value', async () => {+      const req = {+        body: {},+      };++      const res = {+        status: sinon.stub().returnsThis(),+        send: sinon.stub(),+      };++      await program.set(req, res);++      assert.ok(res.status.calledWith(500));+      assert.ok(res.send.calledWith(errorMsg('Value')));+    });++    it('set: Fails without a key', async () => {+      const req = {+        body: {+          value: VALUE,+        },+      };++      const res = {+        status: sinon.stub().returnsThis(),+        send: sinon.stub(),+      }; -// TODO: @ace-n figure out why these tests started failing-it.skip('set: Saves an entity', async () => {-  await request-    .post('/set')-    .send({-      kind: KIND,-      key: NAME,-      value: VALUE,-    })-    .expect(200)-    .expect(response => {-      assert.strictEqual(-        response.text.includes(`Entity ${KIND}/${NAME} saved`),-        true+      await program.set(req, res);++      assert.ok(res.status.calledWith(500));+      assert.ok(res.send.calledWith(errorMsg('Key')));+    });++    it('set: Fails without a kind', async () => {+      const req = {+        body: {+          key: NAME,+          value: VALUE,+        },+      };++      const res = {+        status: sinon.stub().returnsThis(),+        send: sinon.stub(),+      };++      await program.set(req, res);++      assert.ok(res.status.calledWith(500));+      assert.ok(res.send.calledWith(errorMsg('Kind')));+    });++    it('set: Saves an entity', async () => {+      const response = await requestRetry({+        url: `${BASE_URL}/set`,+        method: 'POST',+        body: {+          kind: KIND,+          key: NAME,+          value: VALUE,+        },+        json: true,+      });++      assert.strictEqual(response.statusCode, 200);+      assert.ok(response.body.includes(`Entity ${KIND}/${NAME} saved`));+    });+  });++  describe('get', () => {+    let ffProc;++    before(() => {+      ffProc = execPromise(+        `functions-framework --target=get --signature-type=http`,+        {timeout: FF_TIMEOUT, shell: true, cwd}       );     });-}); -it('get: Fails without a key', () => {-  const req = {-    body: {},-  };-  assert.throws(-    () => {-      program.get(req, null);-    },-    Error,-    errorMsg('Key')-  );-});+    after(async () => {+      await handleLinuxFailures(ffProc);+    }); -it('get: Fails without a kind', () => {-  const req = {-    body: {-      key: NAME,-    },-  };-  assert.throws(-    () => {-      program.get(req, null);-    },-    Error,-    errorMsg('Kind')-  );-});+    it('get: Fails when entity does not exist', async () => {+      const response = await requestRetry({+        url: `${BASE_URL}/get`,+        method: 'POST',+        body: {+          kind: KIND,+          key: 'nonexistent',+        },+        json: true,+      }); -it('get: Fails when entity does not exist', async () => {-  await request-    .post('/get')-    .send({-      kind: KIND,-      key: 'nonexistent',-    })-    .expect(500)-    .expect(response => {-      assert.strictEqual(+      assert.strictEqual(response.statusCode, 500);+      assert.ok(         new RegExp(           /(Missing or insufficient permissions.)|(No entity found for key)/-        ).test(response.text),-        true+        ).test(response.body)       );     });-}); -// TODO: ace-n Figure out why this test started failing, remove skip-it.skip('get: Finds an entity', async () => {-  await request-    .post('/get')-    .send({-      kind: KIND,-      key: NAME,-    })-    .expect(200)-    .expect(response => {-      assert.deepStrictEqual(JSON.parse(response.text), {+    it('get: Finds an entity', async () => {+      const response = await requestRetry({+        method: 'POST',+        url: `${BASE_URL}/get`,+        body: {+          kind: KIND,+          key: NAME,+        },+        json: true,+      });++      assert.strictEqual(response.statusCode, 200);+      assert.deepStrictEqual(response.body, {         description: 'Buy milk',       });     });-}); -it('del: Fails without a key', () => {-  const req = {-    body: {},-  };-  assert.throws(-    () => {-      program.del(req, null);-    },-    Error,-    errorMsg('Kind')-  );-});+    it('get: Fails without a key', async () => {+      const req = {+        body: {},+      }; -it('del: Fails without a kind', () => {-  const req = {-    body: {-      key: NAME,-    },-  };-  assert.throws(-    () => {-      program.del(req, null);-    },-    Error,-    errorMsg('Kind')-  );-});+      const res = {+        status: sinon.stub().returnsThis(),+        send: sinon.stub(),+      };++      await program.get(req, res); -// TODO: ace-n Figure out why this test started failing-it.skip(`del: Doesn't fail when entity does not exist`, async () => {-  await request-    .post('/del')-    .send({-      kind: KIND,-      key: 'nonexistent',-    })-    .expect(200)-    .expect(response => {-      assert.strictEqual(response.text, `Entity ${KIND}/nonexistent deleted.`);+      assert.ok(res.status.calledWith(500));+      assert.ok(res.send.calledWith(errorMsg('Key')));     });-}); -// TODO: ace-n Figure out why this test started failing-it.skip('del: Deletes an entity', async () => {-  await request-    .post(`/del`)-    .send({-      kind: KIND,-      key: NAME,-    })-    .expect(200)-    .expect(response => {-      assert.strictEqual(response.text, `Entity ${KIND}/${NAME} deleted.`);-    });--  const key = datastore.key([KIND, NAME]);-  const [entity] = await datastore.get(key);-  assert.ok(!entity);+    it('get: Fails without a kind', async () => {+      const req = {+        body: {+          key: NAME,+        },+      };++      const res = {+        status: sinon.stub().returnsThis(),+        send: sinon.stub(),+      };++      await program.get(req, res);++      assert.ok(res.status.calledWith(500));+      assert.ok(res.send.calledWith(errorMsg('Kind')));+    });+  });++  describe('del', () => {+    let ffProc;++    before(() => {+      ffProc = execPromise(+        `functions-framework --target=del --signature-type=http`,+        {timeout: FF_TIMEOUT, shell: true, cwd}+      );+    });++    after(async () => {+      await handleLinuxFailures(ffProc);+    });++    it('del: Fails without a key', async () => {+      const req = {+        body: {},+      };+

Nit: Remove unnecessary \n. We can put const declarations together. Even putting the const declarations next to the assert statements looks fine like del: Deletes an entity.

ace-n

comment created time in 5 days

PR opened GoogleCloudPlatform/nodejs-docs-samples

Reviewers
fix: Make functions_http_method consistent with other samples

Inline function handlers like in Go and Python. It looks weird (and is unnecessary) having standalone functions.

See: https://cloud.google.com/functions/docs/writing/http#handling_http_methods

+2 -12

0 comment

1 changed file

pr created time in 5 days

create barnchGoogleCloudPlatform/nodejs-docs-samples

branch : grant-patch-1

created branch time in 5 days

issue commentgoogleapis/nodejs-tasks

Cloud Tasks Emulator

This is more of a product request for Tasks than a sample for the Node repo. It's probably considered an important issue worth addressing, but it won't be fixed by a code sample, probably a tutorial or something else outside this repo.

dinigo

comment created time in 6 days

delete branch GoogleCloudPlatform/ruby-docs-samples

delete branch : grant-116968956

delete time in 6 days

push eventGoogleCloudPlatform/ruby-docs-samples

Grant Timmerman

commit sha 4ba21d8534173b45b42995c4dac73914f1de6140

Use autodetected location. See b/116968956

view details

Grant Timmerman

commit sha 3ec9c7860e890ead546bb42eefc679a462592c12

Update load_from_file.rb

view details

Grant Timmerman

commit sha 2e2ca1b259fd568807ee9ba596864c2e2d90e961

Merge pull request #433 from GoogleCloudPlatform/grant-116968956 BigQuery Snippets: Use autodetected location

view details

push time in 6 days

PR merged GoogleCloudPlatform/ruby-docs-samples

Reviewers
BigQuery Snippets: Use autodetected location cla: yes

Use autodetected location.

In the example provided, it is written that The location must be specified, but the example works even without setting location for datasets located in US and asia-northeast1. Whether specifying location for an upload job is an absolute requirement or not is affecting an application I'm working on. Can you provide details?

See b/116968956

+1 -2

4 comments

1 changed file

grant

pr closed time in 6 days

pull request commentGoogleCloudPlatform/ruby-docs-samples

BigQuery Snippets: Use autodetected location

Like the Java snippet, I added a note that the location is inferred here.

grant

comment created time in 6 days

push eventGoogleCloudPlatform/ruby-docs-samples

Grant Timmerman

commit sha 3ec9c7860e890ead546bb42eefc679a462592c12

Update load_from_file.rb

view details

push time in 6 days

push eventgrant/talks

Grant Timmerman

commit sha ded187d6d65c5a9724017f1718b064e13fef3dcb

Update applications.md

view details

push time in 6 days

push eventgrant/talks

Grant Timmerman

commit sha e791de3af07008525b60ea1e4acdc133994f5bf9

Update applications.md

view details

push time in 6 days

issue commentcdr/code-server

Use default port on 8080 instead of 8443.

I think you just can't configure the port, other args are fine.

I'll have to debug with my colleague later this week. I'm getting ERR_TOO_MANY_REDIRECTS, which seems like my issue.

Would be cool to have a "Deploy to Google Cloud" button or some instructions for this project.

grant

comment created time in 7 days

issue commentcdr/code-server

Use default port on 8080 instead of 8443.

Yeah, I'm just not sure how to create wrapper scripts to do that.

grant

comment created time in 7 days

issue commentcdr/code-server

Use default port on 8080 instead of 8443.

It's not possible to change the port for Cloud Run. I'm currently looking at ways to get around that.

grant

comment created time in 7 days

issue openedcdr/code-server

Use default port on 8080 instead of 8443.

It would be great if the default port and instructions were for PORT 8080 instead of 8443.

This is more standard in practice, and allows for easier integration with tools like Google Cloud Run.

https://github.com/cdr/code-server/blob/master/Dockerfile#L51

created time in 7 days

pull request commentgoogleapis/google-api-php-client

docs: Adds developer docs to repo: Fixes #1648 Fixes #1649 Fixes #165…

Thanks for the quick turnaround on the review @grant

Anytime.

grant

comment created time in 7 days

Pull request review commentgoogleapis/google-api-php-client

docs: Adds developer docs to repo: Fixes #1648 Fixes #1649 Fixes #165…

+# Using OAuth 2.0 for Web Server Applications++This document explains how web server applications use the Google API Client Library for PHP to implement OAuth 2.0 authorization to access Google APIs. OAuth 2.0 allows users to share specific data with an application while keeping their usernames, passwords, and other information private. For example, an application can use OAuth 2.0 to obtain permission from users to store files in their Google Drives.++This OAuth 2.0 flow is specifically for user authorization. It is designed for applications that can store confidential information and maintain state. A properly authorized web server application can access an API while the user interacts with the application or after the user has left the application.++Web server applications frequently also use [service accounts](https://developers.google.com/api-client-library/php/auth/service-accounts) to authorize API requests, particularly when calling Cloud APIs to access project-based data rather than user-specific data. Web server applications can use service accounts in conjunction with user authorization.

Hmm, well I fixed it for sure now.

grant

comment created time in 7 days

push eventgrant/google-api-php-client

Grant Timmerman

commit sha 9171216590b97358626aec5bc0105816157e3bec

docs: Fix bad link

view details

push time in 7 days

pull request commentgoogleapis/google-api-php-client

docs: Adds developer docs to repo: Fixes #1648 Fixes #1649 Fixes #165…

I'd suggest linking this to the relevant DevSite docs instead of adding this here, where it would quickly go out of date.

The point of this PR is to keep the docs close to the source code. The previous docs were last updated in ~2015. Since the libraries are updated more frequently, it's better to keep the docs here where they are visible by the team that works on the client.

grant

comment created time in 7 days

push eventgrant/google-api-php-client

Grant Timmerman

commit sha cec6631e28dc77cd7b7ca62fd19c713966584724

docs: Address @eesheesh's comments

view details

push time in 7 days

CommitCommentEvent
CommitCommentEvent

push eventgrant/talks

Grant Timmerman

commit sha 568eeed4406f1b0cbd506438be45626d0b7879bf

Add thanks tips

view details

push time in 8 days

issue openedgoogleapis/google-api-java-client

Remove Repo Description URL

Please remove the GitHub Repo Description URL. (No need for a replacement)

Docs for this client should be located in a different place than api-client-libraries/.

For example, the G+ API is deprecated. We can't use that as our official sample. https://developers.google.com/api-client-library/java/google-api-java-client/samples

created time in 8 days

Pull request review commentgoogleapis/google-api-php-client

docs: Adds developer docs to repo: Fixes #1648 Fixes #1649 Fixes #165…

+# Getting Started++This document provides all the basic information you need to start using the library. It covers important library concepts, shows examples for various use cases, and gives links to more information.++## Setup++There are a few setup steps you need to complete before you can use this library:++1.  If you don't already have a Google account, [sign up](https://www.google.com/accounts).+2.  If you have never created a Google API project, read the [Managing Projects page](https://developers.google.com/console/help/#managingprojects) and create a project in the [Google Developers Console](https://console.developers.google.com/)+3.  [Install](install.md) the library.++## Authentication and authorization++It is important to understand the basics of how API authentication and authorization are handled. All API calls must use either simple or authorized access (defined below). Many API methods require authorized access, but some can use either. Some API methods that can use either behave differently, depending on whether you use simple or authorized access. See the API's method documentation to determine the appropriate access type.++### 1. Simple API access (API keys)++These API calls do not access any private user data. Your application must authenticate itself as an application belonging to your Google Cloud project. This is needed to measure project usage for accounting purposes.++#### Important concepts++*   **API key**: To authenticate your application, use an [API key](/console/help/#WhatIsKey) for your Google Cloud Console project. Every simple access call your application makes must include this key.+    +> **Warning**: Keep your API key private. If someone obtains your key, they could use it to consume your quota or incur charges against your Google Cloud project.+    ++### 2. Authorized API access (OAuth 2.0)++These API calls access private user data. Before you can call them, the user that has access to the private data must grant your application access. Therefore, your application must be authenticated, the user must grant access for your application, and the user must be authenticated in order to grant that access. All of this is accomplished with [OAuth 2.0](/accounts/docs/OAuth2) and libraries written for it.++#### Important concepts++*   **Scope**: Each API defines one or more scopes that declare a set of operations permitted. For example, an API might have read-only and read-write scopes. When your application requests access to user data, the request must include one or more scopes. The user needs to approve the scope of access your application is requesting.+*   **Refresh and access tokens**: When a user grants your application access, the OAuth 2.0 authorization server provides your application with refresh and access tokens. These tokens are only valid for the scope requested. Your application uses access tokens to authorize API calls. Access tokens expire, but refresh tokens do not. Your application can use a refresh token to acquire a new access token.+    +    > **Warning**: Keep refresh and access tokens private. If someone obtains your tokens, they could use them to access private user data.+    +*   **Client ID and client secret**: These strings uniquely identify your application and are used to acquire tokens. They are created for your Google Cloud project on the [API Access pane](https://code.google.com/apis/console#:access) of the Google Cloud. There are three types of client IDs, so be sure to get the correct type for your application:+    +    *   Web application client IDs+    *   Installed application client IDs+    *   [Service Account](/accounts/docs/OAuth2ServiceAccount) client IDs

Done.

grant

comment created time in 8 days

Pull request review commentgoogleapis/google-api-php-client

docs: Adds developer docs to repo: Fixes #1648 Fixes #1649 Fixes #165…

+# Using OAuth 2.0 for Web Server Applications++This document explains how web server applications use the Google API Client Library for PHP to implement OAuth 2.0 authorization to access Google APIs. OAuth 2.0 allows users to share specific data with an application while keeping their usernames, passwords, and other information private. For example, an application can use OAuth 2.0 to obtain permission from users to store files in their Google Drives.++This OAuth 2.0 flow is specifically for user authorization. It is designed for applications that can store confidential information and maintain state. A properly authorized web server application can access an API while the user interacts with the application or after the user has left the application.++Web server applications frequently also use [service accounts](https://developers.google.com/api-client-library/php/auth/service-accounts) to authorize API requests, particularly when calling Cloud APIs to access project-based data rather than user-specific data. Web server applications can use service accounts in conjunction with user authorization.++## Prerequisites++### Enable APIs for your project++Any application that calls Google APIs needs to enable those APIs in the API Console. To enable the appropriate APIs for your project:++1.  Open the [Library](https://console.developers.google.com/apis/library) page in the API Console.+2.  Select the project associated with your application. Create a project if you do not have one already.+3.  Use the **Library** page to find each API that your application will use. Click on each API and enable it for your project.++### Create authorization credentials++Any application that uses OAuth 2.0 to access Google APIs must have authorization credentials that identify the application to Google's OAuth 2.0 server. The following steps explain how to create credentials for your project. Your applications can then use the credentials to access APIs that you have enabled for that project.++1.  Open the [Credentials page](https://console.developers.google.com/apis/credentials) in the API Console.+2.  Click **Create credentials > OAuth client ID**.+3.  Complete the form. Set the application type to `Web application`. Applications that use languages and frameworks like PHP, Java, Python, Ruby, and .NET must specify authorized **redirect URIs**. The redirect URIs are the endpoints to which the OAuth 2.0 server can send responses.  +      +    For testing, you can specify URIs that refer to the local machine, such as `http://localhost:8080`. With that in mind, please note that all of the examples in this document use `http://localhost:8080` as the redirect URI.  +      +    We recommend that you [design your app's auth endpoints](#protectauthcode) so that your application does not expose authorization codes to other resources on the page.++After creating your credentials, download the **client_secret.json** file from the API Console. Securely store the file in a location that only your application can access.++> **Important:** Do not store the **client_secret.json** file in a publicly-accessible location. In addition, if you share the source code to your application—for example, on GitHub—store the **client_secret.json** file outside of your source tree to avoid inadvertently sharing your client credentials.++### Identify access scopes++Scopes enable your application to only request access to the resources that it needs while also enabling users to control the amount of access that they grant to your application. Thus, there may be an inverse relationship between the number of scopes requested and the likelihood of obtaining user consent.++Before you start implementing OAuth 2.0 authorization, we recommend that you identify the scopes that your app will need permission to access.++We also recommend that your application request access to authorization scopes via an [incremental authorization](#incrementalAuth) process, in which your application requests access to user data in context. This best practice helps users to more easily understand why your application needs the access it is requesting.++The [OAuth 2.0 API Scopes](https://developers.google.com/identity/protocols/googlescopes) document contains a full list of scopes that you might use to access Google APIs.++> If your public application uses scopes that permit access to certain user data, it must pass review. If you see **unverified app** on the screen when testing your application, you must submit a verification request to remove it. Find out more about [unverified apps](https://support.google.com/cloud/answer/7454865) and get answers to [frequently asked questions about app verification](https://support.google.com/cloud/answer/9110914) in the Help Center.++### Language-specific requirements++To run any of the code samples in this document, you'll need a Google account, access to the Internet, and a web browser. If you are using one of the API client libraries, also see the language-specific requirements below.++To run the PHP code samples in this document, you'll need:++*   PHP 5.4 or greater with the command-line interface (CLI) and JSON extension installed.+*   The [Composer](https://getcomposer.org/) dependency management tool.+*   The Google APIs Client Library for PHP:+    ```sh+    php composer.phar require google/apiclient:^2.0+    ```+    +## Obtaining OAuth 2.0 access tokens++The following steps show how your application interacts with Google's OAuth 2.0 server to obtain a user's consent to perform an API request on the user's behalf. Your application must have that consent before it can execute a Google API request that requires user authorization.++The list below quickly summarizes these steps:++1.  Your application identifies the permissions it needs.+2.  Your application redirects the user to Google along with the list of requested permissions.+3.  The user decides whether to grant the permissions to your application.+4.  Your application finds out what the user decided.+5.  If the user granted the requested permissions, your application retrieves tokens needed to make API requests on the user's behalf.++### Step 1: Set authorization parameters++Your first step is to create the authorization request. That request sets parameters that identify your application and define the permissions that the user will be asked to grant to your application.++The code snippet below creates a `Google_Client()` object, which defines the parameters in the authorization request.++That object uses information from your **client_secret.json** file to identify your application. (See [creating authorization credentials](#creatingcred) for more about that file.) The object also identifies the scopes that your application is requesting permission to access and the URL to your application's auth endpoint, which will handle the response from Google's OAuth 2.0 server. Finally, the code sets the optional access_type and include_granted_scopes parameters.++For example, this code requests read-only, offline access to a user's Google Drive:++```php+$client = new Google_Client();+$client->setAuthConfig('client_secret.json');+$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);+$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');+$client->setAccessType('offline');        // offline access+$client->setIncludeGrantedScopes(true);   // incremental auth+```++The request specifies the following information:++#### Parameters++##### `client_id`++**Required**. The client ID for your application. You can find this value in the [API Console](https://console.developers.google.com/). In PHP, call the `setAuthConfig` function to load authorization credentials from a **client_secret.json** file.++```php+$client = new Google_Client();+$client->setAuthConfig('client_secret.json');+```++##### `redirect_uri`++**Required**. Determines where the API server redirects the user after the user completes the authorization flow. The value must exactly match one of the authorized redirect URIs for the OAuth 2.0 client, which you configured in the [API Console](https://console.developers.google.com/). If this value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch' error. Note that the `http` or `https` scheme, case, and trailing slash ('`/`') must all match.  +  +To set this value in PHP, call the `setRedirectUri` function. Note that you must specify a valid redirect URI for your API Console project.++```php+$client->setRedirectUri('http://localhost:8080/oauth2callback.php');+```++##### `scope`++**Required**. A space-delimited list of scopes that identify the resources that your application could access on the user's behalf. These values inform the consent screen that Google displays to the user.  +  +Scopes enable your application to only request access to the resources that it needs while also enabling users to control the amount of access that they grant to your application. Thus, there is an inverse relationship between the number of scopes requested and the likelihood of obtaining user consent. To set this value in PHP, call the `addScope` function:++```php+$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);+```++The [OAuth 2.0 API Scopes](https://developers.google.com/identity/protocols/googlescopes) document provides a full list of scopes that you might use to access Google APIs.  +  +We recommend that your application request access to authorization scopes in context whenever possible. By requesting access to user data in context, via [incremental authorization](#incrementalAuth), you help users to more easily understand why your application needs the access it is requesting.++##### `access_type`++**Recommended**. Indicates whether your application can refresh access tokens when the user is not present at the browser. Valid parameter values are `online`, which is the default value, and `offline`.  +  +Set the value to `offline` if your application needs to refresh access tokens when the user is not present at the browser. This is the method of refreshing access tokens described later in this document. This value instructs the Google authorization server to return a refresh token _and_ an access token the first time that your application exchanges an authorization code for tokens.  +  +To set this value in PHP, call the `setAccessType` function:++```php+$client->setAccessType('offline');+```++##### `state`++**Recommended**. Specifies any string value that your application uses to maintain state between your authorization request and the authorization server's response. The server returns the exact value that you send as a `name=value` pair in the hash (`#`) fragment of the `redirect_uri` after the user consents to or denies your application's access request.  +  +You can use this parameter for several purposes, such as directing the user to the correct resource in your application, sending nonces, and mitigating cross-site request forgery. Since your `redirect_uri` can be guessed, using a `state` value can increase your assurance that an incoming connection is the result of an authentication request. If you generate a random string or encode the hash of a cookie or another value that captures the client's state, you can validate the response to additionally ensure that the request and response originated in the same browser, providing protection against attacks such as cross-site request forgery. See the [OpenID Connect](https://developers.google.com/identity/protocols/OpenIDConnect#createxsrftoken) documentation for an example of how to create and confirm a `state` token.  +  +To set this value in PHP, call the `setState` function:++```php+$client->setState($sample_passthrough_value);+```++##### `include_granted_scopes`++**Optional**. Enables applications to use incremental authorization to request access to additional scopes in context. If you set this parameter's value to `true` and the authorization request is granted, then the new access token will also cover any scopes to which the user previously granted the application access. See the [incremental authorization](#incrementalAuth) section for examples.  +  +To set this value in PHP, call the `setIncludeGrantedScopes` function:++```php+$client->setIncludeGrantedScopes(true);+```++##### `login_hint`++**Optional**. If your application knows which user is trying to authenticate, it can use this parameter to provide a hint to the Google Authentication Server. The server uses the hint to simplify the login flow either by prefilling the email field in the sign-in form or by selecting the appropriate multi-login session.  +  +Set the parameter value to an email address or `sub` identifier, which is equivalent to the user's Google ID.  +  +To set this value in PHP, call the `setLoginHint` function:++```php+$client->setLoginHint('timmerman@google.com');+```++##### `prompt`++**Optional**. A space-delimited, case-sensitive list of prompts to present the user. If you don't specify this parameter, the user will be prompted only the first time your app requests access.  +  +To set this value in PHP, call the `setApprovalPrompt` function:++```php+$client->setApprovalPrompt('consent');+```++Possible values are:++`none`++Do not display any authentication or consent screens. Must not be specified with other values.++`consent`++Prompt the user for consent.++`select_account`++Prompt the user to select an account.++### Step 2: Redirect to Google's OAuth 2.0 server++Redirect the user to Google's OAuth 2.0 server to initiate the authentication and authorization process. Typically, this occurs when your application first needs to access the user's data. In the case of [incremental authorization](#incrementalAuth), this step also occurs when your application first needs to access additional resources that it does not yet have permission to access.++1.  Generate a URL to request access from Google's OAuth 2.0 server:+    +    ```php+    $auth_url = $client->createAuthUrl();+    ```+    +2.  Redirect the user to `$auth_url`:+    +    ```php+    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));+    ```    ++Google's OAuth 2.0 server authenticates the user and obtains consent from the user for your application to access the requested scopes. The response is sent back to your application using the redirect URL you specified.++### Step 3: Google prompts user for consent++In this step, the user decides whether to grant your application the requested access. At this stage, Google displays a consent window that shows the name of your application and the Google API services that it is requesting permission to access with the user's authorization credentials. The user can then consent or refuse to grant access to your application.++Your application doesn't need to do anything at this stage as it waits for the response from Google's OAuth 2.0 server indicating whether the access was granted. That response is explained in the following step.++### Step 4: Handle the OAuth 2.0 server response++The OAuth 2.0 server responds to your application's access request by using the URL specified in the request.++If the user approves the access request, then the response contains an authorization code. If the user does not approve the request, the response contains an error message. The authorization code or error message that is returned to the web server appears on the query string, as shown below:++An error response:++    https://oauth2.example.com/auth?error=access_denied++An authorization code response:++    https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7++> **Important**: If your response endpoint renders an HTML page, any resources on that page will be able to see the authorization code in the URL. Scripts can read the URL directly, and the URL in the `Referer` HTTP header may be sent to any or all resources on the page.  +>+> Carefully consider whether you want to send authorization credentials to all resources on that page (especially third-party scripts such as social plugins and analytics). To avoid this issue, we recommend that the server first handle the request, then redirect to another URL that doesn't include the response parameters.++#### Sample OAuth 2.0 server response++You can test this flow by clicking on the following sample URL, which requests read-only access to view metadata for files in your Google Drive:++```+https://accounts.google.com/o/oauth2/v2/auth?+ scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&+ access_type=offline&+ include_granted_scopes=true&+ state=state_parameter_passthrough_value&+ redirect_uri=http%3A%2F%2Foauth2.example.com%2Fcallback&+ response_type=code&+ client_id=client_id+```++After completing the OAuth 2.0 flow, you should be redirected to `http://localhost/oauth2callback`, which will likely yield a `404 NOT FOUND` error unless your local machine serves a file at that address. The next step provides more detail about the information returned in the URI when the user is redirected back to your application.++### Step 5: Exchange authorization code for refresh and access tokens++After the web server receives the authorization code, it can exchange the authorization code for an access token.++To exchange an authorization code for an access token, use the `authenticate` method:++```php+$client->authenticate($_GET['code']);+```++You can retrieve the access token with the `getAccessToken` method:++```php+$access_token = $client->getAccessToken();+```++[](#top_of_page)Calling Google APIs+-----------------------------------++Use the access token to call Google APIs by completing the following steps:++1.  If you need to apply an access token to a new `Google_Client` object—for example, if you stored the access token in a user session—use the `setAccessToken` method:+    +    ```php+    $client->setAccessToken($access_token);+    ```+    +2.  Build a service object for the API that you want to call. You build a a service object by providing an authorized `Google_Client` object to the constructor for the API you want to call. For example, to call the Drive API:+    +    ```php+    $drive = new Google_Service_Drive($client);+    ```+    +3.  Make requests to the API service using the [interface provided by the service object](https://developers.google.com/api-client-library/php/start/get_started#build). For example, to list the files in the authenticated user's Google Drive:

Done.

grant

comment created time in 8 days

more