Base64 JSON file inputs
Use the x-speakeasy-base64-input-mode extension to let a JSON string field accept binary IO streams or filesystem paths in addition to a pre-encoded base64 string. The generated SDK base64-encodes non-string inputs at request construction time and the wire payload is always a JSON string.
Supported languages
Implemented for Python only. Other targets currently ignore the extension.
Configuring the extension
Add x-speakeasy-base64-input-mode: file to a JSON string property marked as base64 — either format: byte (OpenAPI 3.0+) or contentEncoding: base64 (OpenAPI 3.1+). Without the extension, the field remains a plain str.
properties:
dataByte:
type: string
format: byte
x-speakeasy-base64-input-mode: file
dataContentEncoding:
type: string
contentEncoding: base64
x-speakeasy-base64-input-mode: fileGenerated Python
Opted-in fields are typed as Base64EncodedString, a pydantic alias that runs a BeforeValidator to convert non-string inputs to a base64 string before storage.
from os import PathLike
from typing import IO, Union
Base64FileInput = Union[IO[bytes], PathLike[str]]
Base64EncodedString = Annotated[str, BeforeValidator(encode_base64_file_input)]The encode_base64_file_input validator accepts:
- A
PathLikevalue — the file at that path is read in binary mode and base64-encoded. - A binary IO object (any
io.IOBasereturningbytes) — the stream is read and base64-encoded. - A
str— passed through unchanged (treated as already encoded).
Any other value raises a TypeError.
The generated request model exposes the field as a plain str after validation, so downstream attribute reads remain statically typed as str even when the same component is reused on the response side.
class Base64InputFileModeRequest(BaseModel):
data_byte: Annotated[Base64EncodedString, pydantic.Field(alias="dataByte")]
data_content_encoding: Annotated[
Base64EncodedString, pydantic.Field(alias="dataContentEncoding")
]SDK methods accept the wider input union at the call site:
def post_base64_input_mode(
self,
*,
data_byte: Union[Base64EncodedString, Union[str, Base64FileInput]],
data_content_encoding: Union[Base64EncodedString, Union[str, Base64FileInput]],
) -> models.operations.PostBase64InputModeResponse:
...Usage
# filesystem path
sdk.post_base64_input_mode(
data_byte=Path("./payload.bin"),
data_content_encoding="dGVzdA==",
)
# open binary stream
with open("./payload.bin", "rb") as fh:
sdk.post_base64_input_mode(data_byte=fh, data_content_encoding=fh)
# pre-encoded base64 string
sdk.post_base64_input_mode(data_byte="dGVzdA==", data_content_encoding="dGVzdA==")Limitations
- Python (
pythonv2) only. - Accepted non-string inputs are restricted to
Union[IO[bytes], os.PathLike].bytesandbytearrayliterals are not auto-encoded; encode them withbase64.b64encode(...).decode("ascii")before passing them in. - Generated SDK methods emit
# type: ignore[arg-type]at the request construction site to bridge the wider method-argument union (Union[str, Base64FileInput]) and the declared field type (str). At runtime theBeforeValidatorconverts the value before thestrvalidator runs, so the suppression is aligned with sound runtime behavior. - Schema components reused across request and response leak the wider input union into the response-side
TypedDict. A hand-built response literal will type-check withBytesIO/PathLikeeven though the wire only ever carries astr. PreferBaseModelattribute access on responses, which stays typed asstr.
Last updated on