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 · Tutorial · all subjects

request-bodies

101 notes in this subject, read out of this brain and free to use. This is page 2 of 2.

Forbid extra form fields support version

The ability to forbid extra form fields in Pydantic models is supported since FastAPI version 0.114.0.

Extra forbidden error response format

When a client sends forbidden extra form fields, the error response contains a detail array with an object having: type 'extra_forbidden', loc array with 'body' and field name, msg 'Extra inputs are not permitted', and input containing the extra value that was sent.

Form data requires python-multipart package

To use forms in FastAPI, you must first install the python-multipart package. Add it to your project with `uv add python-multipart`.

Import Form from fastapi

Form is imported directly from fastapi: `from fastapi import Form`.

Form parameters use same declaration style as Body and Query

Form parameters are declared the same way as Body, Query, Path, and Cookie parameters. They support the same configuration options including validation, examples, and alias.

Form inherits from Body

Form is a class that inherits directly from Body.

Form must be used explicitly for form fields

You must use Form explicitly when declaring form body parameters. Without it, parameters would be interpreted as query parameters or JSON body parameters instead of form fields.

Form data encoding: application/x-www-form-urlencoded

HTML forms normally send data using the media type application/x-www-form-urlencoded. When forms include files, the encoding changes to multipart/form-data.

Cannot mix multiple Form parameters with JSON Body fields

You can declare multiple Form parameters in a path operation, but you cannot also declare Body fields that expect to receive JSON, because the request body will be encoded using application/x-www-form-urlencoded instead of application/json. This is a limitation of the HTTP protocol, not FastAPI.

Declare examples in Pydantic model with json_schema_extra

In Pydantic models, you can declare examples using the `model_config` attribute with a `dict` containing `"json_schema_extra"` and the `examples` key. This adds the examples to the generated JSON Schema, which is used in the API docs.

Declare examples on Field() in Pydantic

When using `Field()` in Pydantic models, you can declare additional `examples` as a parameter to show example data for that field in the generated schema and API docs.

Examples parameter for Path, Query, Header, Cookie, Body, Form, File

The following FastAPI functions support declaring `examples`: Path(), Query(), Header(), Cookie(), Body(), Form(), and File(). Examples declared this way are added to their JSON Schemas inside OpenAPI.

Body with single example using Body()

You can pass an `examples` parameter to `Body()` containing one example of the expected request data. The examples are added to the JSON Schema and displayed in the `/docs` UI.

Body with multiple examples using Body()

You can pass multiple `examples` to `Body()` as part of the internal JSON Schema for that body data. However, Swagger UI does not support displaying multiple examples for data in JSON Schema as of 2023-08-26, though a workaround exists using openapi_examples.

openapi_examples parameter for Path, Query, Header, Cookie, Body, Form, File

FastAPI supports the `openapi_examples` parameter for Path(), Query(), Header(), Cookie(), Body(), Form(), and File(). This parameter accepts a dict where keys identify each example and values are dicts containing optional fields: summary (short description), description (long description with Markdown), value (the actual example data), or externalValue (URL pointing to the example).

openapi_examples displays multiple examples in Swagger UI docs

Using the `openapi_examples` parameter on Body() or other FastAPI functions allows multiple examples to be displayed in the `/docs` Swagger UI, solving the limitation where JSON Schema examples are not shown as multiple examples.

OpenAPI 3.1.0 uses JSON Schema 2020-12 with examples field

OpenAPI 3.1.0, used since FastAPI 0.99.0, is based on JSON Schema 2020-12 and includes support for an `examples` field as part of the JSON Schema standard. The older single `example` field is now deprecated.

FastAPI 0.103.0 renamed example parameter to openapi_examples

As of FastAPI 0.103.0, the old OpenAPI-specific `examples` parameter was renamed to `openapi_examples` for the utilities Path(), Query(), Header(), Cookie(), Body(), File(), and Form().

JSON Schema examples vs OpenAPI-specific examples distinction

