Skip to content

Conversation

@tjb9dc
Copy link
Collaborator

@tjb9dc tjb9dc commented Dec 5, 2025

Description

Refs extend-hq/extend-python-sdk#14

Adds a model_dump_json() override to UniversalBaseModel so that JSON serialization properly respects FieldMetadata aliases (e.g., snake_casecamelCase).

Background: The existing dict() method already handles FieldMetadata aliases via convert_and_respect_annotation_metadata(). However, model_dump_json() was calling Pydantic's native implementation directly, which doesn't know about FieldMetadata annotations. This caused JSON output to use Python field names instead of the expected wire-format aliases.

Requested by: [email protected] (@tjb9dc)
Link to Devin run: https://app.devin.ai/sessions/078ffa2dec06476a9c041a29f6f37cf4

Changes Made

  • Added model_dump_json() override to UniversalBaseModel in pydantic_utilities.py
  • Added same override to with_pydantic_v1_on_v2/pydantic_utilities.py variant
  • Updated versions.yml with changelog entry for v4.43.0

The new method delegates to our custom dict() (which handles aliases correctly) and then serializes to JSON:

  • Pydantic v2: Uses to_jsonable_python(data, fallback=encode_by_type) for proper v2 JSON normalization
  • Pydantic v1: Uses json.dumps(data, default=encode_by_type) directly

Note: The with_pydantic_aliases variants were intentionally NOT updated because they use native Pydantic Field(alias=...) where by_alias=True already works correctly. The with_pydantic_v1_on_v2 variant uses the simpler v1-style implementation since it's explicitly v1-only.

Updates Since Last Revision

  • Added proper v1/v2 branching in the main pydantic_utilities.py to use to_jsonable_python for Pydantic v2, matching the existing pattern used by to_jsonable_with_fallback in the codebase

Testing

  • Unit tests added/updated
  • Lint checks pass (pnpm run check)
  • Seed tests (will run in CI)

Human Review Checklist

  • Verify v1/v2 branching is correct (v2 uses to_jsonable_python, v1 uses json.dumps with default)
  • Verify encode_by_type handles all necessary types (datetime, UUID, Decimal, Enum, etc.) - it uses Pydantic's ENCODERS_BY_TYPE
  • Confirm seed tests adequately cover model_dump_json() with aliased fields
  • Verify with_pydantic_v1_on_v2 variant correctly uses simpler implementation (no IS_PYDANTIC_V2 check needed since it's v1-only)

@devin-ai-integration
Copy link
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants