fix(backend): Unbreak UserIntegrations parsing for missing None values (#9994)

Makes all optional fields on `Credentials` models actually optional, and
sets `exclude_none=True` on the corresponding `model_dump`.

This is a hotfix: after running the `aryshare-revid` branch on the dev
deployment, there is some data in the DB that isn't valid for the
`UserIntegrations` model on the `dev` branch (see
[here](https://github.com/Significant-Gravitas/AutoGPT/pull/9946#discussion_r2098428575)).

### Checklist 📋

#### For code changes:
- [x] I have clearly listed my changes in the PR description
- [x] I have made a test plan
- [x] I have tested my changes according to the test plan:
- [x] This fix worked on the `aryshare-revid` branch:
52b6d9696b
This commit is contained in:
Reinier van der Leer
2025-05-21 01:50:19 +02:00
committed by GitHub
parent f466b010e4
commit 73ee6e272a
2 changed files with 6 additions and 6 deletions

View File

@@ -189,7 +189,7 @@ def SchemaField(
class _BaseCredentials(BaseModel):
id: str = Field(default_factory=lambda: str(uuid4()))
provider: str
title: Optional[str]
title: Optional[str] = None
@field_serializer("*")
def dump_secret_strings(value: Any, _info):
@@ -200,13 +200,13 @@ class _BaseCredentials(BaseModel):
class OAuth2Credentials(_BaseCredentials):
type: Literal["oauth2"] = "oauth2"
username: Optional[str]
username: Optional[str] = None
"""Username of the third-party service user that these credentials belong to"""
access_token: SecretStr
access_token_expires_at: Optional[int]
access_token_expires_at: Optional[int] = None
"""Unix timestamp (seconds) indicating when the access token expires (if at all)"""
refresh_token: Optional[SecretStr]
refresh_token_expires_at: Optional[int]
refresh_token: Optional[SecretStr] = None
refresh_token_expires_at: Optional[int] = None
"""Unix timestamp (seconds) indicating when the refresh token expires (if at all)"""
scopes: list[str]
metadata: dict[str, Any] = Field(default_factory=dict)

View File

@@ -124,7 +124,7 @@ async def get_user_integrations(user_id: str) -> UserIntegrations:
async def update_user_integrations(user_id: str, data: UserIntegrations):
encrypted_data = JSONCryptor().encrypt(data.model_dump())
encrypted_data = JSONCryptor().encrypt(data.model_dump(exclude_none=True))
await User.prisma().update(
where={"id": user_id},
data={"integrations": encrypted_data},