API Reference#
This page documents:
Generated HTTP endpoints and query behavior.
Key public symbols with brief descriptions.
Full Python API reference generated via Sphinx autodoc.
Generated CRUD Endpoints#
When you register a view with @fr.include_view(app), both fr.AsyncRestView and fr.RestView expose the same default CRUD surface:
Method |
Path |
Purpose |
Default Status |
|---|---|---|---|
|
|
List resources |
|
|
|
Create resource |
|
|
|
Get resource by ID |
|
|
|
Partial update |
|
|
|
Delete resource |
|
Notes:
Update semantics are
PATCH(partial update), notPUT.GET /{id}andDELETE /{id}return404when the object is not found.Read-only schema fields are ignored on create/update.
*_id: IDSchema[Model]inputs are resolved to SQLAlchemy objects and validated against the database. The nestedidaccepts the related primary-key type, such asintorUUID.
Query Parameters (List Endpoint)#
GET /{prefix}/ supports query modifiers through fr.apply_query_modifiers(...).
V1 (JSONAPI-style)#
Filtering:
?filter[name]=John&filter[age]=>21OR-values:
?filter[id]=1,2,3(comma-separated values are OR’d together)Sorting:
?sort=name,-created_atPagination:
?limit=10&offset=20(no limit is applied when omitted)Contains:
?contains[name]=john(multiple space-separated words are AND’d: all must be contained)V1 uses schema field names, not aliases
V2 (HTTP-style)#
Filtering:
?name=John&created_at__gte=2024-01-01Suffixes:
__gte,__lte,__gt,__lt,__ne,__isnull,__contains(string fields only)OR-values:
?id=1,2,3(comma-separated values are OR’d together)Flat aliased fields use the alias name. If
populate_by_name=Trueis enabled, flat fields also accept the Python field name.
Contains:
?name__contains=john(multiple space-separated words are AND’d: all must be contained)%,_, and\\are escaped before building the SQLILIKE
Sorting:
?order_by=name,-created_atPagination:
?page=2&page_size=10Always applied: even with no pagination params, V2 applies
LIMIT 100 OFFSET 0by default.Defaults:
page=1,page_size=100.
Relation-filtering caveat for V2:
The relation segment must still use the schema/model field name
Only nested field segments may use aliases
Example:
?author.authorName=Alicecan work, while?writer.authorName=Alicedoes not
Query Modifier Version Configuration#
The active version is controlled via:
fr.set_query_modifier_version(fr.QueryModifierVersion.V2)— set globallyfr.get_query_modifier_version()— read the current global settingfr.use_query_modifier_version(version)— context manager; preferred for tests and direct low-level helper calls
fr.QueryModifierVersion is an enum with two members: QueryModifierVersion.V1 (default) and QueryModifierVersion.V2.
Views capture the active query-modifier version when they are registered with
@fr.include_view(...). Set the global version before registering the view, or
set query_modifier_version = fr.QueryModifierVersion.V2 on the view class directly
for explicit per-view behavior.
fr.create_query_param_schema(schema_cls) is context-sensitive: it creates a V1 or V2
query-parameter schema depending on the currently active version.
Optional Pagination Metadata#
List endpoints return a JSON array by default. Set include_pagination_metadata = True
on a view to return metadata together with the list items:
{
"items": [],
"total": 123,
"page": 1,
"page_size": 100,
"total_pages": 2,
"limit": 100,
"offset": 0
}
page, page_size, and total_pages are populated when:
The view uses the V2 query interface (always), or
A V1 view receives
?page=or?page_size=as query parameters.
Otherwise on V1 views, those three fields stay null and limit/offset reflect the V1 ?limit=/?offset= parameters if present.
Endpoint Decorators#
Use these decorators on methods in a view class:
Decorator |
HTTP Method |
Default Status |
|---|---|---|
|
|
|
|
|
|
|
|
FastAPI default ( |
|
|
FastAPI default ( |
|
|
|
|
Custom |
As configured |
@fr.get(), @fr.post(), and @fr.delete() explicitly set the default status code shown.
@fr.patch() and @fr.put() set only the HTTP method; FastAPI applies its own default of 200.
Pass status_code= explicitly to either decorator to override.
@fr.put(...) is available for custom endpoints, but default generated update endpoints use PATCH.
Route Exclusion#
To disable generated endpoints on a view, use:
@fr.include_view(app)
class UserView(fr.AsyncRestView):
prefix = "/users"
model = User
exclude_routes = ("delete", "patch")
Valid route names for exclusion: "index", "get", "post", "patch", "delete".
exclude_routes is typed ClassVar[tuple[str, ...]]; a list literal is also accepted at runtime.
Response Modeling#
For generated CRUD endpoints:
Response schema defaults to
schema(or auto-generated schema when omitted).Input schema for
POSTdefaults to schema without read-only fields (creation_schema).Input schema for
PATCHdefaults to optionalized schema (update_schema, viaPatchMixin).Alias-aware serialization is applied so response payload keys follow schema aliases.
Key Public Symbols#
Model Base Classes#
Symbol |
Description |
|---|---|
|
SQLAlchemy declarative base with dataclass semantics and auto snake_case table names. |
|
Convenience alias combining |
|
Extends |
|
Dataclass mixin adding |
|
Alternative declarative base without dataclass semantics. |
|
Convenience alias combining |
|
Extends |
|
Dataclass mixin adding integer |
|
Non-dataclass mixin adding integer |
|
Non-dataclass mixin adding |
|
Return the unique matching row or create it using a sync SQLAlchemy session. |
|
Async variant of |
|
Cascade string for use with |
|
Like |
Schema Classes and Utilities#
Symbol |
Description |
|---|---|
|
Base Pydantic model with |
|
Generic schema that serializes only the |
|
Combines |
|
Pydantic mixin adding read-only |
|
Type annotation marker. Fields annotated |
|
Type annotation marker. Fields annotated |
|
Mixin that strips |
|
Mixin that makes all writable fields optional with |
|
Auto-generate a Pydantic schema from a SQLAlchemy model. |
|
Generate a schema for a view from its model, excluding relationship fields. Used internally by |
|
Walk a schema instance, load |
View Classes#
Symbol |
Description |
|---|---|
|
Base class for all class-based views. Subclass this directly when you do not need CRUD — add endpoints with |
|
Abstract base shared by |
|
Async CRUD view. Use with async SQLAlchemy sessions. |
|
Sync CRUD view. Use with sync SQLAlchemy sessions. |
fr.View class attributes:
Attribute |
Type |
Description |
|---|---|---|
|
|
URL prefix for all routes in the view (e.g. |
|
|
OpenAPI tags. The view class name is always added automatically; set this to add extra tags. |
|
|
FastAPI dependencies applied to every route in the view. |
|
|
OpenAPI response overrides. Defaults to |
View Class Attributes#
Attribute |
Type |
Description |
|---|---|---|
|
|
The primary Pydantic schema for responses. If omitted, auto-generated from |
|
|
Schema for |
|
|
Schema for |
|
|
The SQLAlchemy model class. |
|
|
Primary key type used in generated |
|
|
Set |
|
|
Route names to suppress. |
|
|
Per-view query style override. Defaults to the global setting at registration time. |
View Free Functions#
These module-level functions mirror the instance methods on AsyncRestView / RestView but take an explicit session argument. Use them when you need the same logic outside a view class.
Symbol |
Description |
|---|---|
|
Create a new model instance from a schema, resolve FK |
|
Apply schema fields to an existing ORM object, resolve FK fields, flush, and return the object. |
|
Flush the session and refresh |
Database#
Symbol |
Description |
|---|---|
|
FastAPI |
|
FastAPI |
|
Configure the framework. Accepts async/sync URLs, engines, session makers, or custom session generators. |
|
Return the configured |
|
Return the configured sync |
|
Intended for tests. Wraps the session factory in a savepoint so test data never commits to the database. Each test rolls back instantly without touching the real data. Requires the session maker as argument. |
|
Restore normal session behavior after testing. |
|
Context manager that swaps the global state for test isolation. |
|
Return the current |
Important Limitations and Capabilities#
Nested schemas are supported for responses and relation filtering, including nested aliases
Nested schemas are not supported for create/update payloads; write payloads must still map directly to model fields or use
*_id: IDSchema[Model]fr.PlainBase/fr.PlainIDBasemodels work with generated CRUD viewsUUID and other non-
intprimary keys are supported throughid_typeandIDSchema[Model]
Minimal Example#
import asyncio
import fastapi_restly as fr
from fastapi import FastAPI
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.orm import Mapped
engine = create_async_engine("sqlite+aiosqlite:///app.db")
fr.configure(async_engine=engine)
app = FastAPI()
class User(fr.IDBase):
name: Mapped[str]
@fr.include_view(app)
class UserView(fr.AsyncRestView):
prefix = "/users"
model = User
async def init_models() -> None:
async with engine.begin() as conn:
await conn.run_sync(fr.DataclassBase.metadata.create_all)
asyncio.run(init_models())
Generated endpoints:
GET /users/POST /users/GET /users/{id}PATCH /users/{id}DELETE /users/{id}