diff --git a/.github/.OwlBot.lock.yaml b/.github/.OwlBot.lock.yaml index f33299dd..8cb43804 100644 --- a/.github/.OwlBot.lock.yaml +++ b/.github/.OwlBot.lock.yaml @@ -1,3 +1,16 @@ +# Copyright 2022 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. docker: image: gcr.io/cloud-devrel-public-resources/owlbot-python:latest - digest: sha256:899d5d7cc340fa8ef9d8ae1a8cfba362c6898584f779e156f25ee828ba824610 + digest: sha256:ed1f9983d5a935a89fe8085e8bb97d94e41015252c5b6c9771257cf8624367e6 diff --git a/.github/release-please.yml b/.github/release-please.yml index 4507ad05..466597e5 100644 --- a/.github/release-please.yml +++ b/.github/release-please.yml @@ -1 +1,2 @@ releaseType: python +handleGHRelease: true diff --git a/.github/release-trigger.yml b/.github/release-trigger.yml new file mode 100644 index 00000000..d4ca9418 --- /dev/null +++ b/.github/release-trigger.yml @@ -0,0 +1 @@ +enabled: true diff --git a/.github/sync-repo-settings.yaml b/.github/sync-repo-settings.yaml index 67fcd59f..49c96ed4 100644 --- a/.github/sync-repo-settings.yaml +++ b/.github/sync-repo-settings.yaml @@ -9,7 +9,8 @@ branchProtectionRules: requiredStatusCheckContexts: - 'cla/google' # No Kokoro: the following are Github actions - - 'lint-mypy' + - 'lint' + - 'mypy' - 'unit-3.6' - 'unit-3.7' - 'unit-3.8' @@ -23,6 +24,8 @@ branchProtectionRules: - 'unit_wo_grpc-3.6' - 'unit_wo_grpc-3.10' - 'cover' + - 'docs' + - 'docfx' permissionRules: - team: actools-python permission: admin diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 00000000..f7b8344c --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,38 @@ +on: + pull_request: + branches: + - main +name: docs +jobs: + docs: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - name: Install nox + run: | + python -m pip install --upgrade setuptools pip wheel + python -m pip install nox + - name: Run docs + run: | + nox -s docs + docfx: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: "3.10" + - name: Install nox + run: | + python -m pip install --upgrade setuptools pip wheel + python -m pip install nox + - name: Run docfx + run: | + nox -s docfx diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml new file mode 100644 index 00000000..79ef73c2 --- /dev/null +++ b/.github/workflows/lint.yml @@ -0,0 +1,25 @@ +on: + pull_request: + branches: + - main +name: lint +jobs: + lint: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: "3.7" + - name: Install nox + run: | + python -m pip install --upgrade setuptools pip wheel + python -m pip install nox + - name: Run lint + run: | + nox -s lint + - name: Run lint_setup_py + run: | + nox -s lint_setup_py diff --git a/.github/workflows/mypy.yml b/.github/workflows/mypy.yml new file mode 100644 index 00000000..f3212da7 --- /dev/null +++ b/.github/workflows/mypy.yml @@ -0,0 +1,22 @@ +on: + pull_request: + branches: + - main +name: mypy +jobs: + mypy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v2 + - name: Setup Python + uses: actions/setup-python@v2 + with: + python-version: "3.7" + - name: Install nox + run: | + python -m pip install --upgrade setuptools pip wheel + python -m pip install nox + - name: Run mypy + run: | + nox -s mypy diff --git a/.github/workflows/unittest_lint.yml b/.github/workflows/unittest.yml similarity index 76% rename from .github/workflows/unittest_lint.yml rename to .github/workflows/unittest.yml index 302be970..9ab0c395 100644 --- a/.github/workflows/unittest_lint.yml +++ b/.github/workflows/unittest.yml @@ -1,44 +1,11 @@ -name: "Lint / Unit tests / Cover / Mypy" +name: "Unit tests" on: pull_request: branches: - main - jobs: - - run-lint-mypy: - name: lint-mypy - runs-on: ubuntu-latest - - steps: - - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup Python - uses: actions/setup-python@v2 - with: - python-version: "3.10" - - - name: Install nox - run: | - python -m pip install --upgrade setuptools pip wheel - python -m pip install nox - - - name: Run lint - run: | - nox -s lint - - - name: Run lint_setup_py - run: | - nox -s lint_setup_py - - - name: Run mypy - run: | - nox -s mypy - run-unittests: name: unit${{ matrix.option }}-${{ matrix.python }} runs-on: ubuntu-latest @@ -58,28 +25,22 @@ jobs: python: 3.8 - option: "_wo_grpc" python: 3.9 - steps: - - name: Checkout uses: actions/checkout@v2 - - name: Setup Python uses: actions/setup-python@v2 with: python-version: ${{ matrix.python }} - - name: Install nox run: | python -m pip install --upgrade setuptools pip wheel python -m pip install nox - - name: Run unit tests env: COVERAGE_FILE: .coverage${{ matrix.option }}-${{matrix.python }} run: | nox -s unit${{ matrix.option }}-${{ matrix.python }} - - name: Upload coverage results uses: actions/upload-artifact@v2 with: @@ -91,28 +52,22 @@ jobs: runs-on: ubuntu-latest needs: - run-unittests - steps: - - name: Checkout uses: actions/checkout@v2 - - name: Setup Python uses: actions/setup-python@v2 with: python-version: "3.10" - - name: Install coverage run: | python -m pip install --upgrade setuptools pip wheel python -m pip install coverage - - name: Download coverage results uses: actions/download-artifact@v2 with: name: coverage-artifacts path: .coverage-results/ - - name: Report coverage results run: | coverage combine .coverage-results/.coverage* diff --git a/.kokoro/release.sh b/.kokoro/release.sh index 0728ce11..a00f93ec 100755 --- a/.kokoro/release.sh +++ b/.kokoro/release.sh @@ -26,7 +26,7 @@ python3 -m pip install --upgrade twine wheel setuptools export PYTHONUNBUFFERED=1 # Move into the package, build the distribution and upload. -TWINE_PASSWORD=$(cat "${KOKORO_GFILE_DIR}/secret_manager/google-cloud-pypi-token") +TWINE_PASSWORD=$(cat "${KOKORO_KEYSTORE_DIR}/73713_google-cloud-pypi-token-keystore-1") cd github/python-api-core python3 setup.py sdist bdist_wheel twine upload --username __token__ --password "${TWINE_PASSWORD}" dist/* diff --git a/.kokoro/release/common.cfg b/.kokoro/release/common.cfg index 586e7649..de4f6f89 100644 --- a/.kokoro/release/common.cfg +++ b/.kokoro/release/common.cfg @@ -23,8 +23,18 @@ env_vars: { value: "github/python-api-core/.kokoro/release.sh" } +# Fetch PyPI password +before_action { + fetch_keystore { + keystore_resource { + keystore_config_id: 73713 + keyname: "google-cloud-pypi-token-keystore-1" + } + } +} + # Tokens needed to report release status back to GitHub env_vars: { key: "SECRET_MANAGER_KEYS" - value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem,google-cloud-pypi-token" + value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem" } diff --git a/CHANGELOG.md b/CHANGELOG.md index e6177e0e..6cbede4c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,23 @@ [1]: https://pypi.org/project/google-api-core/#history +## [2.5.0](https://github.com/googleapis/python-api-core/compare/v2.4.0...v2.5.0) (2022-02-02) + + +### Features + +* add api_key to client options ([#248](https://github.com/googleapis/python-api-core/issues/248)) ([5e5ad37](https://github.com/googleapis/python-api-core/commit/5e5ad37b8161109d65b0fab43636f7424e570fa3)) + + +### Bug Fixes + +* **deps:** remove setuptools from dependencies ([#339](https://github.com/googleapis/python-api-core/issues/339)) ([c782f29](https://github.com/googleapis/python-api-core/commit/c782f294b50b078f01959627fb82aa4c5efec333)) + + +### Documentation + +* fix typo in library name ([#332](https://github.com/googleapis/python-api-core/issues/332)) ([f267111](https://github.com/googleapis/python-api-core/commit/f267111823545a6c67ef5f10b85cd8c2fab8a612)) + ## [2.4.0](https://www.github.com/googleapis/python-api-core/compare/v2.3.2...v2.4.0) (2022-01-11) diff --git a/README.rst b/README.rst index d94f3e88..13d8d3a6 100644 --- a/README.rst +++ b/README.rst @@ -25,4 +25,4 @@ Unsupported Python Versions Python == 2.7, Python == 3.5. The last version of this library compatible with Python 2.7 and 3.5 is -`google-api_core==1.31.1`. +`google-api-core==1.31.1`. diff --git a/google/api_core/client_options.py b/google/api_core/client_options.py index be5523df..4a2a84a4 100644 --- a/google/api_core/client_options.py +++ b/google/api_core/client_options.py @@ -66,11 +66,14 @@ class ClientOptions(object): quota_project_id (Optional[str]): A project name that a client's quota belongs to. credentials_file (Optional[str]): A path to a file storing credentials. + ``credentials_file` and ``api_key`` are mutually exclusive. scopes (Optional[Sequence[str]]): OAuth access token override scopes. + api_key (Optional[str]): Google API key. ``credentials_file`` and + ``api_key`` are mutually exclusive. Raises: ValueError: If both ``client_cert_source`` and ``client_encrypted_cert_source`` - are provided. + are provided, or both ``credentials_file`` and ``api_key`` are provided. """ def __init__( @@ -81,17 +84,21 @@ def __init__( quota_project_id=None, credentials_file=None, scopes=None, + api_key=None, ): if client_cert_source and client_encrypted_cert_source: raise ValueError( "client_cert_source and client_encrypted_cert_source are mutually exclusive" ) + if api_key and credentials_file: + raise ValueError("api_key and credentials_file are mutually exclusive") self.api_endpoint = api_endpoint self.client_cert_source = client_cert_source self.client_encrypted_cert_source = client_encrypted_cert_source self.quota_project_id = quota_project_id self.credentials_file = credentials_file self.scopes = scopes + self.api_key = api_key def __repr__(self): return "ClientOptions: " + repr(self.__dict__) diff --git a/google/api_core/version.py b/google/api_core/version.py index fe11624d..5836d805 100644 --- a/google/api_core/version.py +++ b/google/api_core/version.py @@ -12,4 +12,4 @@ # See the License for the specific language governing permissions and # limitations under the License. -__version__ = "2.4.0" +__version__ = "2.5.0" diff --git a/owlbot.py b/owlbot.py index 451f7c48..0b7f7d21 100644 --- a/owlbot.py +++ b/owlbot.py @@ -28,6 +28,7 @@ ".flake8", # flake8-import-order, layout ".coveragerc", # layout "CONTRIBUTING.rst", # no systests + ".github/workflows/unittest.yml", # exclude unittest gh action ] templated_files = common.py_library(microgenerator=True, cov_level=100) s.move(templated_files, excludes=excludes) @@ -44,4 +45,7 @@ """, ) +s.replace(".github/workflows/lint.yml", "python-version: \"3.10\"", "python-version: \"3.7\"") + + s.shell.run(["nox", "-s", "blacken"], hide_output=False) diff --git a/setup.py b/setup.py index ddc56004..e400a52f 100644 --- a/setup.py +++ b/setup.py @@ -33,7 +33,6 @@ "protobuf >= 3.12.0", "google-auth >= 1.25.0, < 3.0dev", "requests >= 2.18.0, < 3.0.0dev", - "setuptools >= 40.3.0", ] extras = { "grpc": ["grpcio >= 1.33.2, < 2.0dev", "grpcio-status >= 1.33.2, < 2.0dev"], diff --git a/testing/constraints-3.6.txt b/testing/constraints-3.6.txt index 0c2a07b6..bb1eb1e3 100644 --- a/testing/constraints-3.6.txt +++ b/testing/constraints-3.6.txt @@ -9,7 +9,6 @@ googleapis-common-protos==1.52.0 protobuf==3.12.0 google-auth==1.25.0 requests==2.18.0 -setuptools==40.3.0 packaging==14.3 grpcio==1.33.2 grpcio-gcp==0.2.2 diff --git a/tests/unit/test_client_options.py b/tests/unit/test_client_options.py index 38b9ad0a..fbff5457 100644 --- a/tests/unit/test_client_options.py +++ b/tests/unit/test_client_options.py @@ -72,6 +72,36 @@ def test_constructor_with_both_cert_sources(): ) +def test_constructor_with_api_key(): + + options = client_options.ClientOptions( + api_endpoint="foo.googleapis.com", + client_cert_source=get_client_cert, + quota_project_id="quote-proj", + api_key="api-key", + scopes=[ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + ], + ) + + assert options.api_endpoint == "foo.googleapis.com" + assert options.client_cert_source() == (b"cert", b"key") + assert options.quota_project_id == "quote-proj" + assert options.api_key == "api-key" + assert options.scopes == [ + "https://www.googleapis.com/auth/cloud-platform", + "https://www.googleapis.com/auth/cloud-platform.read-only", + ] + + +def test_constructor_with_both_api_key_and_credentials_file(): + with pytest.raises(ValueError): + client_options.ClientOptions( + api_key="api-key", credentials_file="path/to/credentials.json", + ) + + def test_from_dict(): options = client_options.from_dict( { @@ -94,6 +124,7 @@ def test_from_dict(): "https://www.googleapis.com/auth/cloud-platform", "https://www.googleapis.com/auth/cloud-platform.read-only", ] + assert options.api_key is None def test_from_dict_bad_argument(): @@ -112,6 +143,6 @@ def test_repr(): assert ( repr(options) - == "ClientOptions: {'api_endpoint': 'foo.googleapis.com', 'client_cert_source': None, 'client_encrypted_cert_source': None}" - or "ClientOptions: {'client_encrypted_cert_source': None, 'client_cert_source': None, 'api_endpoint': 'foo.googleapis.com'}" + == "ClientOptions: {'api_endpoint': 'foo.googleapis.com', 'client_cert_source': None, 'client_encrypted_cert_source': None, 'api_key': None}" + or "ClientOptions: {'client_encrypted_cert_source': None, 'client_cert_source': None, 'api_endpoint': 'foo.googleapis.com', 'api_key': None}" )