aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGrant Timmerman <timmerman+devrel@google.com>2019-06-26 07:39:48 -0700
committerBu Sun Kim <8822365+busunkim96@users.noreply.github.com>2019-06-26 07:39:48 -0700
commit5c11b0a1b2658b26fe41b13ebd2e9e7b53c1ab01 (patch)
tree152d837a399eba853d2d8a44cba19a74912c52d6
parent715bd7f9ca9a324a05ee05a6476af383e54930f9 (diff)
downloadgoogle-api-python-client-5c11b0a1b2658b26fe41b13ebd2e9e7b53c1ab01.tar.gz
docs: Add docs folder with guides from developers.google.com
-rw-r--r--README.md25
-rw-r--r--docs/README.md35
-rw-r--r--docs/api-keys.md15
-rw-r--r--docs/auth.md41
-rw-r--r--docs/client-secrets.md80
-rw-r--r--docs/django.md47
-rw-r--r--docs/google_app_engine.md149
-rw-r--r--docs/logging.md51
-rw-r--r--docs/media.md75
-rw-r--r--docs/mocks.md106
-rw-r--r--docs/oauth-installed.md173
-rw-r--r--docs/oauth-server.md148
-rw-r--r--docs/oauth-web.md54
-rw-r--r--docs/oauth.md180
-rw-r--r--docs/pagination.md21
-rw-r--r--docs/performance.md48
-rw-r--r--docs/start.md422
-rw-r--r--docs/thread_safety.md28
18 files changed, 1690 insertions, 8 deletions
diff --git a/README.md b/README.md
index 8d4c426b6..8a1f4f25d 100644
--- a/README.md
+++ b/README.md
@@ -8,30 +8,38 @@ This is the Python client library for Google's discovery based APIs. To get star
These client libraries are officially supported by Google. However, the libraries are considered complete and are in maintenance mode. This means that we will address critical bugs and security issues but will not add any new features.
+## Documentation
+
+See the [docs folder](docs/README.md) for more detailed instructions and additional documentation.
+
## Google Cloud Platform
For Google Cloud Platform APIs such as Datastore, Cloud Storage or Pub/Sub, we recommend using [Cloud Client Libraries for Python](https://github.com/GoogleCloudPlatform/google-cloud-python) which is under active development.
-# Installation
+## Installation
+
To install, simply use `pip` or `easy_install`:
```bash
-$ pip install --upgrade google-api-python-client
+pip install --upgrade google-api-python-client
```
+
or
+
```bash
-$ easy_install --upgrade google-api-python-client
+easy_install --upgrade google-api-python-client
```
-See the [Developers Guide](https://developers.google.com/api-client-library/python/start/get_started) for more detailed instructions and additional documentation.
+## Supported Python Versions
-# Supported Python Versions
Python 3.4, 3.5, 3.6 and 3.7 are fully supported and tested. This library may work on later versions of 3, but we do not currently run tests against those versions
-# Deprecated Python Versions
+## Deprecated Python Versions
+
Python == 2.7
-# Third Party Libraries and Dependencies
+## Third Party Libraries and Dependencies
+
The following libraries will be installed when you install the client library:
* [httplib2](https://github.com/httplib2/httplib2)
* [uritemplate](https://github.com/sigmavirus24/uritemplate)
@@ -41,5 +49,6 @@ For development you will also need the following libraries:
* [pycrypto](https://pypi.python.org/pypi/pycrypto)
* [pyopenssl](https://pypi.python.org/pypi/pyOpenSSL)
-# Contributing
+## Contributing
+
Please see the [contributing page](http://google.github.io/google-api-python-client/contributing.html) for more information. In particular, we love pull requests - but please make sure to sign the contributor license agreement.
diff --git a/docs/README.md b/docs/README.md
new file mode 100644
index 000000000..9157aadf4
--- /dev/null
+++ b/docs/README.md
@@ -0,0 +1,35 @@
+# Google API Client LIbrary for Python Docs
+
+ The Google API Client Library for Python is designed for Python
+client-application developers. It offers simple, flexible
+access to many Google APIs.
+
+## Features
+
+- Call Google APIs simply
+- Use the library with Google App Engine
+- Handle Auath with fewer lines of code
+- Use standard tooling for installation
+
+## Documentation
+
+Learn how to use the Google API Python Client with these guides:
+
+- [Getting Started](start.md)
+- [Auth](auth.md)
+ - [API Keys](api-keys.md)
+ - [OAuth 2.0](oauth.md)
+ - [OAuth 2.0 for Web Server Applications](oauth-web.md)
+ - [OAuth 2.0 for Installed Applications](oauth-installed.md)
+ - [OAuth 2.0 for Server to Server Applications](oauth-server.md)
+ - [Client Secrets](client-secrets.md)
+- How to...
+ - [Use Logging](logging.md)
+ - [Upload Media](media.md)
+ - [Use Mocks](mocks.md)
+ - [Use Pagination](pagination.md)
+ - [Improve Performance](performance.md)
+ - [Understand Thread Safety](thread_safety.md)
+ - [Use Google App Engine](google_app_engine.md)
+ - [Use Django](django.md)
+ \ No newline at end of file
diff --git a/docs/api-keys.md b/docs/api-keys.md
new file mode 100644
index 000000000..9d73cbb29
--- /dev/null
+++ b/docs/api-keys.md
@@ -0,0 +1,15 @@
+# API Keys
+
+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 Developers Console documentation also describes [API keys](https://developers.google.com/console/help/using-keys).
+
+> Note: If you do need to access private user data, you must use OAuth 2.0. See [Using OAuth 2.0 for Web Server Applications](oauth-server.md) and [Using OAuth 2.0 for Server to Server Applications](oauth-web.md) for more information.
+
+## Using API Keys
+
+To use API keys, pass them to the `build()` function when creating service objects. For example:
+
+```py
+books_service = build('books', 'v1', developerKey='api_key')
+```
+
+All calls made using that service object will include your API key.
diff --git a/docs/auth.md b/docs/auth.md
new file mode 100644
index 000000000..f197fe338
--- /dev/null
+++ b/docs/auth.md
@@ -0,0 +1,41 @@
+# Authentication Overview
+
+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.
+
+## Access types
+
+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 API Console project. This is needed to measure project usage for accounting purposes.
+
+**API key:** To authenticate your application, use an [API key](api-keys.md) for your API 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 API Console 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 and libraries written for it.
+
+**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 project on the [API Console](https://console.developers.google.com/). There are three types of client IDs, so be sure to get the correct type for your application:
+
+- [Web application](https://developers.google.com/accounts/docs/OAuth2WebServer) client IDs
+- [Installed application](https://developers.google.com/accounts/docs/OAuth2InstalledApp) client IDs
+- [Service Account](https://developers.google.com/accounts/docs/OAuth2ServiceAccount) client IDs
+
+> **Warning:** 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.
+
+## Using API keys
+
+More information and examples for API keys are provided on the [API Keys](api-keys.md) page.
+
+## Using OAuth 2.0
+
+More information and examples for OAuth 2.0 are provided on the [OAuth 2.0](oauth.md) page.
diff --git a/docs/client-secrets.md b/docs/client-secrets.md
new file mode 100644
index 000000000..9a53882e6
--- /dev/null
+++ b/docs/client-secrets.md
@@ -0,0 +1,80 @@
+# Client Secrets
+
+The Google APIs Client Library for Python uses the `client_secrets.json` file format for storing the `client_id`, `client_secret`, and other OAuth 2.0 parameters.
+
+The `client_secrets.json` file format is a [JSON](http://www.json.org/) 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:
+
+```json
+{
+ "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"
+ }
+}
+```
+
+Here is an example client_secrets.json file for an installed application:
+
+```json
+{
+ "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"
+ }
+}
+```
+
+The format defines one of two client ID types:
+
+- `web`: Web application.
+- `installed`: Installed application.
+
+The `web` and `installed` sub-objects have the following mandatory members:
+
+- `client_id` (string): The client ID.
+- `client_secret` (string): The client secret.
+- `redirect_uris` (list of strings): A list of valid redirection endpoint URIs. This list should match the list entered for the client ID on the [API Access pane](https://code.google.com/apis/console#:access) of the Google APIs Console.
+- `auth_uri` (string): The authorization server endpoint URI.
+- `token_uri` (string): The token server endpoint URI.
+
+All of the above members are mandatory. The following optional parameters may appear:
+
+- `client_email` (string) The service account email associated with the client.
+- `auth_provider_x509_cert_url` (string) The URL of the public x509 certificate, used to verify the signature on JWTs, such as ID tokens, signed by the authentication provider.
+- `client_x509_cert_url` (string) The URL of the public x509 certificate, used to verify JWTs signed by the client.
+
+The following examples show how use a `client_secrets.json` file to create a `Flow` object in either an installed application or a web application:
+
+### Installed App
+
+```py
+from google_auth_oauthlib.flow import InstalledAppFlow
+...
+flow = InstalledAppFlow.from_client_secrets_file(
+ 'path_to_directory/client_secret.json',
+ scopes=['https://www.googleapis.com/auth/calendar'])
+```
+
+### Web Server App
+
+```py
+import google.oauth2.credentials
+import google_auth_oauthlib.flow
+
+flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
+ 'path_to_directory/client_secret.json',
+ scopes=['https://www.googleapis.com/auth/calendar'])
+
+flow.redirect_uri = 'https://www.example.com/oauth2callback'
+```
+
+## Motivation
+
+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.
+
diff --git a/docs/django.md b/docs/django.md
new file mode 100644
index 000000000..1f676bea0
--- /dev/null
+++ b/docs/django.md
@@ -0,0 +1,47 @@
+# Using Django
+
+The Google APIs Client Library for Python has special support for the [Django](https://www.djangoproject.com/) 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 [Flow](https://developers.google.com/api-client-library/python/guide/aaa_oauth#flows), [Credentials](https://developers.google.com/api-client-library/python/guide/aaa_oauth#credentials), and [Storage](https://developers.google.com/api-client-library/python/guide/aaa_oauth#storage) objects.
+
+## Flows
+
+Use the [oauth2client.contrib.django\_orm.FlowField](https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.django_orm.html#oauth2client.contrib.django_orm.FlowField) class as a Django model field so that `Flow` 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 `Flow` objects before the first redirection. This way, your redirection handlers can retrieve the `Flow` object already created for the user. In the following code, a model is defined that allows `Flow` objects to be stored and keyed by `User`:
+
+```py
+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()
+```
+
+## Credentials
+
+Use the [oauth2client.contrib.django\_orm.CredentialsField](https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.django_orm.html#oauth2client.contrib.django_orm.CredentialsField) class as a Django model field so that `Credentials` objects can easily be stored. Similar to `Flow` objects, it's normally best to store per-user `Credentials` objects. In the following code, a model is defined that allows `Credentials` objects to be stored and keyed by `User`:
+
+```py
+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()
+```
+
+## Storage
+
+Use the [oauth2client.contrib.django\_orm.Storage](https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.django_orm.html#oauth2client.contrib.django_orm.Storage) class to store and retrieve `Credentials` objects using a model defined with a `CredentialsField` object. You pass the model, field name for the model key, value for the model key, and field name to the `CredentialsField` constructor. The following shows how to create, read, and write `Credentials` objects using the example `CredentialsModel` class above:
+
+```py
+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)
+```
diff --git a/docs/google_app_engine.md b/docs/google_app_engine.md
new file mode 100644
index 000000000..c261ed8f7
--- /dev/null
+++ b/docs/google_app_engine.md
@@ -0,0 +1,149 @@
+# Using Google App Engine
+
+The Google APIs Client Library for Python has special support for [Google App Engine](https://developers.google.com/appengine) 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 [OAuth 2.0](https://developers.google.com/api-client-library/python/guide/aaa_oauth) page.
+
+## Decorators
+
+The easiest way to handle OAuth 2.0 is to use the App Engine [Python decorators](http://en.wikipedia.org/wiki/Python_syntax_and_semantics#Decorators) supplied by this library. These decorators handle all of the OAuth 2.0 steps without you having to use any `Flow`, `Credentials`, or `Storage` objects.
+
+There are two decorator classes to choose from:
+
+* **OAuth2Decorator**: Use the [OAuth2Decorator](https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.appengine.html#oauth2client.contrib.appengine.OAuth2Decorator) class to contruct a decorator with your client ID and secret.
+* **OAuth2DecoratorFromClientSecrets**: Use the [OAuth2DecoratorFromClientSecrets](https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.appengine.html#oauth2client.contrib.appengine.OAuth2DecoratorFromClientSecrets) class to contruct a decorator using a `client_secrets.json` file described in the [flow\_from\_clientsecrets()](https://developers.google.com/api-client-library/python/guide/aaa_oauth#flow_from_clientsecrets) section of the OAuth 2.0 page.
+
+There are also two decorator types to choose from:
+
+* **oauth\_required**: Any method decorated with `oauth_required` completes all OAuth 2.0 steps before entering the function. Within the body of the function, you can use the decorator's `http()` function to get an `Http` object that has already been authorized.
+* **oauth\_aware**: This decorator type requires a little more code than `oauth_required`, 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:
+ * **has\_credentials()**: Returns `True` if there are valid access credentials for the logged in user.
+ * **authorize\_url()**: Returns the first URL that starts the OAuth 2.0 steps.
+
+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.
+
+```py
+def main():
+ application = webapp.WSGIApplication(
+ [
+ ('/', MainHandler),
+ ('/about', AboutHandler),
+ (decorator.callback_path, decorator.callback_handler()),
+ ],
+ debug=True)
+ run_wsgi_app(application)
+```
+
+In the following code snippet, the `OAuth2Decorator` class is used to create an `oauth_required` decorator, and the decorator is applied to a function that accesses the [Google Calendar API](https://developers.google.com/google-apps/calendar/):
+
+```py
+from apiclient.discovery import build
+from google.appengine.ext import webapp
+from oauth2client.contrib.appengine import OAuth2Decorator
+
+decorator = OAuth2Decorator(
+ client_id='your_client_id',
+ client_secret='your_client_secret',
+ 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)
+ ...
+```
+
+In the following code snippet, the `OAuth2DecoratorFromClientSecrets` class is used to create an `oauth_aware` decorator, and the decorator is applied to a function that accesses the [Google Tasks API](https://developers.google.com/google-apps/tasks/):
+
+```py
+import os
+from apiclient.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.
+ ...
+```
+
+## Service Accounts
+
+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 [Service Accounts](https://developers.google.com/accounts/docs/OAuth2ServiceAccount). These server-to-server interactions do not involve a user, and only your application needs to authenticate itself. Use the [AppAssertionCredentials](https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.appengine.html#oauth2client.contrib.appengine.AppAssertionCredentials) class to create a `Credentials` object without using a `Flow` object.
+
+In the following code snippet, a `Credentials` object is created and an `Http` object is authorized:
+
+import httplib2from google.appengine.api import memcachefrom oauth2client.contrib.appengine import AppAssertionCredentials
+...credentials \= AppAssertionCredentials(scope\='https://www.googleapis.com/auth/devstorage.read\_write')http \= credentials.authorize(httplib2.Http(memcache))
+
+Once you have an authorized `Http` object, you can pass it to the [build()](https://google.github.io/google-api-python-client/docs/epy/googleapiclient.discovery-module.html#build) or [execute()](https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.HttpRequest-class.html#execute) functions as you normally would.
+
+## Flows
+
+Use App Engine's [Memcache](https://developers.google.com/appengine/docs/python/memcache/usingmemcache) to store `Flow` objects. When your application is simultaneously going through OAuth 2.0 steps for many users, it's normally best to store per-user `Flow` objects before the first redirection. This way, your redirection handlers can retrieve the `Flow` object already created for the user. In the following code snippet, `Memcache` is used to store and retrieve `Flow` objects keyed by user ID:
+
+```py
+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()))
+```
+
+## Credentials
+
+Use the [oauth2client.contrib.appengine.CredentialsProperty](https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.appengine.html#oauth2client.contrib.appengine.CredentialsProperty) class as an [App Engine Datastore](https://developers.google.com/appengine/docs/python/datastore/overview) `Property`. Creating a `Model` with this `Property` simplifies storing `Credentials` as explained in the [Storage](#Storage) section below. In the following code snippet, a `Model` class is defined using this `Property`.
+
+```py
+from google.appengine.ext import db
+from oauth2client.contrib.appengine import CredentialsProperty
+...
+class CredentialsModel(db.Model):
+ credentials = CredentialsProperty()
+```
+
+## Storage
+
+Use the [oauth2client.contrib.appengine.StorageByKeyName](https://oauth2client.readthedocs.io/en/latest/source/oauth2client.contrib.appengine.html#oauth2client.contrib.appengine.StorageByKeyName) class to store and retrieve `Credentials` objects to and from the [App Engine Datastore](https://developers.google.com/appengine/docs/python/datastore/overview). You pass the model, key value, and property name to its constructor. The following shows how to create, read, and write `Credentials` objects using the example `CredentialsModel` class above:
+
+```py
+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)
+```
+
+## Samples
+
+To see how these classes work together in a full application, see the [App Engine sample applications](https://github.com/google/google-api-python-client/tree/master/samples/appengine) section of this library’s open source project page. \ No newline at end of file
diff --git a/docs/logging.md b/docs/logging.md
new file mode 100644
index 000000000..76d07a9d2
--- /dev/null
+++ b/docs/logging.md
@@ -0,0 +1,51 @@
+# 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](http://docs.python.org/library/logging.html) 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:
+
+```py
+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](https://github.com/httplib2/httplib2) module used by this library. The following code snippet enables logging of all HTTP request and response headers and bodies:
+
+```py
+import httplib2
+httplib2.debuglevel = 4
+``` \ No newline at end of file
diff --git a/docs/media.md b/docs/media.md
new file mode 100644
index 000000000..54f65e1d6
--- /dev/null
+++ b/docs/media.md
@@ -0,0 +1,75 @@
+# 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:
+
+```py
+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:
+
+```py
+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](https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.MediaFileUpload-class.html) class for the media_body value:
+
+```py
+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`](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:
+
+```py
+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:
+
+```py
+media = MediaFileUpload('pig.png', mimetype='image/png', chunksize=1048576, resumable=True)
+```
+
+> Note: 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`](https://google.github.io/google-api-python-client/docs/epy/googleapiclient.errors.HttpError-class.html) 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:
+
+```py
+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](https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.MediaUpload-class.html) which provides the data to be uploaded. You must fully implement the MediaUpload interface. See the source for the [MediaFileUpload](https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.MediaFileUpload-class.html), [MediaIoBaseUpload](MediaIoBaseUpload), and [MediaInMemoryUpload](https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.MediaInMemoryUpload-class.html) classes as examples.
+
diff --git a/docs/mocks.md b/docs/mocks.md
new file mode 100644
index 000000000..09a69f017
--- /dev/null
+++ b/docs/mocks.md
@@ -0,0 +1,106 @@
+# Mocks
+
+The use of [Mock objects](http://en.wikipedia.org/wiki/Mock_object) 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.
+
+> **Note:** Many of the [Python Client Library test scripts](https://github.com/google/google-api-python-client/tree/master/tests) use these classes.
+
+## HttpMock
+
+This class simulates the response to a single HTTP request. As arguments, the constructor for the [HttpMock](https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.HttpMock-class.html) 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.
+
+### Example
+
+This example uses `HttpMock` to simulate the basic steps necessary to complete an API call to the [Google Books API](https://developers.google.com/apis-explorer/#p/books/v1/). The first Mock HTTP returns a status code of 200 and a file named `books-discovery.json`, 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 `books-android.json`, the simulated response.
+
+```py
+from apiclient.discovery import build
+from apiclient.http import HttpMock
+import pprint
+
+http = HttpMock('books-discovery.json', {'status': '200'})
+api_key = 'your_api_key'
+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)
+```
+
+> **Notes:**
+> - To run this sample, it would not be necessary to replace the placeholder your_api_key with an actual key, since the Mock object does not actually call the API.
+> - As you develop and test your application, it is a good idea to save actual API responses in files like books-discovery.json or books-android.json for use in testing.
+> - Notice that a second HttpMock is created to simulate the second HTTP call.
+> - The second use of the execute method demonstrates how you can re-use the request object by calling execute with another Mock object as an argument. (This would also work with an actual HTTP call.)
+
+## HttpMockSequence
+
+The [HttpMockSequence](https://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.HttpMockSequence-class.html) 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.
+
+### Special Values for simulated HTTP responses
+
+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.
+
+<table>
+ <tbody><tr>
+ <th>
+ Keyword
+ </th>
+ <th>
+ Returns:
+ </th>
+ </tr>
+ <tr>
+ <td>
+ <code><span>echo_request_headers</span></code>
+ </td>
+ <td>
+ the complete request headers
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><span>echo_request_headers_as_json</span></code>
+ </td>
+ <td>
+ the complete request headers as a json object
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><span>echo_request_body</span></code>
+ </td>
+ <td>
+ the request body
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <code><span>echo_request_uri</span></code>
+ </td>
+ <td>
+ the request uri
+ </td>
+ </tr></tbody>
+</table>
+
+### Example
+
+The following code snippet combines the two HTTP call simulations from the previous snippet into a single Mock object. The object created using `HttpMockSequence` simulates the return of the discovery document from the `books.volume.list` service, then the return of the result of the 'android' query (built in to the `request` object). You could add code to this snipped to print the contents of `response`, test that it returned successfully, etc.
+
+```py
+from apiclient.discovery import build
+from apiclient.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()
+``` \ No newline at end of file
diff --git a/docs/oauth-installed.md b/docs/oauth-installed.md
new file mode 100644
index 000000000..aaca065c1
--- /dev/null
+++ b/docs/oauth-installed.md
@@ -0,0 +1,173 @@
+# Using OAuth 2.0 for Installed Applications
+
+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.
+
+This document is for you if:
+
+- You are writing an installed app for a platform other than Android or iOS, and
+- Your installed app will run on devices that have a system browser and rich input capabilities, such as devices with full keyboards.
+
+If you are writing an app for Android or iOS, use [Google Sign-In](https://developers.google.com/identity) 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 [Android](https://developers.google.com/identity/sign-in/android) or [iOS](https://developers.google.com/identity/sign-in/ios).
+
+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 [Using OAuth 2.0 for Devices](https://developers.google.com/accounts/docs/OAuth2ForDevices).
+
+## Overview
+
+To use OAuth 2.0 in a locally-installed application, first create application credentials for your project in the API Console.
+
+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.
+
+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.
+
+Finally, your application can use the access token to call Google APIs.
+
+This flow is similar to the one shown in the [Using OAuth 2.0 for Web Server Applications](https://developers.google.com/api-client-library/python/auth/web-app), but with three differences:
+
+- When creating a client ID, you specify that your application is an Installed application. This results in a different value for the redirect_uri parameter.
+- 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.
+- 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.
+
+## Creating application credentials
+
+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.
+
+To obtain application credentials for your project, complete these steps:
+
+1. Open the [Credentials page](https://console.developers.google.com/apis/credentials) in the API Console.
+1. If you haven't done so already, create your OAuth 2.0 credentials by clicking **Create new Client ID** under the **OAuth** heading and selecting the **Installed application** type. Next, look for your application's client ID and client secret in the relevant table.
+
+Download the client_secrets.json file and securely store it in a location that only your application can access.
+
+> **Important:** 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.
+
+## Configuring the client object
+
+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.
+
+### Choosing a redirect URI
+
+When you create a client ID in the [Google API Console](https://console.developers.google.com/), two redirect_uri parameters are created for you: `urn:ietf:wg:oauth:2.0:oob` and `http://localhost`. The value your application uses determines how the authorization code is returned to your application.
+
+#### http://localhost
+
+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 [Google API Console](https://console.developers.google.com/) 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.
+
+> **Note:** 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.
+
+#### urn:ietf:wg:oauth:2.0:oob
+
+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.
+
+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.
+
+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.
+
+#### urn:ietf:wg:oauth:2.0:oob:auto
+
+urn:ietf:wg:oauth:2.0:oob:auto
+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.
+
+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.
+
+### Creating the object
+
+To create a client object from the client_secrets.json file, use the `flow_from_clientsecrets` function. For example, to request read-only access to a user's Google Drive:
+
+```py
+from google_auth_oauthlib.flow import InstalledAppFlow
+
+flow = InstalledAppFlow.from_client_secrets_file(
+ 'client_secret.json',
+ scope=['https://www.googleapis.com/auth/drive.metadata.readonly'])
+```
+
+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.
+
+## Sending users to Google's OAuth 2.0 server
+
+Use either the `run_console` or `run_local_server` function to direct the user to Google's OAuth 2.0 server:
+
+- The run_console 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.
+
+ ```py
+ credentials = flow.run_console()
+ ```
+
+- The run_local_server 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.
+
+ ```py
+ credentials = flow.run_local_server(host='localhost',
+ port=8080,
+ authorization_prompt_message='Please visit this URL: {url}',
+ success_message='The auth flow is complete; you may close this window.',
+ open_browser=True)
+ ```
+
+Google's OAuth 2.0 server authenticates the user and obtains consent from the user for your application to access the requested scopes.
+
+## Calling Google APIs
+
+Use the authorized `Http` object to call Google APIs by completing the following steps:
+
+1. Build a service object for the API that you want to call. You build a a service object by calling the `build` function with the name and version of the API and the authorized Http object. For example, to call version 2 of the Drive API:
+
+ ```py
+ from googleapiclient.discovery import build
+
+ drive_service = build('drive', 'v3', credentials=credentials)
+ ```
+
+1. Make requests to the API service using the [interface provided by the service object](start.md#build). For example, to list the files in the authenticated user's Google Drive:
+
+ ```py
+ files = drive_service.files().list().execute()
+ ```
+
+## Complete example
+
+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.
+
+```py
+import os
+import pprint
+
+import google.oauth2.credentials
+
+from googleapiclient.discovery import build
+from googleapiclient.errors import HttpError
+from google_auth_oauthlib.flow import InstalledAppFlow
+
+pp = pprint.PrettyPrinter(indent=2)
+
+# The CLIENT_SECRETS_FILE variable specifies the name of a file that contains
+# the OAuth 2.0 information for this application, including its client_id and
+# client_secret.
+CLIENT_SECRETS_FILE = "client_secret.json"
+
+# This access scope grants read-only access to the authenticated user's Drive
+# account.
+SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly']
+API_SERVICE_NAME = 'drive'
+API_VERSION = 'v3'
+
+def get_authenticated_service():
+ flow = InstalledAppFlow.from_client_secrets_file(CLIENT_SECRETS_FILE, SCOPES)
+ credentials = flow.run_console()
+ return build(API_SERVICE_NAME, API_VERSION, credentials = credentials)
+
+def list_drive_files(service, **kwargs):
+ results = service.files().list(
+ **kwargs
+ ).execute()
+
+ pp.pprint(results)
+
+if __name__ == '__main__':
+ # When running locally, disable OAuthlib's HTTPs verification. When
+ # running in production *do not* leave this option enabled.
+ os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
+ service = get_authenticated_service()
+ list_drive_files(service,
+ orderBy='modifiedByMeTime desc',
+ pageSize=5)
+``` \ No newline at end of file
diff --git a/docs/oauth-server.md b/docs/oauth-server.md
new file mode 100644
index 000000000..22cba25df
--- /dev/null
+++ b/docs/oauth-server.md
@@ -0,0 +1,148 @@
+# Using OAuth 2.0 for Server to Server Applications
+
+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 service account, 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.)
+
+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 [Google Cloud Datastore](https://cloud.google.com/datastore/) for data persistence would use a service account to authenticate its calls to the Google Cloud Datastore API.
+
+If you have a G Suite domain—if you use [G Suite](https://gsuite.google.com/), for example—an administrator of the G Suite domain can authorize an application to access user data on behalf of users in the G Suite domain. For example, an application that uses the [Google Calendar API](Google Calendar API) to add events to the calendars of all users in a G Suite 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.
+
+> **Note:** When you use [G Suite Marketplace](https://www.google.com/enterprise/marketplace/) 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.
+
+> **Note:** 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.
+
+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.
+
+## Overview
+
+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.
+
+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.
+
+Finally, your application can use the access token to call Google APIs.
+
+## Creating a service account
+
+A service account's credentials include a generated email address that is unique, a client ID, and at least one public/private key pair.
+
+If your application runs on Google App Engine, a service account is set up automatically when you create your project.
+
+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 [Preparing an instance to use service accounts](https://cloud.google.com/compute/docs/authentication#using).
+
+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:
+
+1. Open the [**Service accounts** page](https://console.developers.google.com/permissions/serviceaccounts). If prompted, select a project.
+1. Click **Create service account**.
+1. In the **Create service account** window, type a name for the service account, and select **Furnish a new private key**. If you want to [grant G Suite domain-wide authority](https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority) to the service account, also select **Enable G Suite Domain-wide Delegation**. Then click **Create**.
+
+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.
+
+You can return to the [API Console](https://console.developers.google.com/) 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 [Service accounts](https://developers.google.com/console/help/service-accounts) in the API Console help file.
+
+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.
+
+> **Note:** 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.
+
+## Delegating domain-wide authority to the service account
+
+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.
+
+The following steps must be performed by an administrator of the Google Apps domain:
+
+1. Go to your Google Apps domain’s [Admin console](http://admin.google.com/).
+1. Select **Security** from the list of controls. If you don't see **Security** listed, select **More controls** from the gray bar at the bottom of the page, then select **Security** from the list of controls. If you can't see the controls, make sure you're signed in as an administrator for the domain.
+1. Select **Advanced settings** from the list of options.
+1. Select **Manage third party OAuth Client access** in the **Authentication** section.
+1. In the **Client name** field enter the service account's **Client ID**.
+1. In the **One or More API Scopes** 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: `https://www.googleapis.com/auth/drive`, `https://www.googleapis.com/auth/calendar`.
+1. Click **Authorize**.
+
+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.
+
+## Preparing to make an authorized API call
+
+After you obtain the client email address and private key from the API Console, complete the following steps:
+
+1. Install the required libraries:
+
+ ```sh
+ pip install google-auth google-auth-httplib2 google-api-python-client
+ ```
+
+1. Create a `Credentials` object from the service account's credentials and the scopes your application needs access to. For example:
+
+### Examples
+
+#### Google App Engine standard environment
+
+```py
+from google.auth import app_engine
+
+SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
+
+credentials = app_engine.Credentials(scopes=SCOPES)
+```
+
+> **Note:** 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 [Other platforms](https://developers.google.com/api-client-library/python/auth/service-accounts#jwtsample)).
+
+#### Google Compute Engine
+
+```py
+from google.auth import compute_engine
+
+credentials = compute_engine.Credentials()
+```
+
+You must [configure your Compute Engine instance to allow access to the necessary scopes](https://cloud.google.com/compute/docs/access/create-enable-service-accounts-for-instances#changeserviceaccountandscopes).
+
+> **Note:** 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 [Other platforms](https://developers.google.com/api-client-library/python/auth/service-accounts#jwtsample)). You can use the [application default credentials](https://developers.google.com/accounts/docs/application-default-credentials) to simplify this process.
+
+#### Other Platforms
+
+```py
+from google.oauth2 import service_account
+
+SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
+SERVICE_ACCOUNT_FILE = '/path/to/service.json'
+
+credentials = service_account.Credentials.from_service_account_file(
+ SERVICE_ACCOUNT_FILE, scopes=SCOPES)
+```
+
+Use the `Credentials` object to call Google APIs in your application.
+
+## Calling Google APIs
+
+To call a Google API using the `Credentials` object, complete the following steps:
+
+1. Build a service object for the API that you want to call. You build a a service object by calling the build function with the name and version of the API and the authorized Http object. For example, to call version 1beta3 of the [Cloud SQL Administration API](https://cloud.google.com/sql/docs/admin-api/):
+
+ ```py
+ import googleapiclient.discovery
+
+ sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
+ ```
+
+1. Make requests to the API service using the [interface provided by the service object](https://developers.google.com/api-client-library/python/start/get_started#build). For example, to list the instances of Cloud SQL databases in the example-123 project:
+
+ ```py
+ response = sqladmin.instances().list(project='example-123').execute()
+ ```
+
+## Complete example
+
+The following example prints a JSON-formatted list of Cloud SQL instances in a project.
+
+```py
+from google.oauth2 import service_account
+import googleapiclient.discovery
+
+SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
+SERVICE_ACCOUNT_FILE = '/path/to/service.json'
+
+credentials = service_account.Credentials.from_service_account_file(
+ SERVICE_ACCOUNT_FILE, scopes=SCOPES)
+sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
+response = sqladmin.instances().list(project='exemplary-example-123').execute()
+
+print(response)
+``` \ No newline at end of file
diff --git a/docs/oauth-web.md b/docs/oauth-web.md
new file mode 100644
index 000000000..0f2c26627
--- /dev/null
+++ b/docs/oauth-web.md
@@ -0,0 +1,54 @@
+# Using OAuth 2.0 for Web Server Applications
+
+This document explains how web server applications use the Google API Client Library for Python 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](service-accounts.md) 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.
+1. Select the project associated with your application. Create a project if you do not have one already.
+1. 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.
+
+<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 &gt; OAuth client ID</b>.</li>
+ <li>Complete the form. Set the application type to <code>Web
+ application</code>. Applications that use languages and frameworks
+ like PHP, Java, Python, Ruby, and .NET must specify authorized
+ <b>redirect URIs</b>. The redirect URIs are the endpoints to which the
+ OAuth 2.0 server can send responses.<br><br>
+ For testing, you can specify URIs that refer to the local machine,
+ such as <code>http://localhost:8080</code>. With that in mind, please
+ note that all of the examples in this document use
+ <code>http://localhost:8080</code> as the redirect URI.
+ <br><br>
+ We recommend that you <a href="#protectauthcode">design your app's auth
+ endpoints</a> so that your application does not expose authorization
+ codes to other resources on the page.</li>
+</ol>
+
+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 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 document](https://developers.google.com/identity/protocols/googlescopes) contains a full list of scopes that you might use to access Google APIs. \ No newline at end of file
diff --git a/docs/oauth.md b/docs/oauth.md
new file mode 100644
index 000000000..947c4ac9d
--- /dev/null
+++ b/docs/oauth.md
@@ -0,0 +1,180 @@
+# OAuth 2.0
+
+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.
+
+## OAuth 2.0 explained
+
+OAuth 2.0 is the authorization protocol used by Google APIs. It is summarized on the [Authentication](auth.md) page of this library's documentation, and there are other good references as well:
+
+* [The OAuth 2.0 Authorization Protocol](https://tools.ietf.org/html/rfc6749)
+* [Using OAuth 2.0 to Access Google APIs](https://developers.google.com/accounts/docs/OAuth2)
+
+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.
+
+## Acquiring client IDs and secrets
+
+You can get client IDs and secrets on the [API Access pane](https://console.developers.google.com/apis/credentials) of the Google APIs Console. There are different 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](https://developers.google.com/accounts/docs/OAuth2ServiceAccount) client IDs
+
+**Warning**: 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.
+
+## The oauth2client library
+
+The [oauth2client](http://oauth2client.readthedocs.org/en/latest/index.html) 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 [package](https://pypi.python.org/pypi/oauth2client) if you only need an OAuth 2.0 library. The sections below describe important modules, classes, and functions of this library.
+
+## Flows
+
+The purpose of a `Flow` 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 `Flow` object has functions that help your application take these steps and acquire credentials. `Flow` objects are only temporary and can be discarded once they have produced credentials, but they can also be [pickled](http://docs.python.org/library/pickle.html) and stored. This section describes the various methods to create and use `Flow` objects.
+
+**Note**: See the [Using Google App Engine](app-engine.md) and [Using Django](django.md) pages for platform-specific Flows.
+
+### flow_from_clientsecrets()
+
+The [oauth2client.client.flow_from_clientsecrets()](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.flow_from_clientsecrets) method creates a `Flow` object from a [client_secrets.json](client_secrets.md) file. This [JSON](http://www.json.org/) formatted file stores your client ID, client secret, and other OAuth 2.0 parameters.
+
+The following shows how you can use `flow_from_clientsecrets()` to create a `Flow` object:
+
+```py
+from oauth2client.client import flow_from_clientsecrets
+...
+flow = flow_from_clientsecrets('path_to_directory/client_secrets.json',
+ scope='https://www.googleapis.com/auth/calendar',
+ redirect_uri='http://example.com/auth_return')
+```
+
+### OAuth2WebServerFlow
+
+Despite its name, the [oauth2client.client.OAuth2WebServerFlow](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.OAuth2WebServerFlow) 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 `redirect_uri` parameter. This must be a URI handled by your application.
+
+```py
+from oauth2client.client import OAuth2WebServerFlow
+...
+flow = OAuth2WebServerFlow(client_id='your_client_id',
+ client_secret='your_client_secret',
+ scope='https://www.googleapis.com/auth/calendar',
+ redirect_uri='http://example.com/auth_return')
+```
+
+### step1_get_authorize_url()
+
+The [step1_get_authorize_url()](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.OAuth2WebServerFlow.step1_get_authorize_url) function of the `Flow` 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:
+
+```py
+auth_uri = flow.step1_get_authorize_url()
+# Redirect the user to auth_uri on your platform.
+```
+
+If the user has previously granted your application access, the authorization server immediately redirects again to `redirect_uri`. 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 `redirect_uri` with a `code` query string parameter similar to the following:
+
+`http://example.com/auth_return/?code=kACAH-1Ng1MImB...AA7acjdY9pTD9M`
+
+If they deny access, they get redirected to `redirect_uri` with an `error` query string parameter similar to the following:
+
+`http://example.com/auth_return/?error=access_denied`
+
+### step2_exchange()
+
+The [step2_exchange()](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.OAuth2WebServerFlow.step2_exchange) function of the `Flow` class exchanges an authorization code for a `Credentials` object. Pass the `code` provided by the authorization server redirection to this function:
+
+```py
+credentials = flow.step2_exchange(code)
+```
+
+## Credentials
+
+A `Credentials` object holds refresh and access tokens that authorize access to a single user's data. These objects are applied to `httplib2.Http` 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 `Credentials` objects.
+
+**Note**: See the [Using Google App Engine](google-app-engine.md) and [Using Django](django.md) pages for platform-specific Credentials.
+
+### OAuth2Credentials
+
+The [oauth2client.client.OAuth2Credentials](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.OAuth2Credentials) 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 `Flow` object can create one for you.
+
+### ServiceAccountCredentials
+
+The [oauth2client.service_account.ServiceAccountCredentials](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.service_account.html) class is only used with [OAuth 2.0 Service Accounts](https://developers.google.com/accounts/docs/OAuth2ServiceAccount). No end-user is involved for these server-to-server API calls, so you can create this object directly without using a `Flow` object.
+
+### AccessTokenCredentials
+
+The [oauth2client.client.AccessTokenCredentials](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.AccessTokenCredentials) class is used when you have already obtained an access token by some other means. You can create this object directly without using a `Flow` object.
+
+### authorize()
+
+Use the [authorize()](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.Credentials.authorize) function of the `Credentials` class to apply necessary credential headers to all requests made by an [httplib2.Http](http://bitworking.org/projects/httplib2/doc/html/libhttplib2.html#httplib2.Http) instance:
+
+```py
+import httplib2
+...
+http = httplib2.Http()
+http = credentials.authorize(http)
+```
+
+Once an `httplib2.Http` object has been authorized, it is typically passed to the build function:
+
+```py
+from apiclient.discovery import build
+...
+service = build('calendar', 'v3', http=http)
+```
+
+## Storage
+
+A [oauth2client.client.Storage](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.client.html#oauth2client.client.Storage) object stores and retrieves `Credentials` objects. This section describes the various methods to create and use `Storage` objects.
+
+**Note**: See the [Using Google App Engine](app-engine.md) and [Using Django](django.md) pages for platform-specific Storage.
+
+### file.Storage
+
+The [oauth2client.file.Storage](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.file.html#oauth2client.file.Storage) class stores and retrieves a single `Credentials` 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 `Credentials` to it, and retrieve those credentials:
+
+```py
+from oauth2client.file import Storage
+...
+storage = Storage('_a_credentials_file_')
+storage.put(credentials)
+...
+credentials = storage.get()
+```
+
+### multistore_file
+
+The [oauth2client.contrib.multistore_file](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.contrib.multistore_file.html) module allows multiple credentials to be stored. The credentials are keyed off of:
+
+* client ID
+* user agent
+* scope
+
+### keyring_storage
+
+The [oauth2client.contrib.keyring_storage](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.contrib.keyring_storage.html) module allows a single `Credentials` object to be stored in a [password manager](http://en.wikipedia.org/wiki/Password_manager) if one is available. The credentials are keyed off of:
+
+* Name of the client application
+* User name
+
+```py
+from oauth2client.contrib.keyring_storage import Storage
+...
+storage = Storage('_application name_', '_user name_')
+storage.put(credentials)
+...
+credentials = storage.get()
+```
+
+## Command-line tools
+
+The [oauth2client.tools.run_flow()](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.tools.html#oauth2client.tools.run_flow) function can be used by command-line applications to acquire credentials. It takes a `Flow` 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 `Storage` argument, which updates the file associated with the `Storage` object.
+
+The [oauth2client.tools.run_flow()](http://oauth2client.readthedocs.org/en/latest/source/oauth2client.tools.html#oauth2client.tools.run_flow) function is controlled by command-line flags, and the Python standard library [argparse](http://docs.python.org/dev/library/argparse.html) module must be initialized at the start of your program. Argparse is included in Python 2.7+, and is available as a [separate package](https://pypi.python.org/pypi/argparse) for older versions. The following shows an example of how to use this function:
+
+```py
+import argparse
+from oauth2client import tools
+
+parser = argparse.ArgumentParser(parents=[tools.argparser])
+flags = parser.parse_args()
+...
+credentials = tools.run_flow(flow, storage, flags)
+``` \ No newline at end of file
diff --git a/docs/pagination.md b/docs/pagination.md
new file mode 100644
index 000000000..b34ede9b2
--- /dev/null
+++ b/docs/pagination.md
@@ -0,0 +1,21 @@
+# Pagination
+
+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 `list()`, there may also be a method named `list_next()`. These methods can be found in the API's PyDoc documentation on the [Supported APIs page](https://developers.google.com/api-client-library/python/apis/).
+
+To process the first page of results, create a request object and call `execute()` as you normally would. For further pages, you call the corresponding `method_name_next()` method, and pass it the previous request and response. Continue paging until `method_name_next()` returns None.
+
+In the following code snippet, the paginated results of a Google Plus activities `list()` method are processed:
+
+```py
+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.
diff --git a/docs/performance.md b/docs/performance.md
new file mode 100644
index 000000000..39b83326c
--- /dev/null
+++ b/docs/performance.md
@@ -0,0 +1,48 @@
+# Performance Tips
+
+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 [Performance Tips page for the Google Drive API](https://developers.google.com/drive/performance).
+
+## About gzip
+
+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.
+
+## Partial response (fields parameter)
+
+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 _partial response_ instead.
+
+To request a partial response, add the standard `fields` 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.
+
+In the following code snippet, the `list` method of a fictitious stamps API is called. The `cents` parameter is defined by the API to only return stamps with the given value. The value of the `fields` 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:
+
+```py
+response = service.stamps.list(cents=5, fields='count,items/name').execute()
+```
+
+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 `fields` parameter, and you should see the "Performance Tips" page in the documentation for the API you are using.
+
+## Partial update (patch)
+
+If the API you are calling supports patch, you can avoid sending unnecessary data when modifying resources. For these APIs, you can call the `patch()` method and supply the arguments you wish to modify for the resource. If supported, the API's PyDoc will have documentation for the `patch()` method.
+
+For more information about patch semantics, see the "Performance Tips" page in the documentation for the API you are using.
+
+## Cache
+
+You should turn on caching at the `httplib2` level. The cache will store `ETags` associated with a resource and use them during future fetches and updates of the same resource.
+
+To enable caching, pass in a cache implementation to the `httplib2.Http` constructor. In the simplest case, you can just pass in a directory name, and a cache will be built from that directory:
+
+```py
+http = httplib2.Http(cache=".cache")
+```
+
+On App Engine you can use memcache as a cache object:
+
+```py
+from google.appengine.api import memcache
+http = httplib2.Http(cache=memcache)
+```
+
+## Batch
+
+If you are sending many small requests you may benefit from [batching](batch.md), which allows those requests to be bundled into a single HTTP request.
diff --git a/docs/start.md b/docs/start.md
new file mode 100644
index 000000000..e8b67d767
--- /dev/null
+++ b/docs/start.md
@@ -0,0 +1,422 @@
+# 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 APIs Console project, read the [Managing Projects page](http://developers.google.com/console/help/managing-projects) and create a project in the [Google API Console](https://console.developers.google.com/).
+3. [Install](http://developers.google.com/api-client-library/python/start/installation) 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.
+
+**API key**: To authenticate your application, use an [API key](https://cloud.google.com/docs/authentication/api-keys) 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](https://developers.google.com/identity/protocols/OAuth2) and libraries written for it.
+
+* **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](https://developers.google.com/identity/protocols/OAuth2ServiceAccount) client IDs
+
+ > **Warning**: Keep your client secret private. If someone obtains your client secret, they could use it to consume your quota, incur charges against your Google Cloud project, and request access to user data.
+
+## Building and calling a service
+
+This section describes how to build an API-specific service object, make calls to the service, and process the response.
+
+### Build the service object
+
+Whether you are using simple or authorized API access, you use the [build()](http://google.github.io/google-api-python-client/docs/epy/googleapiclient.discovery-module.html#build) function to create a service object. It takes an API name and API version as arguments. You can see the list of all API versions on the [Supported APIs](http://developers.google.com/api-client-library/python/apis/) page. The service object is constructed with methods specific to the given API. To create it, do the following:
+
+```py
+from apiclient.discovery import build
+service = build('api_name', 'api_version', ...)
+```
+
+### Collections
+
+Each API service provides access to one or more resources. A set of resources of the same type is called a collection. The names of these collections are specific to the API. The service object is constructed with a function for every collection defined by the API. If the given API has a collection named `stamps`, you create the collection object like this:
+
+```py
+collection = service.stamps()
+```
+
+It is also possible for collections to be nested:
+
+```py
+nested_collection = service.featured().stamps()
+```
+
+### Methods and requests
+
+Every collection has a list of methods defined by the API. Calling a collection's method returns an [HttpRequest](http://google.github.io/google-api-python-client/docs/epy/googleapiclient.http.HttpRequest-class.html) object. If the given API collection has a method named `list` that takes an argument called `cents`, you create a request object for that method like this:
+
+```py
+request = collection.list(cents=5)
+```
+
+### Execution and response
+
+Creating a request does not actually call the API. To execute the request and get a response, call the `execute()` function:
+
+```py
+response = request.execute()
+```
+
+Alternatively, you can combine previous steps on a single line:
+
+```py
+response = service.stamps().list(cents=5).execute()
+```
+
+### Working with the response
+
+The response is a Python object built from the JSON response sent by the API server. The JSON structure is specific to the API; for details, see the API's reference documentation. You can also simply print the JSON to see the structure:
+
+```py
+import json
+...
+print json.dumps(response, sort_keys=True, indent=4)
+```
+
+For example, if the printed JSON is the following:
+
+```json
+{
+ "count": 2,
+ "items": [
+ {
+ "cents": 5,
+ "name": "#586 1923-26 5-cent blue Theodore Roosevelt MLH perf 10"
+ },
+ {
+ "cents": 5,
+ "name": "#628 1926 5-cent Ericsson Memorial MLH"
+ }
+ ]
+}
+```
+
+You can access the data like this:
+
+```py
+print 'Num 5 cent stamps: %d' % response['count']
+print 'First stamp name: %s' % response['items'][0]['name']
+```
+
+## Examples
+
+In this section, we provide examples of each access type and application type.
+
+### Authorized API for web application example
+
+For this example, we use authorized API access for a simple web server. It calls the [Google Calendar API](http://developers.google.com/google-apps/calendar/) to list a user's calendar events. Python's built-in [BaseHTTPServer](http://docs.python.org/2/library/basehttpserver.html) is used to create the server. Actual production code would normally use a more sophisticated web server framework, but the simplicity of `BaseHTTPServer` allows the example to focus on using this library.
+
+#### Setup for example
+
+1. **Activate the Calendar API**: [Read about API activation](http://developers.google.com/console/help/activating-apis) and activate the Calendar API.
+2. **Get your client ID and client secret**: Get a client ID and secret for _web applications_. Use `http://localhost` as your domain. After creating the client ID, edit the _Redirect URIs_ field to contain only `http://localhost:8080/`.
+3. **Create calendar events**: In this example, user calendar events will be read. You can use any Google account you own, including the account associated with the application's Google APIs Console project. For the target user, create a few calendar events if none exist already.
+
+#### Code for example
+
+This script is well commented to explain each step.
+
+```py
+#!/usr/bin/python
+import BaseHTTPServer
+import Cookie
+import httplib2
+import StringIO
+import urlparse
+import sys
+
+from apiclient.discovery import build
+from oauth2client.client import AccessTokenRefreshError
+from oauth2client.client import OAuth2WebServerFlow
+from oauth2client.file import Storage
+
+class RequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
+ """Child class of BaseHTTPRequestHandler that only handles GET request."""
+
+ # Create a flow object. This object holds the client_id, client_secret, and
+ # scope. It assists with OAuth 2.0 steps to get user authorization and
+ # credentials. For this example, the client ID and secret are command-line
+ # arguments.
+ flow = OAuth2WebServerFlow(sys.argv[1],
+ sys.argv[2],
+ 'https://www.googleapis.com/auth/calendar',
+ redirect_uri='http://localhost:8080/')
+
+ def do_GET(self):
+ """Handler for GET request."""
+ print '\nNEW REQUEST, Path: %s' % (self.path)
+ print 'Headers: %s' % self.headers
+
+ # To use this server, you first visit
+ # http://localhost:8080/?fake_user=<some_user_name>. You can use any name you
+ # like for the fake_user. It's only used as a key to store credentials,
+ # and has no relationship with real user names. In a real system, you would
+ # only use logged-in users for your system.
+ if self.path.startswith('/?fake_user='):
+ # Initial page entered by user
+ self.handle_initial_url()
+
+ # When you redirect to the authorization server below, it redirects back
+ # to to http://localhost:8080/?code=<some_code> after the user grants access
+ # permission for your application.
+ elif self.path.startswith('/?code='):
+ # Page redirected back from auth server
+ self.handle_redirected_url()
+ # Only the two URL patterns above are accepted by this server.
+ else:
+ # Either an error from auth server or bad user entered URL.
+ self.respond_ignore()
+
+ def handle_initial_url(self):
+ """Handles the initial path."""
+ # The fake user name should be in the URL query parameters.
+ fake_user = self.get_fake_user_from_url_param()
+
+ # Call a helper function defined below to get the credentials for this user.
+ credentials = self.get_credentials(fake_user)
+
+ # If there are no credentials for this fake user or they are invalid,
+ # we need to get new credentials.
+ if credentials is None or credentials.invalid:
+ # Call a helper function defined below to respond to this GET request
+ # with a response that redirects the browser to the authorization server.
+ self.respond_redirect_to_auth_server(fake_user)
+ else:
+ try:
+ # Call a helper function defined below to get calendar data for this
+ # user.
+ calendar_output = self.get_calendar_data(credentials)
+
+ # Call a helper function defined below which responds to this
+ # GET request with data from the calendar.
+ self.respond_calendar_data(calendar_output)
+ except AccessTokenRefreshError:
+ # This may happen when access tokens expire. Redirect the browser to
+ # the authorization server
+ self.respond_redirect_to_auth_server(fake_user)
+
+ def handle_redirected_url(self):
+ """Handles the redirection back from the authorization server."""
+ # The server should have responded with a "code" URL query parameter. This
+ # is needed to acquire credentials.
+ code = self.get_code_from_url_param()
+
+ # Before we redirected to the authorization server, we set a cookie to save
+ # the fake user for retrieval when handling the redirection back to this
+ # server. This is only needed because we are using this fake user
+ # name as a key to access credentials.
+ fake_user = self.get_fake_user_from_cookie()
+
+ #
+ # This is an important step.
+ #
+ # We take the code provided by the authorization server and pass it to the
+ # flow.step2_exchange() function. This function contacts the authorization
+ # server and exchanges the "code" for credentials.
+ credentials = RequestHandler.flow.step2_exchange(code)
+
+ # Call a helper function defined below to save these credentials.
+ self.save_credentials(fake_user, credentials)
+
+ # Call a helper function defined below to get calendar data for this user.
+ calendar_output = self.get_calendar_data(credentials)
+
+ # Call a helper function defined below which responds to this GET request
+ # with data from the calendar.
+ self.respond_calendar_data(calendar_output)
+
+ def respond_redirect_to_auth_server(self, fake_user):
+ """Respond to the current request by redirecting to the auth server."""
+ #
+ # This is an important step.
+ #
+ # We use the flow object to get an authorization server URL that we should
+ # redirect the browser to. We also supply the function with a redirect_uri.
+ # When the auth server has finished requesting access, it redirects
+ # back to this address. Here is pseudocode describing what the auth server
+ # does:
+ # if (user has already granted access):
+ # Do not ask the user again.
+ # Redirect back to redirect_uri with an authorization code.
+ # else:
+ # Ask the user to grant your app access to the scope and service.
+ # if (the user accepts):
+ # Redirect back to redirect_uri with an authorization code.
+ # else:
+ # Redirect back to redirect_uri with an error code.
+ uri = RequestHandler.flow.step1_get_authorize_url()
+
+ # Set the necessary headers to respond with the redirect. Also set a cookie
+ # to store our fake_user name. We will need this when the auth server
+ # redirects back to this server.
+ print 'Redirecting %s to %s' % (fake_user, uri)
+ self.send_response(301)
+ self.send_header('Cache-Control', 'no-cache')
+ self.send_header('Location', uri)
+ self.send_header('Set-Cookie', 'fake_user=%s' % fake_user)
+ self.end_headers()
+
+ def respond_ignore(self):
+ """Responds to the current request that has an unknown path."""
+ self.send_response(200)
+ self.send_header('Content-type', 'text/plain')
+ self.send_header('Cache-Control', 'no-cache')
+ self.end_headers()
+ self.wfile.write(
+ 'This path is invalid or user denied access:\n%s\n\n' % self.path)
+ self.wfile.write(
+ 'User entered URL should look like: http://localhost:8080/?fake_user=johndoe')
+
+ def respond_calendar_data(self, calendar_output):
+ """Responds to the current request by writing calendar data to stream."""
+ self.send_response(200)
+ self.send_header('Content-type', 'text/plain')
+ self.send_header('Cache-Control', 'no-cache')
+ self.end_headers()
+ self.wfile.write(calendar_output)
+
+ def get_calendar_data(self, credentials):
+ """Given the credentials, returns calendar data."""
+ output = StringIO.StringIO()
+
+ # Now that we have credentials, calling the API is very similar to
+ # other authorized access examples.
+
+ # Create an httplib2.Http object to handle our HTTP requests, and authorize
+ # it using the credentials.authorize() function.
+ http = httplib2.Http()
+ http = credentials.authorize(http)
+
+ # The apiclient.discovery.build() function returns an instance of an API
+ # service object that can be used to make API calls.
+ # The object is constructed with methods specific to the calendar API.
+ # The arguments provided are:
+ # name of the API ('calendar')
+ # version of the API you are using ('v3')
+ # authorized httplib2.Http() object that can be used for API calls
+ service = build('calendar', 'v3', http=http)
+
+ # The Calendar API's events().list method returns paginated results, so we
+ # have to execute the request in a paging loop. First, build the request
+ # object. The arguments provided are:
+ # primary calendar for user
+ request = service.events().list(calendarId='primary')
+ # Loop until all pages have been processed.
+ while request != None:
+ # Get the next page.
+ response = request.execute()
+ # Accessing the response like a dict object with an 'items' key
+ # returns a list of item objects (events).
+ for event in response.get('items', []):
+ # The event object is a dict object with a 'summary' key.
+ output.write(repr(event.get('summary', 'NO SUMMARY')) + '\n')
+ # Get the next request object by passing the previous request object to
+ # the list_next method.
+ request = service.events().list_next(request, response)
+
+ # Return the string of calendar data.
+ return output.getvalue()
+
+ def get_credentials(self, fake_user):
+ """Using the fake user name as a key, retrieve the credentials."""
+ storage = Storage('credentials-%s.dat' % (fake_user))
+ return storage.get()
+
+ def save_credentials(self, fake_user, credentials):
+ """Using the fake user name as a key, save the credentials."""
+ storage = Storage('credentials-%s.dat' % (fake_user))
+ storage.put(credentials)
+
+ def get_fake_user_from_url_param(self):
+ """Get the fake_user query parameter from the current request."""
+ parsed = urlparse.urlparse(self.path)
+ fake_user = urlparse.parse_qs(parsed.query)['fake_user'][0]
+ print 'Fake user from URL: %s' % fake_user
+ return fake_user
+
+ def get_fake_user_from_cookie(self):
+ """Get the fake_user from cookies."""
+ cookies = Cookie.SimpleCookie()
+ cookies.load(self.headers.get('Cookie'))
+ fake_user = cookies['fake_user'].value
+ print 'Fake user from cookie: %s' % fake_user
+ return fake_user
+
+ def get_code_from_url_param(self):
+ """Get the code query parameter from the current request."""
+ parsed = urlparse.urlparse(self.path)
+ code = urlparse.parse_qs(parsed.query)['code'][0]
+ print 'Code from URL: %s' % code
+ return code
+
+def main():
+ try:
+ server = BaseHTTPServer.HTTPServer(('', 8080), RequestHandler)
+ print 'Starting server. Use Control+C to stop.'
+ server.serve_forever()
+ except KeyboardInterrupt:
+ print 'Shutting down server.'
+ server.socket.close()
+
+if __name__ == '__main__':
+ main()
+```
+
+Note how the Storage object is used to to retrieve and store credentials. If no credentials are found, the `flow.step1_get_authorize_url()` function is used to redirect the user to the authorization server. Once the user has granted access, the authorization server redirects back to the local server with a `code` query parameter. This code is passed to the `flow.step2_exchange()` function, which returns credentials. From that point forward, this script is very similar to the command-line access example above.
+
+#### Run the example
+
+1. Copy the script to an **empty** directory on your computer.
+2. Open a terminal and go to the directory.
+3. Execute the following command to run the local server:
+
+ python authorized_api_web_server_calendar.py your_client_id your_client_secret
+
+4. Open a web browser and log in to your Google account as the target user.
+5. Go to this URL: `http://localhost:8080/?fake_user=target_user_name` replacing `target_user_name` with the user name for the target user.
+6. If this is the first time the target user has accessed this local server, the target user is redirected to the authorization server. The authorization server asks the target user to grant the application access to calendar data. Click the button that allows access.
+7. The authorization server redirects the browser back to the local server.
+8. Calendar events for the target user are listed on the page.
+
+## Django support
+
+This library includes helper classes that simplify use in a [Django](https://www.djangoproject.com/) application. See the [Using Django](http://developers.google.com/api-client-library/python/guide/django) page for details.
+
+## Google App Engine support
+
+This library includes helper classes that simplify use in a [Google App Engine](http://developers.google.com/appengine/) application. See the [Using Google App Engine](http://developers.google.com/api-client-library/python/guide/google_app_engine) page for details.
+
+## Finding information about the APIs
+
+Use the [APIs Explorer](http://developers.google.com/api-client-library/python/reference/apis_explorer) to browse APIs, list available methods, and even try API calls from your browser.
+
+## Library reference documentation
+
+[PyDoc generated documentation](http://developers.google.com/api-client-library/python/reference/pydoc) is available for all modules in this library.
+
+You can get [interactive help](http://developers.google.com/api-client-library/python/reference/interactive_help) on library classes and functions using an interactive Python shell. \ No newline at end of file
diff --git a/docs/thread_safety.md b/docs/thread_safety.md
new file mode 100644
index 000000000..485f74fa7
--- /dev/null
+++ b/docs/thread_safety.md
@@ -0,0 +1,28 @@
+# Thread Safety
+
+This page contains important information about the thread safety of this library.
+
+## The httplib2.Http() objects are not thread-safe
+
+The google-api-python-client library is built on top of the [httplib2](https://github.com/httplib2/httplib2) 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()`.
+
+The easiest way to provide threads with their own `httplib2.Http()` instances is to either override the construction of it within the service object or to pass an instance via the http argument to method calls.
+
+```py
+# Create a new Http() object for every request
+def build_request(http, *args, **kwargs):
+ new_http = httplib2.Http()
+ return apiclient.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)
+```
+
+## Credential Storage objects are thread-safe
+
+All [Storage](https://oauth2client.readthedocs.io/en/latest/source/oauth2client.client.html#oauth2client.client.Storage) objects defined in this library are thread-safe, and multiple processes and threads can operate on a single store.
+
+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.