Python -VV
Python 3.13.7 (main, Sep 25 2025, 21:20:20) [Clang 17.0.0 (clang-1700.3.19.1)]
Pip Freeze
aiofiles==25.1.0
alembic==1.17.2
annotated-doc==0.0.4
annotated-types==0.7.0
anyio==4.11.0
appdirs==1.4.4
APScheduler==3.11.1
argon2-cffi==25.1.0
argon2-cffi-bindings==25.1.0
async-property==0.2.2
certifi==2025.8.3
cffi==2.0.0
charset-normalizer==3.4.3
click==8.3.0
cryptography==46.0.1
debugpy==1.8.19
Deprecated==1.2.18
deprecation==2.1.0
distro==1.9.0
dnspython==2.8.0
ecdsa==0.19.1
elementpath==5.0.4
email-validator==2.3.0
eval_type_backport==0.2.2
fastapi==0.121.3
frozendict==2.4.6
h11==0.16.0
httpcore==1.0.9
httpx==0.28.1
idna==3.10
img2pdf==0.6.1
iniconfig==2.3.0
invoke==2.2.1
Jinja2==3.1.6
jwcrypto==1.5.6
lxml==6.0.2
Mako==1.3.10
markdown-it-py==4.0.0
MarkupSafe==3.0.3
mdurl==0.1.2
minio==7.2.18
mistralai==1.9.11
mollie-api-python==3.9.1
oauthlib==3.3.1
ocrmypdf==16.11.0
packaging==25.0
pdfminer.six==20250506
pi_heif==1.1.0
pikepdf==9.11.0
pillow==11.3.0
pluggy==1.6.0
pyasn1==0.6.1
pycparser==2.23
pycryptodome==3.23.0
pydantic==2.11.10
pydantic-settings==2.12.0
pydantic-xml==2.18.0
pydantic_core==2.33.2
Pygments==2.19.2
pyschematron==1.1.13
pytest==9.0.1
pytest-asyncio==1.3.0
python-dateutil==2.9.0.post0
python-dotenv==1.2.1
python-jose==3.5.0
python-keycloak==5.8.1
python-multipart==0.0.20
PyYAML==6.0.3
requests==2.32.5
requests-oauthlib==2.0.0
requests-toolbelt==1.0.0
rich==14.1.0
rsa==4.9.1
ruyaml==0.91.0
setuptools==80.9.0
shellingham==1.5.4
six==1.17.0
sniffio==1.3.1
SQLAlchemy==2.0.43
sqlmodel==0.0.27
starlette==0.48.0
typer==0.19.2
typing-inspection==0.4.2
typing_extensions==4.15.0
tzlocal==5.3.1
urllib3==2.5.0
uvicorn==0.38.0
wrapt==1.17.3
xmlschema==4.1.0
Reproduction Steps
- Create a simple Pydantic model:
from mistralai.extra import response_format_from_pydantic_model
from pydantic import BaseModel, Field
import json
class TestModel(BaseModel):
name: str = Field(description="A name field")
value: int = Field(description="A value field")
- Generate a ResponseFormat using the SDK function:
response_format = response_format_from_pydantic_model(TestModel)
- Serialize using
model_dump() without by_alias=True:
serialized = response_format.model_dump(mode='json')
print(json.dumps(serialized, indent=2))
-
Observe that json_schema.schema is null instead of containing the schema definition.
-
Compare with model_dump(by_alias=True):
serialized_with_alias = response_format.model_dump(mode='json', by_alias=True)
print(json.dumps(serialized_with_alias, indent=2))
Expected Behavior
hen calling model_dump() on a ResponseFormat object created with response_format_from_pydantic_model(), the json_schema.schema field should contain the actual JSON schema definition, not null. The serialization should work consistently regardless of whether by_alias=True is used.
The expected output should be:
{
"type": "json_schema",
"json_schema": {
"name": "TestModel",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string", "description": "A name field"},
"value": {"type": "integer", "description": "A value field"}
},
"required": ["name", "value"],
"additionalProperties": false
},
"strict": true
}
}
Additional Context
Current Behavior:
model_dump() shows schema: null
model_dump(by_alias=True) correctly shows the schema
- Actual API calls succeed because the SDK's
marshal_json() function (used for HTTP requests) internally calls model_dump(by_alias=True)
Root Cause:
The issue is in JSONSchema.model_serializer (located in mistralai/models/jsonschema.py). The serializer attempts to retrieve the schema_definition field using its alias "schema", but handler(self) returns a dict with the field name "schema_definition" instead of the alias when by_alias=False:
@model_serializer(mode="wrap")
def serialize_model(self, handler):
serialized = handler(self) # Returns {"schema_definition": {...}, ...}
for n, f in type(self).model_fields.items():
k = f.alias or n # k = "schema" (alias)
val = serialized.get(k) # Returns None because key is "schema_definition", not "schema"
Impact:
While API calls work, this inconsistency causes confusion for:
- Debugging/inspecting serialized data
- Logging request payloads
- Testing code that relies on
model_dump()
- Potential breakage if HTTP serialization method changes
Suggested Solutions
Suggested Fix:
The JSONSchema.model_serializer should check for both the alias key and the field name:
@model_serializer(mode="wrap")
def serialize_model(self, handler):
serialized = handler(self)
for n, f in type(self).model_fields.items():
k = f.alias or n
# Try alias first, then field name as fallback
val = serialized.get(k) or serialized.get(n)
# ... rest of logic ...
Python -VV
Pip Freeze
Reproduction Steps
model_dump()withoutby_alias=True:Observe that
json_schema.schemaisnullinstead of containing the schema definition.Compare with
model_dump(by_alias=True):Expected Behavior
hen calling
model_dump()on aResponseFormatobject created withresponse_format_from_pydantic_model(), thejson_schema.schemafield should contain the actual JSON schema definition, notnull. The serialization should work consistently regardless of whetherby_alias=Trueis used.The expected output should be:
{ "type": "json_schema", "json_schema": { "name": "TestModel", "schema": { "type": "object", "properties": { "name": {"type": "string", "description": "A name field"}, "value": {"type": "integer", "description": "A value field"} }, "required": ["name", "value"], "additionalProperties": false }, "strict": true } }Additional Context
Current Behavior:
model_dump()showsschema: nullmodel_dump(by_alias=True)correctly shows the schemamarshal_json()function (used for HTTP requests) internally callsmodel_dump(by_alias=True)Root Cause:
The issue is in
JSONSchema.model_serializer(located inmistralai/models/jsonschema.py). The serializer attempts to retrieve theschema_definitionfield using its alias"schema", buthandler(self)returns a dict with the field name"schema_definition"instead of the alias whenby_alias=False:Impact:
While API calls work, this inconsistency causes confusion for:
model_dump()Suggested Solutions
Suggested Fix:
The
JSONSchema.model_serializershould check for both the alias key and the field name: