Skip to content
Merged
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@
!/create_types_pyi.py
!/stubdefaulter.sh
!/stubgen.py
!/fixup_versions.py
__pycache__
157 changes: 157 additions & 0 deletions fixup_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
import re

from google.ads.googleads import client

sorted_versions = sorted(client._VALID_API_VERSIONS)


def replace_between_markers(content, marker_prefix, marker_suffix, replacement):
replacement = "\n".join([marker_prefix, replacement, marker_suffix])
new_content = re.sub(
f"{marker_prefix}.+{marker_suffix}",
replacement,
content,
flags=re.DOTALL,
)
return new_content


def fix_interceptors():
interceptor_imports = []
interceptor_request_types = []

for version in sorted_versions:
interceptor_imports.append(f"import google.ads.googleads.{version}.services")
interceptor_request_types.append(
f"google.ads.googleads.{version}.services.SearchGoogleAdsRequest"
)
interceptor_request_types.append(
f"google.ads.googleads.{version}.services.SearchGoogleAdsStreamRequest"
)

interceptor_imports_prefix = "# Autogenerated imports"
interceptor_imports_suffix = "# End of autogenerated imports"
interceptor_request_types_prefix = "# Autogenerated request types"
interceptor_request_types_suffix = "# End of autogenerated request types"

interceptor_import_replacement = "\n".join(interceptor_imports)
interceptor_request_types_replacement = ",\n".join(interceptor_request_types)

interceptor_files = [
"google-stubs/ads/googleads/interceptors/exception_interceptor.pyi",
"google-stubs/ads/googleads/interceptors/logging_interceptor.pyi",
"google-stubs/ads/googleads/interceptors/metadata_interceptor.pyi",
]

for interceptor_file in interceptor_files:
with open(interceptor_file) as f:
interceptor_pyi = f.read()
interceptor_pyi = replace_between_markers(
interceptor_pyi,
interceptor_imports_prefix,
interceptor_imports_suffix,
interceptor_import_replacement,
)
interceptor_pyi = replace_between_markers(
interceptor_pyi,
interceptor_request_types_prefix,
interceptor_request_types_suffix,
interceptor_request_types_replacement,
)
with open(interceptor_file, mode="w") as f:
f.write(interceptor_pyi)


def fix_errors():
error_imports = []
error_types = []

for version in sorted_versions:
error_imports.append(
f"from google.ads.googleads.{version}.errors import GoogleAdsFailure as GoogleAdsFailure{version.upper()}"
)
error_types.append(f"GoogleAdsFailure{version.upper()}")

error_imports_prefix = "# Autogenerated imports"
error_imports_suffix = "# End of autogenerated imports"
error_types_prefix = "# Autogenerated failure types"
error_types_suffix = "# End of autogenerated failure types"

error_imports_replacement = "\n".join(error_imports)
error_types_replacement = " | ".join(error_types)

with open("google-stubs/ads/googleads/errors.pyi") as f:
errors_pyi = f.read()

errors_pyi = replace_between_markers(
errors_pyi,
error_imports_prefix,
error_imports_suffix,
error_imports_replacement,
)
errors_pyi = replace_between_markers(
errors_pyi,
error_types_prefix,
error_types_suffix,
error_types_replacement,
)
with open("google-stubs/ads/googleads/errors.pyi", mode="w") as f:
f.write(errors_pyi)


def fix_client():
default_version_import = (
f"from google.ads.googleads import {client._DEFAULT_VERSION}"
)

default_version_import_prefix = "# Autogenerated import of latest version"
default_version_import_suffix = "# End of autogenerated import of latest version"

with open("google-stubs/ads/googleads/client.pyi") as f:
client_pyi = f.read()

client_pyi = replace_between_markers(
client_pyi,
default_version_import_prefix,
default_version_import_suffix,
default_version_import,
)

version_literals = []
for version in sorted_versions:
version_literals.append(f'_{version.upper()} = Literal["{version}"]')
version_literals.append(
f"_V = {' | '.join([f'_{version.upper()}' for version in sorted_versions])}"
)

version_literals_prefix = "# Autogenerated version literals"
version_literals_suffix = "# End of autogenerated version literals"

version_literals_replacement = "\n".join(version_literals)

client_pyi = replace_between_markers(
client_pyi,
version_literals_prefix,
version_literals_suffix,
version_literals_replacement,
)

get_type_overload = f' def get_type(cls, name: str, version: _V = "{client._DEFAULT_VERSION}") -> Any: ...'

get_type_overload_prefix = " # Autogenerated get_type overload"
get_type_overload_suffix = " # End of autogenerated get_type overload"

client_pyi = replace_between_markers(
client_pyi,
get_type_overload_prefix,
get_type_overload_suffix,
get_type_overload,
)

with open("google-stubs/ads/googleads/client.pyi", mode="w") as f:
f.write(client_pyi)


fix_interceptors()
fix_errors()
fix_client()
11 changes: 4 additions & 7 deletions gen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,8 @@
set -eou pipefail
shopt -s globstar

# Manual: Clone https://github.com/googleads/google-ads-python
# Manual: Update google-ads-python dependency
# Manual: Update the following to match the API versions:
# - GoogleAdsFailure in errors.pyi
# - _V, imports and get_type default in client.pyi
# - _Request in exception_interceptor.pyi, logging_interceptor.pyi and metadata_interceptor.pyi
uv remove google-ads && uv add google-ads
git clone https://github.com/googleads/google-ads-python.git || true
cd google-ads-python
git restore .
git pull
Expand All @@ -21,8 +17,9 @@ uv run python stubgen.py
uv run python create_type_stubs.py
uv run python create_enums.py
uv run python create_service_overloads.py
uv run python fixup_versions.py
./stubdefaulter.sh
mv .gitignore gitignore
mv .gitignore gitignore # Workaround for ruff's handling of gitignore files with whitelisting.
uv run ruff check google-stubs --fix --unsafe-fixes
uv run ruff format google-stubs
mv gitignore .gitignore
Expand Down
7 changes: 7 additions & 0 deletions google-stubs/ads/googleads/client.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -437,14 +437,19 @@ import google.ads.googleads.v23.services.services.user_list_customer_type_servic
import google.ads.googleads.v23.services.services.user_list_service

# End of autogenerated service imports
# Autogenerated import of latest version
from google.ads.googleads import v23

# End of autogenerated import of latest version
from google.ads.googleads.config import _ConfigDataUnparsed

# Autogenerated version literals
_V20 = Literal["v20"]
_V21 = Literal["v21"]
_V22 = Literal["v22"]
_V23 = Literal["v23"]
_V = _V20 | _V21 | _V22 | _V23
# End of autogenerated version literals

class _EnumGetter:
# Autogenerated enums
Expand Down Expand Up @@ -1303,7 +1308,9 @@ class GoogleAdsClient:
use_proto_plus: bool = False,
use_cloud_org_for_api_access: bool | None = None,
) -> None: ...
# Autogenerated get_type overload
def get_type(cls, name: str, version: _V = "v23") -> Any: ...
# End of autogenerated get_type overload
# Autogenerated service overloads
@overload
def get_service(
Expand Down
5 changes: 5 additions & 0 deletions google-stubs/ads/googleads/errors.pyi
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import grpc

# Autogenerated imports
from google.ads.googleads.v20.errors import GoogleAdsFailure as GoogleAdsFailureV20
from google.ads.googleads.v21.errors import GoogleAdsFailure as GoogleAdsFailureV21
from google.ads.googleads.v22.errors import GoogleAdsFailure as GoogleAdsFailureV22
from google.ads.googleads.v23.errors import GoogleAdsFailure as GoogleAdsFailureV23

# End of autogenerated imports

GoogleAdsFailure = (
# Autogenerated failure types
GoogleAdsFailureV20
| GoogleAdsFailureV21
| GoogleAdsFailureV22
| GoogleAdsFailureV23
# End of autogenerated failure types
)

class GoogleAdsException(Exception):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ from typing import TypeVar

import grpc

# Autogenerated imports
import google.ads.googleads.v20.services
import google.ads.googleads.v21.services
import google.ads.googleads.v22.services
import google.ads.googleads.v23.services

# End of autogenerated imports
from .interceptor import Interceptor

_Request = TypeVar(
"_Request",
# Autogenerated request types
google.ads.googleads.v20.services.SearchGoogleAdsRequest,
google.ads.googleads.v20.services.SearchGoogleAdsStreamRequest,
google.ads.googleads.v21.services.SearchGoogleAdsRequest,
Expand All @@ -20,6 +23,7 @@ _Request = TypeVar(
google.ads.googleads.v22.services.SearchGoogleAdsStreamRequest,
google.ads.googleads.v23.services.SearchGoogleAdsRequest,
google.ads.googleads.v23.services.SearchGoogleAdsStreamRequest,
# End of autogenerated request types
)
_Response = TypeVar("_Response")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,18 @@ from typing import TypeVar
import grpc
from google.protobuf.message import Message

# Autogenerated imports
import google.ads.googleads.v20.services
import google.ads.googleads.v21.services
import google.ads.googleads.v22.services
import google.ads.googleads.v23.services

# End of autogenerated imports
from .interceptor import Interceptor

_Request = TypeVar(
"_Request",
# Autogenerated request types
google.ads.googleads.v20.services.SearchGoogleAdsRequest,
google.ads.googleads.v20.services.SearchGoogleAdsStreamRequest,
google.ads.googleads.v21.services.SearchGoogleAdsRequest,
Expand All @@ -22,6 +25,7 @@ _Request = TypeVar(
google.ads.googleads.v22.services.SearchGoogleAdsStreamRequest,
google.ads.googleads.v23.services.SearchGoogleAdsRequest,
google.ads.googleads.v23.services.SearchGoogleAdsStreamRequest,
# End of autogenerated request types
)
_Response = TypeVar("_Response")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ from typing import TypeVar

import grpc

# Autogenerated imports
import google.ads.googleads.v20.services
import google.ads.googleads.v21.services
import google.ads.googleads.v22.services
import google.ads.googleads.v23.services

# End of autogenerated imports
from .interceptor import Interceptor

_Request = TypeVar(
"_Request",
# Autogenerated request types
google.ads.googleads.v20.services.SearchGoogleAdsRequest,
google.ads.googleads.v20.services.SearchGoogleAdsStreamRequest,
google.ads.googleads.v21.services.SearchGoogleAdsRequest,
Expand All @@ -20,6 +23,7 @@ _Request = TypeVar(
google.ads.googleads.v22.services.SearchGoogleAdsStreamRequest,
google.ads.googleads.v23.services.SearchGoogleAdsRequest,
google.ads.googleads.v23.services.SearchGoogleAdsStreamRequest,
# End of autogenerated request types
)
_Response = TypeVar("_Response")

Expand Down
Loading