Skip to content

Commit 4fce62f

Browse files
jaycee-licopybara-github
authored andcommitted
chore: Ensure deeply nested fields are loaded from raw responses even if not defined in types.py
PiperOrigin-RevId: 818743475
1 parent 7d4d23e commit 4fce62f

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

google/genai/_common.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,28 @@ def _format_collection(
548548
return f'{brackets[0]}\n' + ',\n'.join(elements) + f',\n{indent}{brackets[1]}'
549549

550550

551+
def _camel_to_snake(camel_case_string: str) -> str:
552+
"""Converts a camelCase string to snake_case."""
553+
snake_case_string = re.sub(r'(?<!^)([A-Z])', r'_\1', camel_case_string)
554+
return snake_case_string.lower()
555+
556+
557+
def _camel_key_to_snake(message: Any) -> Any:
558+
"""Converts all camelCase keys to snake_case in a dict or list."""
559+
if isinstance(message, dict):
560+
return {
561+
# Several xxxMetadata fields have already released with camelCase
562+
# values, we need to keep them as is.
563+
_camel_to_snake(key) if 'metadata' not in key.lower() else key:
564+
_camel_key_to_snake(value) if 'metadata' not in key.lower() else value
565+
for key, value in message.items()
566+
}
567+
elif isinstance(message, list):
568+
return [_camel_key_to_snake(value) for value in message]
569+
else:
570+
return message
571+
572+
551573
class BaseModel(pydantic.BaseModel):
552574

553575
model_config = pydantic.ConfigDict(
@@ -576,6 +598,9 @@ def _from_response(
576598
response: dict[str, object],
577599
kwargs: dict[str, object],
578600
) -> T:
601+
# Convert all camelCase keys to snake_case before loading the response.
602+
response = _camel_key_to_snake(response)
603+
579604
# To maintain forward compatibility, we need to remove extra fields from
580605
# the response.
581606
# We will provide another mechanism to allow users to access these fields.

0 commit comments

Comments
 (0)