-
Notifications
You must be signed in to change notification settings - Fork 358
fix: Store Pydantic models as dicts in session state for JSON serialization #130
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
base: main
Are you sure you want to change the base?
fix: Store Pydantic models as dicts in session state for JSON serialization #130
Conversation
|
Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). View this failed invocation of the CLA check for more information. For the most up to date status, view the checks section at the bottom of the pull request. |
Summary of ChangesHello @diptendulkar, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a critical serialization error encountered when Pydantic models are stored in the ADK's Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Code Review
This pull request correctly addresses a JSON serialization error that occurred when storing Pydantic models in the session state. The solution of converting models to dictionaries using .model_dump() before storing and reconstructing them with .model_validate() upon retrieval is sound and has been applied consistently. The changes are well-implemented and include defensive checks to handle both dictionaries and model instances, ensuring robustness. I have one suggestion to improve maintainability by refactoring the repeated model reconstruction logic.
| payment_mandate: PaymentMandate = PaymentMandate.model_validate(payment_mandate_data) if isinstance(payment_mandate_data, dict) else payment_mandate_data | ||
| cart_mandate: CartMandate = CartMandate.model_validate(cart_mandate_data) if isinstance(cart_mandate_data, dict) else cart_mandate_data |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic for reconstructing Pydantic models from dictionaries is repeated in a few places (e.g., here, line 188 in this file, and in samples/python/src/roles/shopping_agent/subagents/shopper/tools.py on line 127).
To improve maintainability and adhere to the DRY (Don't Repeat Yourself) principle, consider extracting this into a utility function. For example:
from pydantic import BaseModel
from typing import Type, TypeVar
M = TypeVar("M", bound=BaseModel)
def reconstruct_model(data: dict | M, model_class: Type[M]) -> M:
"""Reconstructs a Pydantic model from a dict if necessary."""
if isinstance(data, dict):
return model_class.model_validate(data)
return dataThis helper could be placed in a shared utility module. Using it would simplify the code to:
payment_mandate: PaymentMandate = reconstruct_model(payment_mandate_data, PaymentMandate)
cart_mandate: CartMandate = reconstruct_model(cart_mandate_data, CartMandate)Since modifying shared files might be outside the scope of this PR, this could be addressed in a follow-up.
…zation This fixes the 'Object of type IntentMandate is not JSON serializable' error when the ADK's SqliteSessionService tries to serialize session state. Changes: - Store IntentMandate, CartMandate, PaymentMandate, and PaymentReceipt as dicts using .model_dump() instead of raw Pydantic objects - Reconstruct Pydantic objects on retrieval where needed for property access
34e268e to
24f4e3b
Compare
|
I have signed the SLA |
Description
Summary
Fixes session state serialization error when using ADK's
SqliteSessionService. Pydantic models stored intool_context.statewere causingTypeError: Object of type IntentMandate is not JSON serializablebecausejson.dumps()cannot serialize PydanticBaseModelinstances directly.Problem
When the ADK persists session state to SQLite, it calls
json.dumps(delta)on the state delta. If the state contains Pydantic model instances (likeIntentMandate,CartMandate,PaymentMandate), serialization fails with:This fixes the 'Object of type IntentMandate is not JSON serializable' error when the ADK's SqliteSessionService tries to serialize session state.
Solution
Store Pydantic models as dictionaries using
.model_dump()and reconstruct them on retrieval using.model_validate()where property access is needed.Changes
samples/python/src/roles/shopping_agent/subagents/shopper/tools.py:intent_mandate→ stored as.model_dump()cart_mandates→ stored as list of dictsupdate_chosen_cart_mandate()→ reconstructsCartMandateobjects on retrievalsamples/python/src/roles/shopping_agent/tools.py:cart_mandate,payment_receipt,payment_mandate,signed_payment_mandate→ stored as dictscreate_payment_mandate()→ reconstructsCartMandateon retrievalsign_mandates_on_user_device()→ reconstructsPaymentMandateandCartMandateon retrievalTesting
Run the sample scenario:
bash samples/python/scenarios/a2a/human-present/cards/run.sh## Related Issues
Thank you for opening a Pull Request!
Before submitting your PR, there are a few things you can do to make sure it goes smoothly:
CONTRIBUTINGGuide.Fixes #129 🦕