failed NO_PATCH NO_PATCH UNSUBMITTED empty_patch(None) · None tool calls · 0 s · fastapi/fastapi
♻️ Fix JSON Schema for bytes, use `"contentMediaType": "application/octet-stream"` instead of `"format": "binary"` ♻️ Fix JSON Schema for bytes, use `"contentMediaType": "application/octet-stream"` instead of `"format": "binary"` ## Background `format: binary` was defined in OpenAPI 3.0.x, in OpenAPI 3.1.x the schema was aligned with the latest JSON Schema, recommending instead `contentMediaType: application/octet-stream`. I suspect the JSON Schema for `bytes` using `"format": "binary"` comes from my first implementation in Pydantic 1.x. It was defined and suggested in OpenAPI 3.0.x (not in JSON Schema): https://spec.openapis.org/oas/v3.0.3.html#considerations-for-file-uploads OpenAPI 3.1.x aligned support with JSON Schema draft 07, so it was suggested to upate file uploads to use the regular JSON Schema format: `"contentMediaType": "application/octet-stream"`: https://learn.openapis.org/upgrading/v3.0-to-v3.1 This is defined in JSON Schema 07: https://json-schema.org/draft-07/json-schema-validation#rfc.section.8.4 ### JSON Schema 2020-12 Note Now OpenAPI 3.2 is aligned with JSON Schema 2020-12, which is what Pydantic v2 implements (except for this, I'm implementing it there too). It's the same as in JSON Schema draft 07, so this still applies: https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-01#name-contentmediatype ### Usage in JSON JSON as a format actually doesn't support bytes, everything has to be in UTF-8 strings. Transporting bytes in JSON would require encoding bytes in a string, e.g. with base64. But as JSON Schema is not only defined to declare JSON payloads but also payloads that could have a comparable structure and defined with JSON Schema, it's still there in the spec.
| # | Tool | Arguments | Result |
|---|---|---|---|
| No trace captured. | |||
F
=================================== FAILURES ===================================
________________________ test_list_schema[/list-bytes] _________________________
path = '/list-bytes'
@pytest.mark.parametrize(
"path",
[
"/list-bytes",
"/list-uploadfile",
],
)
def test_list_schema(path: str):
openapi = app.openapi()
body_model_name = get_body_model_name(openapi, path)
> assert app.openapi()["components"]["schemas"][body_model_name] == {
"properties": {
"p": {
"type": "array",
"items": {
"type": "string",
"contentMediaType": "application/octet-stream",
},
"title": "P",
},
},
"required": ["p"],
"title": body_model_name,
"type": "object",
}
E AssertionError: assert {'properties'...y_list_bytes'} == {'properties'...pe': 'object'}
E
E Omitting 3 identical items, use -vv to show
E Differing items:
E {'properties': {'p': {'items': {'type': 'string', 'format': 'binary'}, 'type': 'array', 'title': 'P'}}} != {'properties': {'p': {'type': 'array', 'items': {'type': 'string', 'contentMediaType': 'application/octet-stream'}, 'title': 'P'}}}
E Use -v to get more diff
tests/test_request_params/test_file/test_list.py:36: AssertionError
=============================== warnings summary ===============================
../../../../../../../Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.52.1-py3-none-any/starlette/testclient.py:45
/Users/jp/repos/kaggle-gemini-coding-agent-post-training/.envs/overlays/starlette-0.52.1-py3-none-any/starlette/testclient.py:45: DeprecationWarning: The anyio.abc.BlockingPortal alias is deprecated, use anyio.from_thread.BlockingPortal instead.
_PortalFactoryType = Callable[[], AbstractContextManager[anyio.abc.BlockingPortal]]
-- Docs: https://docs.pytest.org/en/stable/how-to/capture-warnings.html
!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!
1 failed, 1 warning in 0.62s