JSON Schema's `examples` field is a list of examples added within the JSON Schema object. OpenAPI-specific `examples` (now `openapi_examples`) is a dict with multiple examples and extra metadata (summary, description, value, externalValue) that goes in the path operation declaration outside JSON Schema structures.

Pydantic examples added to JSON Schema and OpenAPI

When you add `examples` inside a Pydantic model using `schema_extra` or `Field(examples=[...])`, the examples are added to the JSON Schema for that Pydantic model, which is then included in the OpenAPI specification and used in the docs UI.

FastAPI does not require SQL database

FastAPI does not require you to use a SQL (relational) database. You can use any database that you want.

SQLModel overview and purpose

SQLModel is built on top of SQLAlchemy and Pydantic. It was made by the same author of FastAPI to be the perfect match for FastAPI applications that need to use SQL databases.

Databases supported by SQLModel

SQLModel is based on SQLAlchemy and supports any database that SQLAlchemy supports, including PostgreSQL, MySQL, SQLite, Oracle, and Microsoft SQL Server.

table=True parameter in SQLModel

The parameter table=True tells SQLModel that a class is a table model, meaning it should represent a table in the SQL database, not just a data model.

Primary key field in SQLModel

Field(primary_key=True) tells SQLModel that a field is the primary key in the SQL database. For primary key fields, use int | None to allow creating objects without an id in Python code, assuming the database will generate it when saving. SQLModel defines such columns as non-null INTEGER in the database schema.

Index field in SQLModel

Field(index=True) tells SQLModel to create a SQL index for a column, which allows faster lookups in the database when reading data filtered by that column.

SQLModel engine purpose

A SQLModel engine (which is actually a SQLAlchemy engine underneath) holds the connections to the database. You would have one single engine object for all your code to connect to the same database.

check_same_thread parameter for SQLite

Using check_same_thread=False allows FastAPI to use the same SQLite database in different threads. This is necessary because one single request could use more than one thread, for example in dependencies.

Session in SQLModel

A Session stores the objects in memory and keeps track of any changes needed in the data, then uses the engine to communicate with the database.

Create database tables on startup

Use an application startup event to create database tables. For production, use a migration script that runs before you start your app.

SQLModel.metadata.create_all() function

Use SQLModel.metadata.create_all(engine) to create the tables for all table models.

SQLModel model as Pydantic model

Each SQLModel model is also a Pydantic model. You can use it in the same type annotations that you could use Pydantic models. If you declare a parameter of type Hero, it will be read from the JSON body. If you declare it as the function's return type, the shape of the data will show up in the automatic API docs UI.

Add object to database session

Use session.add() to add a new object to the Session instance. Then call session.commit() to commit the changes to the database. Call session.refresh() to refresh the data in the object.

Read from database with select() and pagination

Use select() to query the database. You can include limit and offset to paginate the results.

Delete object from database

Use session.delete() to delete an object from the database, then call session.commit() to commit the changes.

SQLModel inheritance for avoiding field duplication

With SQLModel, you can use inheritance to avoid duplicating all the fields in all cases. Table models have table=True, while data models do not have table=True and are actually just Pydantic models.

HeroBase - shared fields pattern

Create a base model like HeroBase that has all the fields that are shared by all the models, such as name and age.

HeroCreate - model for client input validation

Create a HeroCreate data model that validates the data from clients when creating a new hero. This model can receive fields like secret_name that should be stored but not returned to clients.

HeroUpdate - model with all optional fields

Create a HeroUpdate data model for updating a hero. All fields are optional with default values of None. This allows clients to send just the fields they want to update. Use PATCH HTTP operation for updates.

exclude_unset parameter for partial updates

When updating, get a dict with all data sent by the client by using exclude_unset=True. This excludes any values that would be there just for being the default values.

sqlmodel_update() method

Use hero_db.sqlmodel_update(hero_data) to update a table model object with data from a dict.

Give your agent this brain