Skip to content

Commit 85c8700

Browse files
committed
Fix quota project id review comments: form widget, docstrings, anon check, error messages, test boundaries
1 parent 7580cfe commit 85c8700

File tree

3 files changed

+11
-10
lines changed

3 files changed

+11
-10
lines changed

providers/google/docs/connections/gcp.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ Quota Project ID (optional)
127127

128128
The Google Cloud project ID to use for API quota and billing purposes. This is useful
129129
when using a shared service account but want to attribute quota/billing to a different
130-
project. If not specified, the default project from the connection is used. Must be a
130+
project. If not specified, no separate quota project is configured on the credentials and Google Cloud's default behavior applies. Must be a
131131
valid GCP project ID (lowercase letters, digits, hyphens, 6–30 characters, starting
132132
with a letter).
133133

@@ -418,5 +418,5 @@ Examples
418418

419419
**Examples**
420420

421-
See the example DAG: ``airflow/providers/google/cloud/example_dags/example_quota_project.py``
421+
See the example DAG: ``tests/system/providers/google/common/example_quota_project_system.py``
422422

providers/google/src/airflow/providers/google/common/hooks/base_google.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,9 @@ def get_connection_form_widgets(cls) -> dict[str, Any]:
262262
"is_anonymous": BooleanField(
263263
lazy_gettext("Anonymous credentials (ignores all other settings)"), default=False
264264
),
265+
"quota_project_id": StringField(
266+
lazy_gettext("Quota Project ID"), widget=BS3TextFieldWidget()
267+
),
265268
}
266269

267270
@classmethod
@@ -291,7 +294,7 @@ def __init__(
291294
:param impersonation_chain: Optional service account to impersonate using short-term
292295
credentials.
293296
:param quota_project_id: Optional Project ID to use for quota/billing purposes.
294-
If None, the Project ID from the GCP connection is used.
297+
If None, no separate quota project is configured and the default behavior of the credentials is used.
295298
:param kwargs: Additional arguments to pass to parent constructor.
296299
"""
297300
super().__init__(**kwargs)
@@ -356,7 +359,7 @@ def get_credentials_and_project_id(self) -> tuple[Credentials, str | None]:
356359

357360
# Apply quota project before caching credentials
358361
quota_project = self.quota_project_id or self._get_field("quota_project_id")
359-
if quota_project:
362+
if quota_project and not is_anonymous:
360363
self._validate_quota_project(quota_project)
361364
if not hasattr(credentials, "with_quota_project"):
362365
raise ValueError(
@@ -391,8 +394,7 @@ def _validate_quota_project(self, quota_project: str) -> None:
391394
if not is_valid_gcp_project_id(quota_project):
392395
raise ValueError(
393396
f"Invalid quota_project_id '{quota_project}'. "
394-
"Project IDs must start with a lowercase letter and can contain "
395-
"only lowercase letters and digits."
397+
"Project IDs must be 6-30 characters long, start with a lowercase letter, and can contain only lowercase letters, digits, and hyphens."
396398
)
397399

398400
def get_credentials(self) -> Credentials:

providers/google/tests/unit/google/common/hooks/test_base_google.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -585,11 +585,10 @@ def test_quota_project_invalid_format(self):
585585
invalid_ids = [
586586
"UPPERCASE", # Must be lowercase
587587
"special@chars", # Invalid characters
588-
"a", # Too short
589-
"a" * 31, # Too long
588+
"ab-cd", # Too short
589+
"a" + "b" * 30, # Too long
590590
"1starts-with-number", # Must start with letter
591-
"", # Empty string
592-
None, # None value
591+
"", #Empty-String
593592
]
594593

595594
for invalid_id in invalid_ids:

0 commit comments

Comments
 (0)