new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

FastAPI · Advanced · all subjects

advanced python types

17 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Declare optional parameter with Union or Optional

To declare an optional parameter that can accept None, use Union[SomeType, None] from the typing module, or use Optional[SomeType]. In Python 3.10+, you can also use SomeType | None syntax. Example: def say_hi(name: Union[str, None]): print(f"Hi {name}!"). The recommendation is to use Union[SomeType, None] instead of Optional[SomeType] because Union is more explicit about what it means.

Optional vs Union semantic difference for parameter naming

Optional[SomeType] and Union[SomeType, None] are equivalent underneath, but Union is preferred for semantic clarity. The word 'optional' implies the parameter itself is optional (doesn't need to be provided), but Optional[str] actually means the value can be None while the parameter is still required. A function with def say_hi(name: Optional[str]) still requires the parameter to be passed; you cannot call say_hi() without it. The parameter only accepts None as a valid value.

Use Union instead of Optional in response_model

When using type annotations in places like response_model that don't support the | syntax, use Union from the typing module instead of the vertical bar. For example, response_model=Union[str, None] instead of trying to use str | None.

Modern Python union syntax with pipe operator

In most cases with modern Python versions, you can use the | operator to define unions of types directly in annotations. For example: def say_hi(name: str | None): print(f"Hey {name}!"). This is simpler and more readable than Union or Optional.

FastAPI supports standard Python dataclasses for requests and responses

FastAPI allows you to use Python's standard dataclasses module (from the dataclasses library) to declare request bodies and response models, just like Pydantic models. This works because FastAPI uses Pydantic internally, and Pydantic has built-in support for converting standard dataclasses to Pydantic's dataclasses.

Dataclasses support data validation, serialization, and documentation

When using dataclasses with FastAPI, they support the same features as Pydantic models: data validation, data serialization, and automatic documentation generation in the API docs.

Dataclasses can be used in response_model parameter

You can pass a standard dataclass to the response_model parameter of a path operation. FastAPI will automatically convert it to a Pydantic dataclass and its schema will appear in the API documentation.

Use pydantic.dataclasses as drop-in replacement for standard dataclasses

If you encounter issues with automatically generated API documentation when using standard dataclasses in nested structures, you can swap the standard dataclasses import for pydantic.dataclasses, which is a drop-in replacement. Import field from standard dataclasses, but use pydantic.dataclasses for the dataclass decorator itself.

Dataclasses can be combined with type annotations for nested structures

You can combine dataclasses with standard Python type annotations (like List, Dict, etc.) to create complex nested data structures. FastAPI will serialize these mixed structures correctly to JSON in responses.

Dataclasses limitation compared to Pydantic models

Dataclasses cannot do everything that Pydantic models can do. For advanced use cases, you may still need to use Pydantic models instead of dataclasses.

Dataclasses available since FastAPI 0.67.0

Support for using standard Python dataclasses in FastAPI has been available since version 0.67.0.

Pydantic bytes field with val_json_bytes for base64 input validation

You can declare a Pydantic model with bytes fields and use val_json_bytes in the model config to tell Pydantic to validate input JSON data by decoding base64 strings into bytes. When configured this way, the field expects base64 encoded bytes in the JSON request.

Pydantic bytes field with ser_json_bytes for base64 output serialization

You can use bytes fields with ser_json_bytes in the model config for output data, and Pydantic will serialize the bytes as base64 when generating the JSON response.

Pydantic bytes field with both val_json_bytes and ser_json_bytes

You can configure the same Pydantic model to use val_json_bytes for input validation and ser_json_bytes for output serialization to handle both receiving and sending JSON data with base64 encoded bytes.

Base64 encoding efficiency compared to files

Base64 encoding requires more characters than the original binary data, making it normally less efficient than regular file uploads. Use base64 only if you definitely need to include binary data in JSON and cannot use files instead.

JSON format limitation with binary data

JSON can only contain UTF-8 encoded strings and cannot contain raw bytes. Binary data must be encoded as base64 to be included in JSON.

Alternatives to base64 in JSON for binary data

Consider using Request Files for uploading binary data and Custom Response - FileResponse for sending binary data instead of encoding binary data as base64 in JSON.

Give your agent this brain