diff --git a/CHANGELOG.md b/CHANGELOG.md index b0eb4fb1dac..a092ec5de68 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +### [1.8.2](https://www.github.com/googleapis/google-api-python-client/compare/v1.8.1...v1.8.2) (2020-04-21) + + +### Bug Fixes + +* Remove `apiclient.__version__` ([#871](https://www.github.com/googleapis/google-api-python-client/issues/871)) ([c7516a2](https://github.com/googleapis/google-api-python-client/commit/1d8ec6874e1c6081893de7cd7cbc86d1f6580320d)), closes [googleapis#870](https://www.github.com/googleapis/googleapis/issues/870) + + ### [1.8.1](https://www.github.com/googleapis/google-api-python-client/compare/v1.8.0...v1.8.1) (2020-04-20) diff --git a/README.md b/README.md index 1ed3078f635..d1d7d3a618d 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ virtualenv ## 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 +Python 3.5, 3.6 and 3.7, and 3.8 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 diff --git a/apiclient/__init__.py b/apiclient/__init__.py index 38dd24b111c..8d9c4ecb8f3 100644 --- a/apiclient/__init__.py +++ b/apiclient/__init__.py @@ -19,8 +19,6 @@ sample_tools = None from googleapiclient import schema -__version__ = googleapiclient.__version__ - _SUBMODULES = { "channel": channel, "discovery": discovery, diff --git a/describe.py b/describe.py index e36db534d37..c808a3ba414 100755 --- a/describe.py +++ b/describe.py @@ -247,6 +247,12 @@ def method(name, doc): """ params = method_params(doc) + if sys.version_info.major >= 3: + import html + doc = html.escape(doc) + else: + import cgi + doc = cgi.escape(doc) return string.Template(METHOD_TEMPLATE).substitute( name=name, params=params, doc=doc ) @@ -348,7 +354,10 @@ def document_collection_recursive(resource, path, root_discovery, discovery): html = document_collection(resource, path, root_discovery, discovery) f = open(os.path.join(FLAGS.dest, path + "html"), "w") - f.write(html.encode("utf-8")) + if sys.version_info.major < 3: + html = html.encode("utf-8") + + f.write(html) f.close() for name in dir(resource): @@ -450,7 +459,10 @@ def document_api_from_discovery_document(uri): markdown.append("\n") with open("docs/dyn/index.md", "w") as f: - f.write("\n".join(markdown).encode("utf-8")) + markdown = "\n".join(markdown) + if sys.version_info.major < 3: + markdown = markdown.encode("utf-8") + f.write(markdown) else: sys.exit("Failed to load the discovery document.") diff --git a/docs/dyn/index.md b/docs/dyn/index.md index 1c63b5bf936..5fd77fd33ae 100644 --- a/docs/dyn/index.md +++ b/docs/dyn/index.md @@ -1,3 +1,94 @@ +# Index + +[A](#A), [B](#B), [C](#C), [D](#D), [F](#F), [G](#G), [H](#H), [I](#I), [J](#J), [K](#K), [L](#L), [M](#M), [O](#O), [P](#P), [R](#R), [S](#S), [T](#T), [U](#U), [V](#V), [W](#W), [Y](#Y) + +## A + +[abusiveexperiencereport](#abusiveexperiencereport), [acceleratedmobilepageurl](#acceleratedmobilepageurl), [accessapproval](#accessapproval), [accesscontextmanager](#accesscontextmanager), [adexchangebuyer](#adexchangebuyer), [adexchangebuyer2](#adexchangebuyer2), [adexperiencereport](#adexperiencereport), [admin](#admin), [adsense](#adsense), [adsensehost](#adsensehost), [alertcenter](#alertcenter), [analytics](#analytics), [analyticsreporting](#analyticsreporting), [androiddeviceprovisioning](#androiddeviceprovisioning), [androidenterprise](#androidenterprise), [androidmanagement](#androidmanagement), [androidpublisher](#androidpublisher), [appengine](#appengine), [appsactivity](#appsactivity), [appstate](#appstate) + +## B + +[bigquerydatatransfer](#bigquerydatatransfer), [bigtableadmin](#bigtableadmin), [binaryauthorization](#binaryauthorization), [blogger](#blogger), [books](#books) + +## C + +[calendar](#calendar), [chat](#chat), [civicinfo](#civicinfo), [classroom](#classroom), [commentanalyzer](#commentanalyzer), [composer](#composer), [compute](#compute), [container](#container), [containeranalysis](#containeranalysis), [content](#content), [customsearch](#customsearch) + +### Cloud +[cloudasset](#cloudasset), [cloudbilling](#cloudbilling), [cloudbuild](#cloudbuild), [clouddebugger](#clouddebugger), [clouderrorreporting](#clouderrorreporting), [cloudfunctions](#cloudfunctions), [cloudidentity](#cloudidentity), [cloudiot](#cloudiot), [cloudkms](#cloudkms), [cloudprivatecatalog](#cloudprivatecatalog), [cloudprivatecatalogproducer](#cloudprivatecatalogproducer), [cloudprofiler](#cloudprofiler), [cloudresourcemanager](#cloudresourcemanager), [cloudscheduler](#cloudscheduler), [cloudsearch](#cloudsearch), [cloudshell](#cloudshell), [cloudtasks](#cloudtasks), [cloudtrace](#cloudtrace), + +## D + +[dataflow](#dataflow), [datafusion](#datafusion), [dataproc](#dataproc), [datastore](#datastore), [deploymentmanager](#deploymentmanager), [dfareporting](#dfareporting), [dialogflow](#dialogflow), [digitalassetlinks](#digitalassetlinks), [discovery](#discovery), [dlp](#dlp), [dns](#dns), [docs](#docs), [doubleclickbidmanager](#doubleclickbidmanager), [doubleclicksearch](#doubleclicksearch), [drive](#drive), [driveactivity](#driveactivity) + +## F + +[factchecktools](#factchecktools), [fcm](#fcm), [file](#file), [firebase](#firebase), [firebasedynamiclinks](#firebasedynamiclinks), [firebasehosting](#firebasehosting), [firebaserules](#firebaserules), [firestore](#firestore), [fitness](#fitness), [fusiontables](#fusiontables) + +## G + +[games](#games), [gamesConfiguration](#gamesconfiguration), [gamesManagement](#gamesmanagement), [genomics](#genomics), [gmail](#gmail), [groupsmigration](#groupsmigration), [groupssettings](#groupssettings) + +## H + +[healthcare](#healthcare) + +## I + +[iam](#iam), [iamcredentials](#iamcredentials), [iap](#iap), [identitytoolkit](#identitytoolkit), [indexing](#indexing) + +## J + +[jobs](#jobs) + +## K + +[kgsearch](#kgsearch) + +## L + +[language](#language), [libraryagent](#libraryagent), [licensing](#licensing), [logging](#logging) + +## M + +[manufacturers](#manufacturers), [mirror](#mirror), [ml](#ml), [monitoring](#monitoring) + +## O + +[oauth2](#oauth2), [osconfig](#osconfig), [oslogin](#oslogin) + +## P + +[pagespeedonline](#pagespeedonline), [people](#people), [playcustomapp](#playcustomapp), [plus](#plus), [plusDomains](#plusdomains), [poly](#poly), [proximitybeacon](#proximitybeacon), [pubsub](#pubsub) + +## R + +[redis](#redis), [remotebuildexecution](#remotebuildexecution), [replicapool](#replicapool), [reseller](#reseller), [run](#run), [runtimeconfig](#runtimeconfig) + +## S + +[safebrowsing](#safebrowsing), [script](#script), [searchconsole](#searchconsole), [securitycenter](#securitycenter), [servicebroker](#servicebroker), [serviceconsumermanagement](#serviceconsumermanagement), [servicecontrol](#servicecontrol), [servicemanagement](#servicemanagement), [servicenetworking](#servicenetworking), [serviceusage](#serviceusage), [sheets](#sheets), [siteVerification](#siteverification), [slides](#slides), [sourcerepo](#sourcerepo), [spanner](#spanner), [speech](#speech), [sqladmin](#sqladmin), [storage](#storage), [storagetransfer](#storagetransfer), [streetviewpublish](#streetviewpublish), [surveys](#surveys) + +## T + +[tagmanager](#tagmanager), [tasks](#tasks), [testing](#testing), [texttospeech](#texttospeech), [toolresults](#toolresults), [tpu](#tpu), [translate](#translate) + +## U + +[urlshortener](#urlshortener) + +## V + +[vault](#vault), [videointelligence](#videointelligence), [vision](#vision) + +## W + +[webfonts](#webfonts), [webmasters](#webmasters), [websecurityscanner](#websecurityscanner) + +## Y + +[youtube](#youtube), [youtubeAnalytics](#youtubeanalytics), [youtubereporting](#youtubereporting) + ## abusiveexperiencereport * [v1](http://googleapis.github.io/google-api-python-client/docs/dyn/abusiveexperiencereport_v1.html) @@ -727,4 +818,3 @@ ## youtubereporting * [v1](http://googleapis.github.io/google-api-python-client/docs/dyn/youtubereporting_v1.html) - diff --git a/docs/oauth-server.md b/docs/oauth-server.md index cb7b59d20e8..da8509625f7 100644 --- a/docs/oauth-server.md +++ b/docs/oauth-server.md @@ -8,13 +8,13 @@ If you have a G Suite domain—if you use [G Suite](https://gsuite.google.com/), > **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. +> **Note:** Although you can use service accounts in applications that run from a G Suite domain, service accounts are not members of your G Suite account and aren't subject to domain policies set by G Suite administrators. For example, a policy set in the G Suite Admin console to restrict the ability of G Suite end users to share documents outside of the domain would not apply to service accounts. Similarly, that policy would prevent users from sharing documents with service accounts, because service acounts are always outside of the domain. If you're using G Suite domain-wide delegation, this isn't relevant to you - you are accessing APIs while acting as a domain user, not as the service account itself. 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. +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 G Suite 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. @@ -44,19 +44,19 @@ Take note of the service account's email address and store the service account's ## 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. +If your application runs in a G Suite 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: +The following steps must be performed by an administrator of the G Suite domain: -1. Go to your Google Apps domain’s [Admin console](http://admin.google.com/). +1. Go to your G Suite domain’s [Admin console](https://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. 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. +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 in the `subject` argument. ## Preparing to make an authorized API call @@ -110,6 +110,21 @@ credentials = service_account.Credentials.from_service_account_file( Use the `Credentials` object to call Google APIs in your application. +#### Using Domain-wide Delegation + +```python +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, subject='user@domain.com') +``` + +Use the `Credentials` object to call Google APIs in your application. The API requests would be authorized as `user@domain.com`, if you've authorized the service account accordingly in the G Suite Admin console. + + ## Calling Google APIs To call a Google API using the `Credentials` object, complete the following steps: @@ -145,4 +160,4 @@ sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=cr response = sqladmin.instances().list(project='exemplary-example-123').execute() print(response) -``` \ No newline at end of file +``` diff --git a/docs/oauth.md b/docs/oauth.md index 2ce18e18bea..5246948b6a0 100644 --- a/docs/oauth.md +++ b/docs/oauth.md @@ -49,7 +49,7 @@ The example below uses the `Flow` class to handle the installed appplication aut #### from_client_secrets_file() -The [google_auth_oauthlib.Flow.from_client_secrets()](https://google-auth-oauthlib.readthedocs.io/en/latest/reference/google_auth_oauthlib.flow.html#google_auth_oauthlib.flow.Flow.from_client_secrets_file) 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 [google_auth_oauthlib.Flow.from_client_secrets()](https://google-auth-oauthlib.readthedocs.io/en/latest/reference/google_auth_oauthlib.flow.html#google_auth_oauthlib.flow.Flow.from_client_secrets_file) 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 `from_client_secrets_file()` to create a `Flow` object: @@ -138,4 +138,4 @@ service = build('calendar', 'v3', credentials=credentials) `google-auth-oauthlib` does not currently have support for credentials storage. It may be added in the future. See [oauth2client deprecation](https://google-auth.readthedocs.io/en/latest/oauth2client-deprecation.html#replacement) for more details. ## oauth2client deprecation -The [oauth2client](http://oauth2client.readthedocs.org/en/latest/index.html) library was previously recommended for handling the OAuth 2.0 protocol. It is now deprecated, and we recommend `google-auth` and `google-auth-oauthlib`. See [oauth2client deprecation](https://google-auth.readthedocs.io/en/latest/oauth2client-deprecation.html) for more details. \ No newline at end of file +The [oauth2client](http://oauth2client.readthedocs.org/en/latest/index.html) library was previously recommended for handling the OAuth 2.0 protocol. It is now deprecated, and we recommend `google-auth` and `google-auth-oauthlib`. See [oauth2client deprecation](https://google-auth.readthedocs.io/en/latest/oauth2client-deprecation.html) for more details. diff --git a/googleapiclient/errors.py b/googleapiclient/errors.py index 64853a4075e..2f7b112f0d8 100644 --- a/googleapiclient/errors.py +++ b/googleapiclient/errors.py @@ -124,7 +124,7 @@ class MediaUploadSizeError(Error): class ResumableUploadError(HttpError): - """Error occured during resumable upload.""" + """Error occurred during resumable upload.""" pass @@ -142,7 +142,7 @@ class InvalidNotificationError(Error): class BatchError(HttpError): - """Error occured during batch operations.""" + """Error occurred during batch operations.""" @util.positional(2) def __init__(self, reason, resp=None, content=None): diff --git a/googleapiclient/http.py b/googleapiclient/http.py index 41256668b2e..8aec1d51b5a 100644 --- a/googleapiclient/http.py +++ b/googleapiclient/http.py @@ -709,7 +709,7 @@ def next_chunk(self, num_retries=0): Raises: googleapiclient.errors.HttpError if the response was not a 2xx. - httplib2.HttpLib2Error if a transport error has occured. + httplib2.HttpLib2Error if a transport error has occurred. """ headers = self._headers.copy() headers["range"] = "bytes=%d-%d" % ( @@ -860,7 +860,7 @@ def execute(self, http=None, num_retries=0): Raises: googleapiclient.errors.HttpError if the response was not a 2xx. - httplib2.HttpLib2Error if a transport error has occured. + httplib2.HttpLib2Error if a transport error has occurred. """ if http is None: http = self.http @@ -956,7 +956,7 @@ def next_chunk(self, http=None, num_retries=0): Raises: googleapiclient.errors.HttpError if the response was not a 2xx. - httplib2.HttpLib2Error if a transport error has occured. + httplib2.HttpLib2Error if a transport error has occurred. """ if http is None: http = self.http @@ -1419,7 +1419,7 @@ def _execute(self, http, order, requests): request: list, list of request objects to send. Raises: - httplib2.HttpLib2Error if a transport error has occured. + httplib2.HttpLib2Error if a transport error has occurred. googleapiclient.errors.BatchError if the response is the wrong format. """ message = MIMEMultipart("mixed") @@ -1495,7 +1495,7 @@ def execute(self, http=None): None Raises: - httplib2.HttpLib2Error if a transport error has occured. + httplib2.HttpLib2Error if a transport error has occurred. googleapiclient.errors.BatchError if the response is the wrong format. """ # If we have no requests return diff --git a/samples/analytics/management_v3_reference.py b/samples/analytics/management_v3_reference.py index 51bf78d3c1a..afd07fc4da2 100755 --- a/samples/analytics/management_v3_reference.py +++ b/samples/analytics/management_v3_reference.py @@ -98,7 +98,7 @@ def traverse_hiearchy(service): service: The service object built by the Google API Python client library. Raises: - HttpError: If an error occured when accessing the API. + HttpError: If an error occurred when accessing the API. AccessTokenRefreshError: If the current token was invalid. """ diff --git a/setup.py b/setup.py index 60974fbdff4..b00678de60f 100644 --- a/setup.py +++ b/setup.py @@ -52,7 +52,7 @@ with io.open(readme_filename, encoding="utf-8") as readme_file: readme = readme_file.read() -version = "1.8.1" +version = "1.8.2" setup( name="google-api-python-client",