Skip to content

feat: check Python and dependency versions in generated GAPICs #2419

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions gapic/templates/%namespace/%name_%version/%sub/__init__.py.j2
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,79 @@ from {{package_path}} import gapic_version as package_version

__version__ = package_version.__version__


import google.api_core as api_core

try:
api_core.check_python_version("{{package_path}}")
api_core.check_dependency_versions("{{package_path}}")
except AttributeError:
{# TODO: Remove this try-catch when we require api-core at a version that
supports the changes in https://github.com/googleapis/python-api-core/pull/832

In the meantime, please ensure the functionality here mirrors the
equivalent functionality in api_core, in those two functions above.
#}
# An older version of api_core is installed, which does not define the
# functions above. We do equivalent checks manually.

import logging
import sys

_py_version_str = sys.version.split()[0]
_package_label = "{{package_path}}"
if sys.version_info < (3, 9):
logging.warning("You are using a non-supported Python version " +
f"({_py_version_str}). Google will not post any further " +
f"updates to {_package_label} supporting this Python version. " +
"Please upgrade to the latest Python version, or at " +
f"least to Python 3.9, and then update {_package_label}.")
if sys.version_info[:2] == (3, 9):
logging.warning(f"You are using a Python version ({_py_version_str}) " +
f"which Google will stop supporting in {_package_label} when " +
"it reaches its end of life (October 2025). Please " +
"upgrade to the latest Python version, or at " +
"least Python 3.10, before then, and " +
f"then update {_package_label}.")

from packaging.version import parse as parse_version

if sys.version_info < (3, 8):
import pkg_resources
def _get_version(dependency_name):
try:
version_string = pkg_resources.get_distribution(dependency_name).version
return parse_version(version_string)
except pkg_resources.DistributionNotFound:
return None
else:
from importlib import metadata

def _get_version(dependency_name):
try:
version_string = metadata.version("requests")
parsed_version = parse_version(version_string)
return parsed_version.release
except metadata.PackageNotFoundError:
return None

_dependency_package = "google.protobuf"
_next_supported_version = "4.25.8"
_next_supported_version_tuple = (4, 25, 8)
_version_used = _get_version(_dependency_package)
if _version_used and _version_used < _next_supported_version_tuple:
logging.warning(f"DEPRECATION: Package {_package_label} depends on " +
f"{_dependency_package}, currently installed at version " +
f"{_version_used.__str__}. Future updates to " +
f"{_package_label} will require {_dependency_package} at " +
f"version {_next_supported_version} or higher. Please ensure " +
"that either (a) your Python environment doesn't pin the " +
f"version of {_dependency_package}, so that updates to " +
f"{_package_label} can require the higher version, or " +
"(b) you manually update your Python environment to use at " +
f"least version {_next_supported_version} of " +
f"{_dependency_package}.")

{# Import subpackages. -#}
{% for subpackage, _ in api.subpackages|dictsort %}
from . import {{ subpackage }}
Expand Down
8 changes: 8 additions & 0 deletions noxfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ def unit(session):
"pyfakefs",
"grpcio-status",
"proto-plus",
"setuptools", # TODO: Remove when not needed in __init__.py.j2
"packaging", # TODO: Remove when not needed in __init__.py.j2
)
session.install("-e", ".")
session.run(
Expand Down Expand Up @@ -481,6 +483,8 @@ def run_showcase_unit_tests(session, fail_under=100, rest_async_io_enabled=False
"pytest-xdist",
"asyncmock; python_version < '3.8'",
"pytest-asyncio",
"setuptools", # TODO: Remove when not needed in __init__.py.j2
"packaging", # TODO: Remove when not needed in __init__.py.j2
)
# Run the tests.
# NOTE: async rest is not supported against the minimum supported version of google-api-core.
Expand Down Expand Up @@ -594,6 +598,8 @@ def showcase_mypy(
"types-protobuf",
"types-requests",
"types-dataclasses",
"setuptools", # TODO: Remove when not needed in __init__.py.j2
"packaging", # TODO: Remove when not needed in __init__.py.j2
)

with showcase_library(session, templates=templates, other_opts=other_opts) as lib:
Expand Down Expand Up @@ -724,6 +730,8 @@ def mypy(session):
"types-PyYAML",
"types-dataclasses",
"click==8.1.3",
"setuptools", # TODO: Remove when not needed in __init__.py.j2
"packaging", # TODO: Remove when not needed in __init__.py.j2
)
session.install(".")
session.run("mypy", "-p", "gapic")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,73 @@
__version__ = package_version.__version__


import google.api_core as api_core

try:
api_core.check_python_version("google.cloud.asset_v1")
api_core.check_dependency_versions("google.cloud.asset_v1")
except AttributeError:
# An older version of api_core is installed, which does not define the
# functions above. We do equivalent checks manually.

import logging
import sys

_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.asset_v1"
if sys.version_info < (3, 9):
logging.warning("You are using a non-supported Python version " +
f"({_py_version_str}). Google will not post any further " +
f"updates to {_package_label} supporting this Python version. " +
"Please upgrade to the latest Python version, or at " +
f"least to Python 3.9, and then update {_package_label}.")
if sys.version_info[:2] == (3, 9):
logging.warning(f"You are using a Python version ({_py_version_str}) " +
f"which Google will stop supporting in {_package_label} when " +
"it reaches its end of life (October 2025). Please " +
"upgrade to the latest Python version, or at " +
"least Python 3.10, before then, and " +
f"then update {_package_label}.")

from packaging.version import parse as parse_version

if sys.version_info < (3, 8):
import pkg_resources
def _get_version(dependency_name):
try:
version_string = pkg_resources.get_distribution(dependency_name).version
return parse_version(version_string)
except pkg_resources.DistributionNotFound:
return None
else:
from importlib import metadata

def _get_version(dependency_name):
try:
version_string = metadata.version("requests")
parsed_version = parse_version(version_string)
return parsed_version.release
except metadata.PackageNotFoundError:
return None

_dependency_package = "google.protobuf"
_next_supported_version = "4.25.8"
_next_supported_version_tuple = (4, 25, 8)
_version_used = _get_version(_dependency_package)
if _version_used and _version_used < _next_supported_version_tuple:
logging.warning(f"DEPRECATION: Package {_package_label} depends on " +
f"{_dependency_package}, currently installed at version " +
f"{_version_used.__str__}. Future updates to " +
f"{_package_label} will require {_dependency_package} at " +
f"version {_next_supported_version} or higher. Please ensure " +
"that either (a) your Python environment doesn't pin the " +
f"version of {_dependency_package}, so that updates to " +
f"{_package_label} can require the higher version, or " +
"(b) you manually update your Python environment to use at " +
f"least version {_next_supported_version} of " +
f"{_dependency_package}.")


from .services.asset_service import AssetServiceClient
from .services.asset_service import AssetServiceAsyncClient

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,73 @@
__version__ = package_version.__version__


import google.api_core as api_core

try:
api_core.check_python_version("google.iam.credentials_v1")
api_core.check_dependency_versions("google.iam.credentials_v1")
except AttributeError:
# An older version of api_core is installed, which does not define the
# functions above. We do equivalent checks manually.

import logging
import sys

_py_version_str = sys.version.split()[0]
_package_label = "google.iam.credentials_v1"
if sys.version_info < (3, 9):
logging.warning("You are using a non-supported Python version " +
f"({_py_version_str}). Google will not post any further " +
f"updates to {_package_label} supporting this Python version. " +
"Please upgrade to the latest Python version, or at " +
f"least to Python 3.9, and then update {_package_label}.")
if sys.version_info[:2] == (3, 9):
logging.warning(f"You are using a Python version ({_py_version_str}) " +
f"which Google will stop supporting in {_package_label} when " +
"it reaches its end of life (October 2025). Please " +
"upgrade to the latest Python version, or at " +
"least Python 3.10, before then, and " +
f"then update {_package_label}.")

from packaging.version import parse as parse_version

if sys.version_info < (3, 8):
import pkg_resources
def _get_version(dependency_name):
try:
version_string = pkg_resources.get_distribution(dependency_name).version
return parse_version(version_string)
except pkg_resources.DistributionNotFound:
return None
else:
from importlib import metadata

def _get_version(dependency_name):
try:
version_string = metadata.version("requests")
parsed_version = parse_version(version_string)
return parsed_version.release
except metadata.PackageNotFoundError:
return None

_dependency_package = "google.protobuf"
_next_supported_version = "4.25.8"
_next_supported_version_tuple = (4, 25, 8)
_version_used = _get_version(_dependency_package)
if _version_used and _version_used < _next_supported_version_tuple:
logging.warning(f"DEPRECATION: Package {_package_label} depends on " +
f"{_dependency_package}, currently installed at version " +
f"{_version_used.__str__}. Future updates to " +
f"{_package_label} will require {_dependency_package} at " +
f"version {_next_supported_version} or higher. Please ensure " +
"that either (a) your Python environment doesn't pin the " +
f"version of {_dependency_package}, so that updates to " +
f"{_package_label} can require the higher version, or " +
"(b) you manually update your Python environment to use at " +
f"least version {_next_supported_version} of " +
f"{_dependency_package}.")


from .services.iam_credentials import IAMCredentialsClient
from .services.iam_credentials import IAMCredentialsAsyncClient

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,73 @@
__version__ = package_version.__version__


import google.api_core as api_core

try:
api_core.check_python_version("google.cloud.eventarc_v1")
api_core.check_dependency_versions("google.cloud.eventarc_v1")
except AttributeError:
# An older version of api_core is installed, which does not define the
# functions above. We do equivalent checks manually.

import logging
import sys

_py_version_str = sys.version.split()[0]
_package_label = "google.cloud.eventarc_v1"
if sys.version_info < (3, 9):
logging.warning("You are using a non-supported Python version " +
f"({_py_version_str}). Google will not post any further " +
f"updates to {_package_label} supporting this Python version. " +
"Please upgrade to the latest Python version, or at " +
f"least to Python 3.9, and then update {_package_label}.")
if sys.version_info[:2] == (3, 9):
logging.warning(f"You are using a Python version ({_py_version_str}) " +
f"which Google will stop supporting in {_package_label} when " +
"it reaches its end of life (October 2025). Please " +
"upgrade to the latest Python version, or at " +
"least Python 3.10, before then, and " +
f"then update {_package_label}.")

from packaging.version import parse as parse_version

if sys.version_info < (3, 8):
import pkg_resources
def _get_version(dependency_name):
try:
version_string = pkg_resources.get_distribution(dependency_name).version
return parse_version(version_string)
except pkg_resources.DistributionNotFound:
return None
else:
from importlib import metadata

def _get_version(dependency_name):
try:
version_string = metadata.version("requests")
parsed_version = parse_version(version_string)
return parsed_version.release
except metadata.PackageNotFoundError:
return None

_dependency_package = "google.protobuf"
_next_supported_version = "4.25.8"
_next_supported_version_tuple = (4, 25, 8)
_version_used = _get_version(_dependency_package)
if _version_used and _version_used < _next_supported_version_tuple:
logging.warning(f"DEPRECATION: Package {_package_label} depends on " +
f"{_dependency_package}, currently installed at version " +
f"{_version_used.__str__}. Future updates to " +
f"{_package_label} will require {_dependency_package} at " +
f"version {_next_supported_version} or higher. Please ensure " +
"that either (a) your Python environment doesn't pin the " +
f"version of {_dependency_package}, so that updates to " +
f"{_package_label} can require the higher version, or " +
"(b) you manually update your Python environment to use at " +
f"least version {_next_supported_version} of " +
f"{_dependency_package}.")


from .services.eventarc import EventarcClient
from .services.eventarc import EventarcAsyncClient

Expand Down
Loading
Loading