Query API#

fastapi_restly.query implements list-endpoint filtering, sorting, and pagination: create_list_params_schema() derives the URL parameter schema from a response schema and its model, and apply_list_params() applies validated parameters to a SQLAlchemy select.

fastapi_restly.query.apply_list_params(params: BaseModel | QueryParams, select_query: Select, model: type[DeclarativeBase], schema_cls: type[BaseModel]) Select#

Apply pagination, sorting, and filtering on a SQL query using validated list-endpoint query parameters.

params is normally an instance of the schema returned by create_list_params_schema(). The generated FastAPI endpoints always pass a validated instance, so pagination/filter bounds have already been checked.

A raw QueryParams is also accepted for callers that build the query parameters programmatically. Raw inputs bypass schema validation — the caller is responsible for verifying page/page_size ranges and any per-view bounds (max_page_size); this function only performs the minimum coercion needed to apply the SQL clauses.

Examples:

# Pagination
page=2&page_size=50

# Sorting
sort=name,-created_at

# Filtering
name=Bob&status=active&created_at__gte=2024-01-01

# Contains (string fields)
name__contains=John&email__icontains=example
fastapi_restly.query.create_list_params_schema(schema_cls: type[BaseModel], model: type[DeclarativeBase], *, default_page_size: int = 50, max_page_size: int = 1000, paginated: bool = True) type[BaseModel]#

Create a Pydantic model that describes and validates URL query parameters for list endpoints.

The generated model accepts pagination (page, page_size), sorting (sort), and one filter parameter per response-schema field that maps to a filterable column on model – with optional __in/__ne/__gte/ __lte/__gt/__lt/__isnull/__contains/__icontains suffixes. Fields that do not resolve to a column (relationship/collection fields, or reference traversals the request path would reject) get no filter params, so the generated schema – and the OpenAPI it produces – no longer advertises filters for fields that are not filterable at all. Fields whose type is a collection (dict/list, e.g. JSON or ARRAY columns) generate only __isnull: a query-string value cannot coerce into them, so every other operator would fail at request time.

When paginated is true (the default), page and page_size are added and validated by Pydantic with bounds (page >= 1, 1 <= page_size <= max_page_size); out-of-range values produce a standard 422 response from FastAPI. When it is false, no pagination parameters are emitted at all – the endpoint returns every matching row – while sorting and filtering stay available.

Args:
schema_cls: The response schema whose fields drive the available

filter parameters.

model: The SQLAlchemy model the list endpoint queries. Used to verify

each field resolves to a filterable column; non-column fields are omitted from the generated params.

default_page_size: Default value for the page_size parameter when

the client omits it. Only used when paginated is true.

max_page_size: Upper bound (inclusive) for the page_size

parameter. Defaults to MAX_PAGE_SIZE.

paginated: Whether to emit page/page_size parameters. False for

an unpaginated view, which returns the full result set.

See also

Filter, Sort, and Paginate Lists documents the URL filter, sort, and pagination grammar that these helpers implement.