diff options
author | Sam Chiu <samchiu@google.com> | 2020-04-23 18:36:57 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-04-23 18:36:57 +0000 |
commit | f67aafdbb0042fd485be312caa0522b9bba45362 (patch) | |
tree | 56d1947e247e124556896a7c0669f84df8d63fbd | |
parent | 4fd3d4c4bad3b5edccba7cc76bbde8e29e4c13f2 (diff) | |
parent | 24bd0d3e0d2ed88d452d5d0bbf0c8abb4bb85ed3 (diff) | |
download | google-api-python-client-f67aafdbb0042fd485be312caa0522b9bba45362.tar.gz |
Revert "Upgrade python/google-api-python-client to v1.8.1" am: 31456956be am: 24bd0d3e0d
Change-Id: I19afd47bab82266755654cc7935a1cc9ed3ace67
-rw-r--r-- | .github/ISSUE_TEMPLATE/bug_report.md | 22 | ||||
-rw-r--r-- | .github/PULL_REQUEST_TEMPLATE.md | 7 | ||||
-rw-r--r-- | .github/release-please.yml | 1 | ||||
-rw-r--r-- | .gitignore | 2 | ||||
-rwxr-xr-x | .kokoro/build.sh | 32 | ||||
-rw-r--r-- | .kokoro/common.cfg | 19 | ||||
-rw-r--r-- | .kokoro/continuous/continuous.cfg | 2 | ||||
-rw-r--r-- | .kokoro/presubmit/presubmit.cfg | 2 | ||||
-rwxr-xr-x | .kokoro/release.sh | 34 | ||||
-rw-r--r-- | .kokoro/release/common.cfg | 64 | ||||
-rw-r--r-- | .kokoro/release/release.cfg | 1 | ||||
-rwxr-xr-x | .kokoro/trampoline.sh | 17 | ||||
-rw-r--r-- | .repo-metadata.json | 11 | ||||
-rw-r--r-- | CHANGELOG (renamed from CHANGELOG.md) | 103 | ||||
-rw-r--r-- | METADATA | 6 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | googleapiclient/__init__.py | 2 | ||||
-rw-r--r-- | googleapiclient/discovery.py | 23 | ||||
-rw-r--r-- | googleapiclient/http.py | 28 | ||||
-rw-r--r-- | googleapiclient/model.py | 7 | ||||
-rw-r--r-- | noxfile.py | 78 | ||||
-rw-r--r-- | renovate.json | 5 | ||||
-rw-r--r-- | setup.py | 24 | ||||
-rw-r--r-- | synth.metadata | 12 | ||||
-rw-r--r-- | synth.py | 30 | ||||
-rw-r--r-- | tests/test_discovery.py | 144 | ||||
-rw-r--r-- | tests/test_http.py | 63 | ||||
-rw-r--r-- | tests/test_json_model.py | 6 | ||||
-rw-r--r-- | tox.ini | 24 |
29 files changed, 210 insertions, 563 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 7d3526577..3d44f3e4b 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -11,33 +11,23 @@ Thanks for stopping by to let us know something could be better! Please run down the following list and make sure you've tried the usual "quick fixes": - Search the issues already opened: https://github.com/googleapis/google-api-python-client/issues - - Search StackOverflow: https://stackoverflow.com/questions/tagged/google-cloud-platform+python + - If you have a question, post on Stackoverflow under the `google-api` tag. + - If you are reporting an issue or requesting a feature for a G Suite API, please use their [public issue tracker](https://gsuite-developers.googleblog.com/2017/03/a-new-issue-tracker-for-g-suite.html) If you are still having issues, please be sure to include as much information as possible: #### Environment details - - OS type and version: - - Python version: `python --version` - - pip version: `pip --version` - - `google-api-python-client` version: `pip show google-api-python-client` + - OS: + - Python version: + - pip version: + - `google-api-python-client` version: #### Steps to reproduce 1. ? 2. ? -#### Code example - -```python -# example -``` - -#### Stack trace -``` -# example -``` - Making sure to follow these steps will guarantee the quickest resolution possible. Thanks! diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index 24c6fa88f..000000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,7 +0,0 @@ -Thank you for opening a Pull Request! Before submitting your PR, there are a few things you can do to make sure it goes smoothly: -- [ ] Make sure to open an issue as a [bug/issue](https://github.com/googleapis/google-api-python-client/issues/new/choose) before writing your code! That way we can discuss the change, evaluate designs, and agree on the general idea -- [ ] Ensure the tests and linter pass -- [ ] Code coverage does not decrease (if any source code was changed) -- [ ] Appropriate docs were updated (if necessary) - -Fixes #<issue_number_goes_here> 🦕 diff --git a/.github/release-please.yml b/.github/release-please.yml deleted file mode 100644 index 4507ad059..000000000 --- a/.github/release-please.yml +++ /dev/null @@ -1 +0,0 @@ -releaseType: python diff --git a/.gitignore b/.gitignore index 1637b1d3b..cf2c4a698 100644 --- a/.gitignore +++ b/.gitignore @@ -5,7 +5,7 @@ build/ dist/ # Test files -.nox/ +.tox/ # Coverage files .coverage diff --git a/.kokoro/build.sh b/.kokoro/build.sh index ab8cebb4b..e0c966b5a 100755 --- a/.kokoro/build.sh +++ b/.kokoro/build.sh @@ -1,17 +1,4 @@ #!/bin/bash -# Copyright 2018 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. set -eo pipefail @@ -20,20 +7,7 @@ cd github/google-api-python-client # Disable buffering, so that the logs stream through. export PYTHONUNBUFFERED=1 -# Debug: show build environment -env | grep KOKORO +python3 -m pip install --upgrade tox -# Setup service account credentials. -export GOOGLE_APPLICATION_CREDENTIALS=${KOKORO_GFILE_DIR}/service-account.json - -# Setup project id. -export PROJECT_ID=$(cat "${KOKORO_GFILE_DIR}/project-id.json") - -# Remove old nox -python3.6 -m pip uninstall --yes --quiet nox-automation - -# Install nox -python3.6 -m pip install --upgrade --quiet nox -python3.6 -m nox --version - -python3.6 -m nox +# Run tests +tox diff --git a/.kokoro/common.cfg b/.kokoro/common.cfg new file mode 100644 index 000000000..c21dc6d4f --- /dev/null +++ b/.kokoro/common.cfg @@ -0,0 +1,19 @@ +# Format: //devtools/kokoro/config/proto/build.proto + +# Download trampoline resources. +gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" + +# Use the trampoline script to run in docker. +build_file: "google-api-python-client/.kokoro/trampoline.sh" + +# Configure the docker image for kokoro-trampoline. +env_vars: { + key: "TRAMPOLINE_IMAGE" + value: "gcr.io/cloud-devrel-kokoro-resources/python-multi" +} + +# Tell the trampoline which build file to use. +env_vars: { + key: "TRAMPOLINE_BUILD_FILE" + value: "github/google-api-python-client/.kokoro/build.sh" +} diff --git a/.kokoro/continuous/continuous.cfg b/.kokoro/continuous/continuous.cfg index 8f43917d9..18a4c3532 100644 --- a/.kokoro/continuous/continuous.cfg +++ b/.kokoro/continuous/continuous.cfg @@ -1 +1 @@ -# Format: //devtools/kokoro/config/proto/build.proto
\ No newline at end of file +# Format: //devtools/kokoro/config/proto/build.proto diff --git a/.kokoro/presubmit/presubmit.cfg b/.kokoro/presubmit/presubmit.cfg index 8f43917d9..18a4c3532 100644 --- a/.kokoro/presubmit/presubmit.cfg +++ b/.kokoro/presubmit/presubmit.cfg @@ -1 +1 @@ -# Format: //devtools/kokoro/config/proto/build.proto
\ No newline at end of file +# Format: //devtools/kokoro/config/proto/build.proto diff --git a/.kokoro/release.sh b/.kokoro/release.sh deleted file mode 100755 index b4756d089..000000000 --- a/.kokoro/release.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# https://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -#!/bin/bash - -set -eo pipefail - -# Start the releasetool reporter -python3 -m pip install gcp-releasetool -python3 -m releasetool publish-reporter-script > /tmp/publisher-script; source /tmp/publisher-script - -# Ensure that we have the latest versions of Twine, Wheel, and Setuptools. -python3 -m pip install --upgrade twine wheel setuptools - -# Disable buffering, so that the logs stream through. -export PYTHONUNBUFFERED=1 - -# Move into the package, build the distribution and upload. -TWINE_PASSWORD=$(cat "${KOKORO_KEYSTORE_DIR}/73713_google_cloud_pypi_password") -cd github/google-api-python-client -python3 setup.py sdist bdist_wheel -twine upload --username gcloudpypi --password "${TWINE_PASSWORD}" dist/* diff --git a/.kokoro/release/common.cfg b/.kokoro/release/common.cfg deleted file mode 100644 index 6a8864b88..000000000 --- a/.kokoro/release/common.cfg +++ /dev/null @@ -1,64 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto - -# Build logs will be here -action { - define_artifacts { - regex: "**/*sponge_log.xml" - } -} - -# Download trampoline resources. -gfile_resources: "/bigstore/cloud-devrel-kokoro-resources/trampoline" - -# Use the trampoline script to run in docker. -build_file: "google-api-python-client/.kokoro/trampoline.sh" - -# Configure the docker image for kokoro-trampoline. -env_vars: { - key: "TRAMPOLINE_IMAGE" - value: "gcr.io/cloud-devrel-kokoro-resources/python-multi" -} -env_vars: { - key: "TRAMPOLINE_BUILD_FILE" - value: "github/google-api-python-client/.kokoro/release.sh" -} - -# Fetch the token needed for reporting release status to GitHub -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 73713 - keyname: "yoshi-automation-github-key" - } - } -} - -# Fetch PyPI password -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 73713 - keyname: "google_cloud_pypi_password" - } - } -} - -# Fetch magictoken to use with Magic Github Proxy -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 73713 - keyname: "releasetool-magictoken" - } - } -} - -# Fetch api key to use with Magic Github Proxy -before_action { - fetch_keystore { - keystore_resource { - keystore_config_id: 73713 - keyname: "magic-github-proxy-api-key" - } - } -} diff --git a/.kokoro/release/release.cfg b/.kokoro/release/release.cfg deleted file mode 100644 index 8f43917d9..000000000 --- a/.kokoro/release/release.cfg +++ /dev/null @@ -1 +0,0 @@ -# Format: //devtools/kokoro/config/proto/build.proto
\ No newline at end of file diff --git a/.kokoro/trampoline.sh b/.kokoro/trampoline.sh index e8c4251f3..0efc3be38 100755 --- a/.kokoro/trampoline.sh +++ b/.kokoro/trampoline.sh @@ -12,12 +12,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - set -eo pipefail - -python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" || ret_code=$? - -chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh -${KOKORO_GFILE_DIR}/trampoline_cleanup.sh || true - -exit ${ret_code} +# Always run the cleanup script, regardless of the success of bouncing into +# the container. +function cleanup() { + chmod +x ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh + ${KOKORO_GFILE_DIR}/trampoline_cleanup.sh + echo "cleanup"; +} +trap cleanup EXIT +python3 "${KOKORO_GFILE_DIR}/trampoline_v1.py" diff --git a/.repo-metadata.json b/.repo-metadata.json deleted file mode 100644 index 1b810b0be..000000000 --- a/.repo-metadata.json +++ /dev/null @@ -1,11 +0,0 @@ - -{ - "name": "google-api-python-client", - "name_pretty": "Google API Python Client", - "client_documentation": "https://github.com/googleapis/google-api-python-client/tree/master/docs#google-api-client-library-for-python-docs", - "issue_tracker": "https://github.com/googleapis/google-api-python-client/issues", - "release_level": "ga", - "language": "python", - "repo": "googleapis/google-api-python-client", - "distribution_name": "google-api-python-client" - }
\ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG index b0eb4fb1d..92b744e57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG @@ -1,25 +1,4 @@ -# Changelog - -### [1.8.1](https://www.github.com/googleapis/google-api-python-client/compare/v1.8.0...v1.8.1) (2020-04-20) - - -### Bug Fixes - -* Adding ConnectionError to retry mechanism ([#822](https://www.github.com/googleapis/google-api-python-client/issues/822)) ([c7516a2](https://www.github.com/googleapis/google-api-python-client/commit/c7516a2ea2c229479633690c109f8763dc0b30ed)), closes [googleapis#558](https://www.github.com/googleapis/googleapis/issues/558) -* replace '-' in method names with '_' ([#863](https://www.github.com/googleapis/google-api-python-client/issues/863)) ([8ed729f](https://www.github.com/googleapis/google-api-python-client/commit/8ed729f1d868a8713ab442bf0bf59e77ba36afb6)) - -### v1.8.0 - Version 1.8.0 - - Release to support API endpoint override. - - New Features - - Add api endpoint override. ([#829](https://github.com/googleapis/google-api-python-client/pull/829)) - - Implementation Changes - - Don't set http.redirect_codes if the attr doesn't exist and allow more httplib2 versions. ([#841](https://github.com/googleapis/google-api-python-client/pull/841)) - -### v1.7.12 +v1.7.12 Version 1.7.12 Bugfix release @@ -49,7 +28,7 @@ - Blacken ([#772](https://github.com/googleapis/google-api-python-client/pull/722)) - Move kokoro configs ([#832](https://github.com/googleapis/google-api-python-client/pull/832)) -### v1.7.11 +v1.7.11 Version 1.7.11 Bugfix release @@ -61,7 +40,7 @@ - Fix typo in filename used in 'docs/auth.md' ([#736](https://github.com/googleapis/google-api-python-client/pull/736)) -### v1.7.10 +v1.7.10 Version 1.7.10 Bugfix release @@ -83,21 +62,21 @@ - tox.ini: Look for Python syntax errors and undefined names ([#721](https://github.com/googleapis/google-api-python-client/pull/721)) -### v1.7.9 +v1.7.9 Version 1.7.9 Bugfix release - Remove Django Samples. ([#657](https://github.com/googleapis/google-api-python-client/pull/657)) - Call request_orig with kwargs ([#658](https://github.com/googleapis/google-api-python-client/pull/658)) -### v1.7.8 +v1.7.8 Version 1.7.8 Bugfix release - Convert '$' in method name to '_' ([#616](https://github.com/googleapis/google-api-python-client/pull/616)) - Alias unitest2 import as unittest in test__auth.py ([#613](https://github.com/googleapis/google-api-python-client/pull/613)) -### v1.7.7 +v1.7.7 Version 1.7.7 Bugfix release @@ -110,28 +89,28 @@ - Add badges ([#455](https://github.com/google/google-api-python-client/pull/455)) -### v1.7.6 +v1.7.6 Version 1.7.6 Bugfix release - Add client-side limit for batch requests (#585) -### v1.7.5 +v1.7.5 Version 1.7.5 Bugfix release - Fix the client to respect the passed in developerKey and credentials -### v1.7.4 +v1.7.4 Version 1.7.4 Bugfix release - Catch ServerNotFoundError to retry the request (#532) -### v1.7.3 +v1.7.3 Version 1.7.3 Bugfix release @@ -139,21 +118,21 @@ - Make apiclient.sample_tools gracefully fail to import (#525). -### v1.7.2 +v1.7.2 Version 1.7.2 Bugfix release - Remove unnecessary check in apiclient/__ini__.py (#522). -### v1.7.1 +v1.7.1 Version 1.7.1 Bugfix release - Remove unnecessary check in setup.py (#518). -### v1.7.0 +v1.7.0 Version 1.7.0 This release drops the hard requirement on oauth2client and installs @@ -163,7 +142,7 @@ - Drop oauth2client dependency (#499) - Include tests in source distribution (#514) -### v1.6.7 +v1.6.7 Version 1.6.7 Bugfix release @@ -180,7 +159,7 @@ - discovery.py: remove unused oauth2client import. (#492) - Update README to reference GCP API client libraries. (#490) -### v1.6.6 +v1.6.6 Version 1.6.6 Bugfix release @@ -189,7 +168,7 @@ - Increase the default media chunksize to 100MB. (#482) - Remove unnecessary parsing of mime headers in HttpRequest.__init__ (#467) -### v1.6.5 +v1.6.5 Version 1.6.5 Bugfix release @@ -208,14 +187,14 @@ - Handle variant error format gracefully. (#459) - Avoid testing against Django >= 2.0.0 on Python 2. (#460) -### v1.6.4 +v1.6.4 Version 1.6.4 Bugfix release - Warn when google-auth credentials are used but google-auth-httplib2 isn't available. (#443) -### v1.6.3 +v1.6.3 Version 1.6.3 Bugfix release @@ -231,7 +210,7 @@ - Don't treat httplib2.Credentials as oauth credentials. (#425) - Various fixes to the Django sample. (#413) -### v1.6.2 +v1.6.2 Version 1.6.2 Bugfix release @@ -240,14 +219,14 @@ when a developerKey was specified. (#347) - Official support for Python 3.5 and 3.6. (#341) -### v1.6.1 +v1.6.1 Version 1.6.1 Bugfix release - Fixed a bug where using google-auth with scoped credentials would fail. (#328) -### v1.6.0 +v1.6.0 Version 1.6.0 Release to drop support for Python 2.6 and add support for google-auth. @@ -268,7 +247,7 @@ - Fixed resumable upload failure when receiving a 308 response. (#312) - Clarified the support versions of Python 3. (#316) -### v1.5.5 +v1.5.5 Version 1.5.5 Bugfix release @@ -278,7 +257,7 @@ - Refresh all discovery docs, not just the preferred ones. (#298) - Update minimum httplib2 dependency to >=0.9.2. -### v1.5.4 +v1.5.4 Version 1.5.4 Bugfix release @@ -288,14 +267,14 @@ - Allow oauth2client 4.0.0, with the caveat that file-based discovery caching is disabled. -### v1.5.3 +v1.5.3 Version 1.5.3 Bugfix release - Fixed import error with oauth2client >= 3.0.0. (#270) -### v1.5.2 +v1.5.2 Version 1.5.2 Bugfix release @@ -306,7 +285,7 @@ - Obtain access token if necessary in BatchHttpRequest.execute(). (#232) - Warn when running tests using HttpMock without having a cache. (#261) -### v1.5.1 +v1.5.1 Version 1.5.1 Bugfix release @@ -319,7 +298,7 @@ - Use named loggers instead of the root logger. (#206) - New search console example. (#212) -### v1.5.0 +v1.5.0 Version 1.5.0 Release to support oauth2client >= 2.0.0. @@ -330,22 +309,22 @@ - Handle SSL errors with retries (#160) - Fix incompatibility with oauth2client v2.0.0 (#182) -### v1.4.2 +v1.4.2 Version 1.4.2 Add automatic caching for the discovery docs. -### v1.4.1 +v1.4.1 Version 1.4.1 Add the googleapiclient.discovery.Resource.new_batch_http_request method. -### v1.4.0 +v1.4.0 Version 1.4.0 Python 3 support. -### v1.3.2 +v1.3.2 Version 1.3.2 Small bugfix release. @@ -355,12 +334,12 @@ - Better handling of `content-length` in media requests. - Add support for methodPath entries containing colon. -### v1.3.1 +v1.3.1 Version 1.3.1 Quick release for a fix around aliasing in v1.3. -### v1.3 +v1.3 Version 1.3 Add support for the Google Application Default Credentials. @@ -379,7 +358,7 @@ setup.py attempts to detect this and prevents it. Simply remove the previous version and reinstall to fix this. -### v1.2 +v1.2 Version 1.2 The use of the gflags library is now deprecated, and is no longer a @@ -405,7 +384,7 @@ - Update AdExchange Buyer API examples to version v1.2. -### v1.1 +v1.1 Version 1.1 Add PEM support to SignedJWTAssertionCredentials (used to only support @@ -433,12 +412,12 @@ - Ensure that dataWrapper feature is checked before using the 'data' value. - HMAC verification does not use a constant time algorithm. -### v1.0 +v1.0 Version 1.0 - Changes to the code for running tests and building releases. -### v1.0c3 +v1.0c3 Version 1.0 Release Candidate 3 - In samples and oauth2 decorator, escape untrusted content before displaying it. @@ -461,7 +440,7 @@ - oauth2client support for URL-encoded format of exchange token response (e.g. Facebook) - Build cleaner and easier to read docs for dynamic surfaces. -### v1.0c2 +v1.0c2 Version 1.0 Release Candidate 2 - Parameter values of None should be treated as missing. Fixes issue #144. @@ -469,7 +448,7 @@ - Move all remaining samples over to client_secrets.json. Fixes issue #156. - Make locked_file.py understand win32file primitives for better awesomeness. -### v1.0c1 +v1.0c1 Version 1.0 Release Candidate 1 - Documentation for the library has switched to epydoc: @@ -494,7 +473,7 @@ * new analytics api samples. Reviewed here: http://codereview.appspot.com/5494058/ - Convert all inline samples to the Farm API for consistency. -### v1.0beta8 +v1.0beta8 - Updated meda upload support. - Many fixes for batch requests. - Better handling for requests that don't require a body. @@ -509,7 +488,7 @@ 'body' parameter in your call. The solution is to remove the unneeded body={} parameter. -### v1.0beta7 +v1.0beta7 - Support for batch requests. http://code.google.com/p/google-api-python-client/wiki/Batch - Support for media upload. http://code.google.com/p/google-api-python-client/wiki/MediaUpload - Better handling for APIs that return something other than JSON. @@ -9,10 +9,10 @@ third_party { type: GIT value: "https://github.com/google/google-api-python-client" } - version: "v1.8.1" + version: "v1.7.12" last_upgrade_date { year: 2020 - month: 4 - day: 20 + month: 3 + day: 11 } } @@ -10,14 +10,12 @@ These client libraries are officially supported by Google. However, the librari See the [docs folder](docs/README.md) for more detailed instructions and additional documentation. -## Other Google API libraries +## Google Cloud Platform / Google Ads 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). For Google Ads API, we recommend using [Google Ads API Client Library for Python](https://github.com/googleads/google-ads-python/). -For Google Firebase Admin API, we recommend using [Firebase Admin Python SDK](https://github.com/firebase/firebase-admin-python). - ## Installation Install this library in a [virtualenv](https://virtualenv.pypa.io/en/latest/) using pip. virtualenv is a tool to diff --git a/googleapiclient/__init__.py b/googleapiclient/__init__.py index c9218dd85..140b946fb 100644 --- a/googleapiclient/__init__.py +++ b/googleapiclient/__init__.py @@ -12,6 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. +__version__ = "1.7.12" + # Set default logging handler to avoid "No handler found" warnings. import logging diff --git a/googleapiclient/discovery.py b/googleapiclient/discovery.py index 66d4927aa..87403b9e8 100644 --- a/googleapiclient/discovery.py +++ b/googleapiclient/discovery.py @@ -46,7 +46,6 @@ import re # Third-party imports import httplib2 import uritemplate -import google.api_core.client_options # Local imports from googleapiclient import _auth @@ -131,10 +130,10 @@ def fix_method_name(name): name: string, method name. Returns: - The name with '_' appended if the name is a reserved word and '$' and '-' + The name with '_' appended if the name is a reserved word and '$' replaced with '_'. """ - name = name.replace("$", "_").replace("-", "_") + name = name.replace("$", "_") if keyword.iskeyword(name) or name in RESERVED_WORDS: return name + "_" else: @@ -177,7 +176,6 @@ def build( credentials=None, cache_discovery=True, cache=None, - client_options=None, ): """Construct a Resource for interacting with an API. @@ -204,8 +202,6 @@ def build( cache_discovery: Boolean, whether or not to cache the discovery doc. cache: googleapiclient.discovery_cache.base.CacheBase, an optional cache object for the discovery documents. - client_options: Dictionary or google.api_core.client_options, Client options to set user - options on the client. API endpoint should be set through client_options. Returns: A Resource object with methods for interacting with the service. @@ -232,7 +228,6 @@ def build( model=model, requestBuilder=requestBuilder, credentials=credentials, - client_options=client_options ) except HttpError as e: if e.resp.status == http_client.NOT_FOUND: @@ -309,7 +304,6 @@ def build_from_document( model=None, requestBuilder=HttpRequest, credentials=None, - client_options=None ): """Create a Resource for interacting with an API. @@ -334,8 +328,6 @@ def build_from_document( credentials: oauth2client.Credentials or google.auth.credentials.Credentials, credentials to be used for authentication. - client_options: Dictionary or google.api_core.client_options, Client options to set user - options on the client. API endpoint should be set through client_options. Returns: A Resource object with methods for interacting with the service. @@ -358,16 +350,7 @@ def build_from_document( ) raise InvalidJsonError() - # If an API Endpoint is provided on client options, use that as the base URL - base = urljoin(service['rootUrl'], service["servicePath"]) - if client_options: - if type(client_options) == dict: - client_options = google.api_core.client_options.from_dict( - client_options - ) - if client_options.api_endpoint: - base = client_options.api_endpoint - + base = urljoin(service["rootUrl"], service["servicePath"]) schema = Schemas(service) # If the http client is not specified, then we must construct an http client diff --git a/googleapiclient/http.py b/googleapiclient/http.py index 41256668b..719664de1 100644 --- a/googleapiclient/http.py +++ b/googleapiclient/http.py @@ -81,11 +81,6 @@ DEFAULT_HTTP_TIMEOUT_SEC = 60 _LEGACY_BATCH_URI = "https://www.googleapis.com/batch" -if six.PY2: - # That's a builtin python3 exception, nonexistent in python2. - # Defined to None to avoid NameError while trying to catch it - ConnectionError = None - def _should_retry_response(resp_status, content): """Determines whether a response should be retried. @@ -182,10 +177,6 @@ def _retry_request( # It's important that this be before socket.error as it's a subclass # socket.timeout has no errorcode exception = socket_timeout - except ConnectionError as connection_error: - # Needs to be before socket.error as it's a subclass of - # OSError (socket.error) - exception = connection_error except socket.error as socket_error: # errno's contents differ by platform, so we have to match by name. if socket.errno.errorcode.get(socket_error.errno) not in { @@ -1760,18 +1751,16 @@ class HttpMockSequence(object): connection_type=None, ): resp, content = self._iterable.pop(0) - content = six.ensure_binary(content) - - if content == b"echo_request_headers": + if content == "echo_request_headers": content = headers - elif content == b"echo_request_headers_as_json": + elif content == "echo_request_headers_as_json": content = json.dumps(headers) - elif content == b"echo_request_body": + elif content == "echo_request_body": if hasattr(body, "read"): content = body.read() else: content = body - elif content == b"echo_request_uri": + elif content == "echo_request_uri": content = uri if isinstance(content, six.text_type): content = content.encode("utf-8") @@ -1902,13 +1891,6 @@ def build_http(): # for Resumable Uploads rather than Permanent Redirects. # This asks httplib2 to exclude 308s from the status codes # it treats as redirects - try: - http.redirect_codes = http.redirect_codes - {308} - except AttributeError: - # Apache Beam tests depend on this library and cannot - # currently upgrade their httplib2 version - # http.redirect_codes does not exist in previous versions - # of httplib2, so pass - pass + http.redirect_codes = http.redirect_codes - {308} return http diff --git a/googleapiclient/model.py b/googleapiclient/model.py index f58549c49..554056e3e 100644 --- a/googleapiclient/model.py +++ b/googleapiclient/model.py @@ -27,13 +27,12 @@ __author__ = "jcgregorio@google.com (Joe Gregorio)" import json import logging import platform -import pkg_resources from six.moves.urllib.parse import urlencode +from googleapiclient import __version__ from googleapiclient.errors import HttpError -_LIBRARY_VERSION = pkg_resources.get_distribution("google-api-python-client").version _PY_VERSION = platform.python_version() LOGGER = logging.getLogger(__name__) @@ -153,7 +152,7 @@ class BaseModel(Model): else: headers["x-goog-api-client"] = "" headers["x-goog-api-client"] += "gdcl/%s gl-python/%s" % ( - _LIBRARY_VERSION, + __version__, _PY_VERSION, ) @@ -219,7 +218,7 @@ class BaseModel(Model): return self.no_content_response return self.deserialize(content) else: - LOGGER.debug("Content from bad request was: %r" % content) + LOGGER.debug("Content from bad request was: %s" % content) raise HttpError(resp, content) def serialize(self, body_value): diff --git a/noxfile.py b/noxfile.py deleted file mode 100644 index 438ff41c5..000000000 --- a/noxfile.py +++ /dev/null @@ -1,78 +0,0 @@ - -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import nox - -test_dependencies = [ - "google-auth", - "google-auth-httplib2", - "mox", - "pyopenssl", - "pytest", - "pytest-cov", - "webtest", - "coverage", - "unittest2", - "mock", -] - - -@nox.session(python=["3.7"]) -def lint(session): - session.install("flake8") - session.run( - "flake8", - "googleapiclient", - "tests", - "--count", - "--select=E9,F63,F7,F82", - "--show-source", - "--statistics", - ) - - -@nox.parametrize( - "oauth2client", - [ - "oauth2client<2dev", - "oauth2client>=2,<=3dev", - "oauth2client>=3,<=4dev", - "oauth2client>=4,<=5dev", - ], -) -@nox.session(python=["2.7", "3.5", "3.6", "3.7"]) -def unit(session, oauth2client): - session.install(*test_dependencies) - session.install(oauth2client) - if session.python < "3.0": - session.install("django<2.0.0") - else: - session.install("django>=2.0.0") - - session.install('.') - - # Run py.test against the unit tests. - session.run( - "py.test", - "--quiet", - "--cov=googleapiclient", - "--cov=tests", - "--cov-append", - "--cov-config=.coveragerc", - "--cov-report=", - "--cov-fail-under=85", - "tests", - *session.posargs, - )
\ No newline at end of file diff --git a/renovate.json b/renovate.json deleted file mode 100644 index f45d8f110..000000000 --- a/renovate.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": [ - "config:base" - ] -} @@ -28,40 +28,31 @@ if (3, 1) <= sys.version_info < (3, 4): print("google-api-python-client requires python3 version >= 3.4.", file=sys.stderr) sys.exit(1) -import io -import os from setuptools import setup packages = ["apiclient", "googleapiclient", "googleapiclient/discovery_cache"] install_requires = [ - # NOTE: Apache Beam tests depend on this library and cannot - # currently upgrade their httplib2 version. - # Please see https://github.com/googleapis/google-api-python-client/pull/841 - "httplib2>=0.9.2,<1dev", + "httplib2>=0.17.0,<1dev", "google-auth>=1.4.1", "google-auth-httplib2>=0.0.3", - "google-api-core>=1.13.0,<2dev", "six>=1.6.1,<2dev", "uritemplate>=3.0.0,<4dev", ] -package_root = os.path.abspath(os.path.dirname(__file__)) +long_desc = """The Google API Client for Python is a client library for +accessing the Plus, Moderator, and many other Google APIs.""" -readme_filename = os.path.join(package_root, "README.md") -with io.open(readme_filename, encoding="utf-8") as readme_file: - readme = readme_file.read() +import googleapiclient -version = "1.8.1" +version = googleapiclient.__version__ setup( name="google-api-python-client", version=version, description="Google API Client Library for Python", - long_description=readme, - long_description_content_type='text/markdown', - author="Google LLC", - author_email="googleapis-packages@google.com", + long_description=long_desc, + author="Google Inc.", url="http://github.com/google/google-api-python-client/", install_requires=install_requires, python_requires=">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*", @@ -73,6 +64,7 @@ setup( "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", diff --git a/synth.metadata b/synth.metadata deleted file mode 100644 index d06a0f15b..000000000 --- a/synth.metadata +++ /dev/null @@ -1,12 +0,0 @@ -{ - "updateTime": "2020-03-30T20:47:31.469660Z", - "sources": [ - { - "git": { - "name": "synthtool", - "remote": "https://github.com/googleapis/synthtool.git", - "sha": "f5e8c88d9870d8aa4eb43fa0b39f07e02bfbe4df" - } - } - ] -}
\ No newline at end of file diff --git a/synth.py b/synth.py deleted file mode 100644 index 017717db6..000000000 --- a/synth.py +++ /dev/null @@ -1,30 +0,0 @@ -# Copyright 2020 Google LLC -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import synthtool as s -from synthtool import gcp - -common = gcp.CommonTemplates() - -# ---------------------------------------------------------------------------- -# Add templated files -# ---------------------------------------------------------------------------- -templated_files = common.py_library() - -# Copy kokoro configs. -# Docs are excluded as repo docs cannot currently be generated using sphinx. -s.move(templated_files / '.kokoro', excludes=['**/docs/*', 'publish-docs.sh']) - -# Also move issue templates -s.move(templated_files / '.github')
\ No newline at end of file diff --git a/tests/test_discovery.py b/tests/test_discovery.py index 6400f2147..f85035ef4 100644 --- a/tests/test_discovery.py +++ b/tests/test_discovery.py @@ -466,7 +466,7 @@ class DiscoveryFromDocument(unittest.TestCase): plus = build_from_document( discovery, base=base, credentials=self.MOCK_CREDENTIALS ) - self.assertEqual("https://www.googleapis.com/plus/v1/", plus._baseUrl) + self.assertEquals("https://www.googleapis.com/plus/v1/", plus._baseUrl) def test_building_with_optional_http_with_authorization(self): discovery = open(datafile("plus.json")).read() @@ -503,7 +503,7 @@ class DiscoveryFromDocument(unittest.TestCase): plus = build_from_document( discovery, base="https://www.googleapis.com/", http=http ) - self.assertEqual(plus._http, http) + self.assertEquals(plus._http, http) def test_building_with_developer_key_skips_adc(self): discovery = open(datafile("plus.json")).read() @@ -515,25 +515,6 @@ class DiscoveryFromDocument(unittest.TestCase): # application default credentials were used. self.assertNotIsInstance(plus._http, google_auth_httplib2.AuthorizedHttp) - def test_api_endpoint_override_from_client_options(self): - discovery = open(datafile("plus.json")).read() - api_endpoint = "https://foo.googleapis.com/" - options = google.api_core.client_options.ClientOptions( - api_endpoint=api_endpoint - ) - plus = build_from_document(discovery, client_options=options) - - self.assertEqual(plus._baseUrl, api_endpoint) - - def test_api_endpoint_override_from_client_options_dict(self): - discovery = open(datafile("plus.json")).read() - api_endpoint = "https://foo.googleapis.com/" - plus = build_from_document( - discovery, client_options={"api_endpoint": api_endpoint} - ) - - self.assertEqual(plus._baseUrl, api_endpoint) - class DiscoveryFromHttp(unittest.TestCase): def setUp(self): @@ -607,39 +588,6 @@ class DiscoveryFromHttp(unittest.TestCase): zoo = build("zoo", "v1", http=http, cache_discovery=False) self.assertTrue(hasattr(zoo, "animals")) - def test_api_endpoint_override_from_client_options(self): - http = HttpMockSequence( - [ - ({"status": "404"}, "Not found"), - ({"status": "200"}, open(datafile("zoo.json"), "rb").read()), - ] - ) - api_endpoint = "https://foo.googleapis.com/" - options = google.api_core.client_options.ClientOptions( - api_endpoint=api_endpoint - ) - zoo = build( - "zoo", "v1", http=http, cache_discovery=False, client_options=options - ) - self.assertEqual(zoo._baseUrl, api_endpoint) - - def test_api_endpoint_override_from_client_options_dict(self): - http = HttpMockSequence( - [ - ({"status": "404"}, "Not found"), - ({"status": "200"}, open(datafile("zoo.json"), "rb").read()), - ] - ) - api_endpoint = "https://foo.googleapis.com/" - zoo = build( - "zoo", - "v1", - http=http, - cache_discovery=False, - client_options={"api_endpoint": api_endpoint}, - ) - self.assertEqual(zoo._baseUrl, api_endpoint) - class DiscoveryFromAppEngineCache(unittest.TestCase): def test_appengine_memcache(self): @@ -980,8 +928,8 @@ class Discovery(unittest.TestCase): self.http = HttpMock(datafile("zoo.json"), {"status": "200"}) zoo = build("zoo", "v1", http=self.http) request = zoo.animals().crossbreed(media_body=datafile("small.png")) - self.assertEqual("image/png", request.headers["content-type"]) - self.assertEqual(b"PNG", request.body[1:4]) + self.assertEquals("image/png", request.headers["content-type"]) + self.assertEquals(b"PNG", request.body[1:4]) def test_simple_media_raise_correct_exceptions(self): self.http = HttpMock(datafile("zoo.json"), {"status": "200"}) @@ -1004,8 +952,8 @@ class Discovery(unittest.TestCase): zoo = build("zoo", "v1", http=self.http) request = zoo.animals().insert(media_body=datafile("small.png")) - self.assertEqual("image/png", request.headers["content-type"]) - self.assertEqual(b"PNG", request.body[1:4]) + self.assertEquals("image/png", request.headers["content-type"]) + self.assertEquals(b"PNG", request.body[1:4]) assertUrisEqual( self, "https://www.googleapis.com/upload/zoo/v1/animals?uploadType=media&alt=json", @@ -1025,8 +973,8 @@ class Discovery(unittest.TestCase): request = zoo.animals().insert( media_body=datafile("small-png"), media_mime_type="image/png" ) - self.assertEqual("image/png", request.headers["content-type"]) - self.assertEqual(b"PNG", request.body[1:4]) + self.assertEquals("image/png", request.headers["content-type"]) + self.assertEquals(b"PNG", request.body[1:4]) assertUrisEqual( self, "https://www.googleapis.com/upload/zoo/v1/animals?uploadType=media&alt=json", @@ -1097,13 +1045,13 @@ class Discovery(unittest.TestCase): media_upload = MediaFileUpload(datafile("small.png"), resumable=True) request = zoo.animals().insert(media_body=media_upload, body={}) self.assertTrue(request.headers["content-type"].startswith("application/json")) - self.assertEqual('{"data": {}}', request.body) - self.assertEqual(media_upload, request.resumable) + self.assertEquals('{"data": {}}', request.body) + self.assertEquals(media_upload, request.resumable) - self.assertEqual("image/png", request.resumable.mimetype()) + self.assertEquals("image/png", request.resumable.mimetype()) self.assertNotEquals(request.body, None) - self.assertEqual(request.resumable_uri, None) + self.assertEquals(request.resumable_uri, None) http = HttpMockSequence( [ @@ -1130,32 +1078,32 @@ class Discovery(unittest.TestCase): ) status, body = request.next_chunk(http=http) - self.assertEqual(None, body) + self.assertEquals(None, body) self.assertTrue(isinstance(status, MediaUploadProgress)) - self.assertEqual(0, status.resumable_progress) + self.assertEquals(0, status.resumable_progress) # Two requests should have been made and the resumable_uri should have been # updated for each one. - self.assertEqual(request.resumable_uri, "http://upload.example.com/2") - self.assertEqual(media_upload, request.resumable) - self.assertEqual(0, request.resumable_progress) + self.assertEquals(request.resumable_uri, "http://upload.example.com/2") + self.assertEquals(media_upload, request.resumable) + self.assertEquals(0, request.resumable_progress) # This next chuck call should upload the first chunk status, body = request.next_chunk(http=http) - self.assertEqual(request.resumable_uri, "http://upload.example.com/3") - self.assertEqual(media_upload, request.resumable) - self.assertEqual(13, request.resumable_progress) + self.assertEquals(request.resumable_uri, "http://upload.example.com/3") + self.assertEquals(media_upload, request.resumable) + self.assertEquals(13, request.resumable_progress) # This call will upload the next chunk status, body = request.next_chunk(http=http) - self.assertEqual(request.resumable_uri, "http://upload.example.com/4") - self.assertEqual(media_upload.size() - 1, request.resumable_progress) - self.assertEqual('{"data": {}}', request.body) + self.assertEquals(request.resumable_uri, "http://upload.example.com/4") + self.assertEquals(media_upload.size() - 1, request.resumable_progress) + self.assertEquals('{"data": {}}', request.body) # Final call to next_chunk should complete the upload. status, body = request.next_chunk(http=http) - self.assertEqual(body, {"foo": "bar"}) - self.assertEqual(status, None) + self.assertEquals(body, {"foo": "bar"}) + self.assertEquals(status, None) def test_resumable_media_good_upload(self): """Not a multipart upload.""" @@ -1164,12 +1112,12 @@ class Discovery(unittest.TestCase): media_upload = MediaFileUpload(datafile("small.png"), resumable=True) request = zoo.animals().insert(media_body=media_upload, body=None) - self.assertEqual(media_upload, request.resumable) + self.assertEquals(media_upload, request.resumable) - self.assertEqual("image/png", request.resumable.mimetype()) + self.assertEquals("image/png", request.resumable.mimetype()) - self.assertEqual(request.body, None) - self.assertEqual(request.resumable_uri, None) + self.assertEquals(request.body, None) + self.assertEquals(request.resumable_uri, None) http = HttpMockSequence( [ @@ -1195,26 +1143,26 @@ class Discovery(unittest.TestCase): ) status, body = request.next_chunk(http=http) - self.assertEqual(None, body) + self.assertEquals(None, body) self.assertTrue(isinstance(status, MediaUploadProgress)) - self.assertEqual(13, status.resumable_progress) + self.assertEquals(13, status.resumable_progress) # Two requests should have been made and the resumable_uri should have been # updated for each one. - self.assertEqual(request.resumable_uri, "http://upload.example.com/2") + self.assertEquals(request.resumable_uri, "http://upload.example.com/2") - self.assertEqual(media_upload, request.resumable) - self.assertEqual(13, request.resumable_progress) + self.assertEquals(media_upload, request.resumable) + self.assertEquals(13, request.resumable_progress) status, body = request.next_chunk(http=http) - self.assertEqual(request.resumable_uri, "http://upload.example.com/3") - self.assertEqual(media_upload.size() - 1, request.resumable_progress) - self.assertEqual(request.body, None) + self.assertEquals(request.resumable_uri, "http://upload.example.com/3") + self.assertEquals(media_upload.size() - 1, request.resumable_progress) + self.assertEquals(request.body, None) # Final call to next_chunk should complete the upload. status, body = request.next_chunk(http=http) - self.assertEqual(body, {"foo": "bar"}) - self.assertEqual(status, None) + self.assertEquals(body, {"foo": "bar"}) + self.assertEquals(status, None) def test_resumable_media_good_upload_from_execute(self): """Not a multipart upload.""" @@ -1253,7 +1201,7 @@ class Discovery(unittest.TestCase): ) body = request.execute(http=http) - self.assertEqual(body, {"foo": "bar"}) + self.assertEquals(body, {"foo": "bar"}) def test_resumable_media_fail_unknown_response_code_first_request(self): """Not a multipart upload.""" @@ -1299,7 +1247,7 @@ class Discovery(unittest.TestCase): ) status, body = request.next_chunk(http=http) - self.assertEqual( + self.assertEquals( status.resumable_progress, 7, "Should have first checked length and then tried to PUT more.", @@ -1623,9 +1571,9 @@ class Discovery(unittest.TestCase): media_upload = MediaFileUpload(datafile("empty"), resumable=True) request = zoo.animals().insert(media_body=media_upload, body=None) - self.assertEqual(media_upload, request.resumable) - self.assertEqual(request.body, None) - self.assertEqual(request.resumable_uri, None) + self.assertEquals(media_upload, request.resumable) + self.assertEquals(request.body, None) + self.assertEquals(request.resumable_uri, None) http = HttpMockSequence( [ @@ -1642,9 +1590,9 @@ class Discovery(unittest.TestCase): ) status, body = request.next_chunk(http=http) - self.assertEqual(None, body) + self.assertEquals(None, body) self.assertTrue(isinstance(status, MediaUploadProgress)) - self.assertEqual(0, status.progress()) + self.assertEquals(0, status.progress()) class Next(unittest.TestCase): diff --git a/tests/test_http.py b/tests/test_http.py index 2c0756e6c..2bf5060c0 100644 --- a/tests/test_http.py +++ b/tests/test_http.py @@ -132,31 +132,32 @@ class HttpMockWithErrors(object): def request(self, *args, **kwargs): if not self.num_errors: return httplib2.Response(self.success_json), self.success_data - elif self.num_errors == 5 and PY3: - ex = ConnectionResetError # noqa: F821 - elif self.num_errors == 4: - ex = httplib2.ServerNotFoundError() - elif self.num_errors == 3: - ex = socket.error() - ex.errno = socket.errno.EPIPE - elif self.num_errors == 2: - ex = ssl.SSLError() else: - # Initialize the timeout error code to the platform's error code. - try: - # For Windows: - ex = socket.error() - ex.errno = socket.errno.WSAETIMEDOUT - except AttributeError: - # For Linux/Mac: - if PY3: - ex = socket.timeout() - else: + self.num_errors -= 1 + if self.num_errors == 1: # initial == 2 + raise ssl.SSLError() + if self.num_errors == 3: # initial == 4 + raise httplib2.ServerNotFoundError() + else: # initial != 2,4 + if self.num_errors == 2: + # first try a broken pipe error (#218) ex = socket.error() - ex.errno = socket.errno.ETIMEDOUT - - self.num_errors -= 1 - raise ex + ex.errno = socket.errno.EPIPE + else: + # Initialize the timeout error code to the platform's error code. + try: + # For Windows: + ex = socket.error() + ex.errno = socket.errno.WSAETIMEDOUT + except AttributeError: + # For Linux/Mac: + if PY3: + ex = socket.timeout() + else: + ex = socket.error() + ex.errno = socket.errno.ETIMEDOUT + # Now raise the correct error. + raise ex class HttpMockWithNonRetriableErrors(object): @@ -561,14 +562,14 @@ class TestMediaIoBaseDownload(unittest.TestCase): def test_media_io_base_download_retries_connection_errors(self): self.request.http = HttpMockWithErrors( - 5, {"status": "200", "content-range": "0-2/3"}, b"123" + 4, {"status": "200", "content-range": "0-2/3"}, b"123" ) download = MediaIoBaseDownload(fd=self.fd, request=self.request, chunksize=3) download._sleep = lambda _x: 0 # do nothing download._rand = lambda: 10 - status, done = download.next_chunk(num_retries=5) + status, done = download.next_chunk(num_retries=4) self.assertEqual(self.fd.getvalue(), b"123") self.assertEqual(True, done) @@ -898,13 +899,13 @@ class TestHttpRequest(unittest.TestCase): def test_retry_connection_errors_non_resumable(self): model = JsonModel() request = HttpRequest( - HttpMockWithErrors(5, {"status": "200"}, '{"foo": "bar"}'), + HttpMockWithErrors(4, {"status": "200"}, '{"foo": "bar"}'), model.response, u"https://www.example.com/json_api_endpoint", ) request._sleep = lambda _x: 0 # do nothing request._rand = lambda: 10 - response = request.execute(num_retries=5) + response = request.execute(num_retries=4) self.assertEqual({u"foo": u"bar"}, response) def test_retry_connection_errors_resumable(self): @@ -917,7 +918,7 @@ class TestHttpRequest(unittest.TestCase): request = HttpRequest( HttpMockWithErrors( - 5, {"status": "200", "location": "location"}, '{"foo": "bar"}' + 4, {"status": "200", "location": "location"}, '{"foo": "bar"}' ), model.response, u"https://www.example.com/file_upload", @@ -926,7 +927,7 @@ class TestHttpRequest(unittest.TestCase): ) request._sleep = lambda _x: 0 # do nothing request._rand = lambda: 10 - response = request.execute(num_retries=5) + response = request.execute(num_retries=4) self.assertEqual({u"foo": u"bar"}, response) def test_retry(self): @@ -1121,7 +1122,7 @@ class TestBatch(unittest.TestCase): def test_id_to_from_content_id_header(self): batch = BatchHttpRequest() - self.assertEqual("12", batch._header_to_id(batch._id_to_header("12"))) + self.assertEquals("12", batch._header_to_id(batch._id_to_header("12"))) def test_invalid_content_id_header(self): batch = BatchHttpRequest() @@ -1645,7 +1646,7 @@ class TestHttpBuild(unittest.TestCase): def test_build_http_default_timeout_can_be_set_to_zero(self): socket.setdefaulttimeout(0) http = build_http() - self.assertEqual(http.timeout, 0) + self.assertEquals(http.timeout, 0) def test_build_http_default_308_is_excluded_as_redirect(self): http = build_http() diff --git a/tests/test_json_model.py b/tests/test_json_model.py index 68578039e..0064f3fd7 100644 --- a/tests/test_json_model.py +++ b/tests/test_json_model.py @@ -26,19 +26,17 @@ __author__ = "jcgregorio@google.com (Joe Gregorio)" import copy import json import os -import pkg_resources import platform import unittest2 as unittest import httplib2 import googleapiclient.model +from googleapiclient import __version__ from googleapiclient.errors import HttpError from googleapiclient.model import JsonModel from six.moves.urllib.parse import parse_qs -_LIBRARY_VERSION = pkg_resources.get_distribution("google-api-python-client").version - class Model(unittest.TestCase): def test_json_no_body(self): @@ -173,7 +171,7 @@ class Model(unittest.TestCase): headers["x-goog-api-client"], "gccl/1.23.4" + " gdcl/" - + _LIBRARY_VERSION + + __version__ + " gl-python/" + platform.python_version(), ) diff --git a/tox.ini b/tox.ini new file mode 100644 index 000000000..1d9bc1391 --- /dev/null +++ b/tox.ini @@ -0,0 +1,24 @@ +[tox] +envlist = py{27,34,35,36,37}-oauth2client{1,2,3,4} + +[testenv] +deps = + oauth2client1: oauth2client<2dev + oauth2client2: oauth2client>=2,<=3dev + oauth2client3: oauth2client>=3,<=4dev + oauth2client4: oauth2client>=4,<=5dev + google-auth + google-auth-httplib2 + mox + pyopenssl + django<2.0.0; python_version < '3.0.0' + django>=2.0.0; python_version > '3.0.0' + flake8 + webtest + nose + coverage>=3.6,<3.99 + unittest2 + mock +commands = + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + nosetests --with-coverage --cover-package=googleapiclient --nocapture --cover-erase --cover-tests --cover-branches --cover-min-percentage=85 [] |