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 REST Endpoints#
Register a view with fr.include_view(app, ViewClass) or @fr.include_view(app). fr.AsyncRestView and fr.RestView expose the same generated resource surface:
Method |
Path |
Purpose |
Default Status |
|---|---|---|---|
|
|
List resources |
|
|
|
Create resource |
|
|
|
Get resource by ID |
|
|
|
Partial update |
|
|
|
Delete resource |
|
Notes:
Updates use
PATCH, notPUT. React Admin views also exposePUT /{id}forra-data-simple-rest; see React Admin Integration.GET /{id}andDELETE /{id}return404when the object is not found.Read-only schema fields are ignored on create/update.
*_id: IDRef[Model]inputs are resolved to SQLAlchemy objects and validated. The scalar id is the related primary-key type, such asintorUUID.
Query Parameters (List Endpoint)#
GET /{prefix}/ exposes list parameters derived from the response schema;
keys use public field names (aliases included), and dotted paths filter on
relations. The grammar in one line each — the canonical treatment, including
comma semantics, LIKE escaping, foreign-key filtering, and alias rules, is
Filter, Sort, and Paginate Lists:
Kind |
Form |
|---|---|
Equality / OR |
|
Operators |
|
Relation paths |
|
Sorting |
|
Pagination |
|
Unknown keys |
rejected with |
Low-level helpers#
fr.query.create_list_params_schema(...) and fr.query.apply_list_params(...) power generated list endpoints. Use the view classes for normal CRUD. Call these helpers directly only for custom endpoints that need the same list grammar. Pass a validated params-schema instance, not raw QueryParams.
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": 2,
"page_size": 50,
"total_pages": 3
}
page, page_size, and total_pages are populated only when pagination is active: the client sent ?page= / ?page_size=, or the view set default_page_size. Without pagination, those fields are null.
Endpoint Decorators#
Use these decorators on methods in a view class:
Decorator |
HTTP Method |
Default Status |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Custom |
As configured |
The shorthand decorators explicitly set the default status code shown. Pass status_code= to override it.
Other keyword arguments pass through to FastAPI route registration: response_model=, dependencies=, responses=, tags=, and other APIRouter.add_api_route() options.
@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 = [fr.ViewRoute.DELETE, fr.ViewRoute.UPDATE]
Valid route values for exclusion: fr.ViewRoute.GET_MANY, fr.ViewRoute.GET_ONE, fr.ViewRoute.CREATE, fr.ViewRoute.UPDATE, fr.ViewRoute.DELETE.
exclude_routes accepts ViewRoute values or the equivalent route-shell method names, such as "delete_endpoint".
Response Modeling#
For generated CRUD endpoints:
Response schema defaults to
schema(or an auto-generated*Readschema when omitted).Input schema for
POSTdefaults to schema without read-only fields (schema_create, generated as*Create).Input schema for
PATCHdefaults to optionalized schema (schema_update, generated as*Update).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 |
|
Dataclass mixin adding |
|
Dataclass mixin adding integer |
|
|
Cascade string for use with |
|
Like |
FastAPI-Restly also works with ordinary SQLAlchemy models that inherit from your own DeclarativeBase. Use fr.IDBase for Restly’s dataclass convenience base; bring your own base for standard constructor semantics or existing model layers.
RestView and AsyncRestView assume one scalar resource identifier at /{id}. The column can have another name when you provide explicit schemas and id_type, but the generated CRUD routes, IDSchema, IDRef, React Admin, and OpenAPI identity shape all remain scalar-id contracts. For composite keys, use fr.View and explicit routes such as @fr.get("/{tenant_id}/{slug}").
Schema Classes and Utilities#
Symbol |
Description |
|---|---|
Thin Pydantic base equivalent to |
|
Response-schema base class that adds the resource’s own read-only |
|
Scalar FK reference type. Wire format is the raw id ( |
|
Nested relationship-object field type. Wire format is |
|
Pydantic mixin adding read-only |
|
|
Type annotation marker. Fields annotated |
|
Type annotation marker. Fields annotated |
Auto-generate a Pydantic schema from a SQLAlchemy model. Useful for scaffolding, prototypes, and internal tools; prefer explicit schemas for stable public API contracts. Import from |
View Classes#
Symbol |
Description |
|---|---|
Base class for all class-based views. Subclass this directly when you do not need CRUD — add endpoints with |
|
Supported advanced base class for custom CRUD foundations shared by sync and async views. Import from |
|
Async CRUD view. Use with async SQLAlchemy sessions. |
|
Sync CRUD view. Use with sync SQLAlchemy sessions. |
|
Value object returned by |
|
Async CRUD view that speaks the |
|
Sync variant of |
View Method Surface#
Each CRUD verb on RestView / AsyncRestView is split into three tiers —
route shell (<verb>_endpoint), request handler (handle_<verb>), business
method (<verb>) — so you override the layer that owns your change; the
model and decision table live in
How Overrides Work: The Three Tiers.
Alongside the tiers are cross-cutting override points (build_query,
apply_query_params, count, authorize,
before_commit / after_commit, to_response, snapshot) and domain
utilities you call instead of override (make_new_object, update_object,
save_object, delete_object). make_new_object / update_object are also
the cooperative override point for field stamps.
On AsyncRestView every method below is async; the signatures are otherwise identical.
Tier / kind |
Method |
Signature |
Return |
Purpose |
|---|---|---|---|---|
Route shell |
|
response schema list or pagination envelope |
|
|
Route shell |
|
response schema |
|
|
Route shell |
|
response schema |
|
|
Route shell |
|
response schema |
|
|
Route shell |
|
|
|
|
Request handler |
|
|
Run |
|
Request handler |
|
|
Load through |
|
Request handler |
|
|
Authorize, run |
|
Request handler |
|
|
Load, authorize, snapshot, run |
|
Request handler |
|
|
Load, authorize, snapshot, run |
|
Custom-action bracket |
|
context manager |
|
|
Business method |
|
|
Scoped, filtered, paginated page plus total count, via |
|
Business method |
|
|
Load one row through |
|
Business method |
|
|
Build a new object and save it. Commit-free — the usual create override point. |
|
Business method |
|
|
Apply the update payload to |
|
Business method |
|
|
Delete |
|
Override point |
|
|
Base read query shared by |
|
Override point |
|
|
Apply URL filter/sort/pagination to |
|
Override point |
|
|
Total for the list: receives the same params-applied query and strips |
|
Override point |
|
|
Gate a verb. A no-op by default; override to enforce policy and raise |
|
Override point |
|
|
In-transaction side effect (outbox/audit rows), atomic with the write. |
|
Override point |
|
|
Post-commit side effect (email, webhook, cache invalidation). |
|
Override point |
|
response payload |
The single wire-level response method, called by the route shells with the wire |
|
Override point |
|
|
Frozen capture of an object’s column values at load time, passed as |
|
Helper |
|
response schema |
Validate and serialize an ORM object with Restly’s alias/reference/write-only handling. Override for custom projections or an intentional |
|
Helper |
|
response schema list or pagination envelope |
Serialize a |
|
Helper |
|
pagination envelope |
Serialize a |
|
Domain utility |
|
|
|
Build and stage a new object without flushing. The cooperative override point for stamping extra fields on create — call |
Domain utility |
|
|
|
Apply writable fields without flushing. The cooperative override point for stamping extra fields on update — call |
Domain utility |
|
|
|
Flush and refresh a staged object. Does not commit — |
Domain utility |
|
|
|
Delete and flush an existing object. Does not commit. |
Internal methods prefixed with _, such as _reject_unknown_query_params, are implementation details even though they are visible on instances.
See Class-Based Views for the class hierarchy, Override Endpoints for examples of choosing which tier to override, and Use Type Annotations for the typed signatures of these methods.
View Class Attributes#
On every View (CRUD or not):
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 |
Additional attributes on RestView / AsyncRestView:
Attribute |
Type |
Description |
|---|---|---|
|
The read/response schema. If omitted, auto-generated from |
|
|
Schema for |
|
|
Schema for |
|
|
The SQLAlchemy model class. |
|
|
Scalar primary-key type used in the generated |
|
|
Set |
|
|
Route names to suppress. |
|
|
Query keys to allow on the listing endpoint in addition to those derived from the response schema. Use for view-specific parameters consumed outside |
|
|
Default |
|
|
Upper bound for |
Advanced Object Helpers#
These helpers build, update, delete, and save ORM objects from schemas. Use them outside view instance methods: custom routes, services, workers, or tests. Sync and async variants are exported at the top level and from fastapi_restly.objects.
Symbol |
Description |
|---|---|
|
Build a new |
|
Apply the schema’s writable fields onto an existing ORM |
Flush the session and refresh |
|
Delete |
|
|
Async equivalent of |
|
Async equivalent of |
Async equivalent of |
|
Async equivalent of |
The view methods of the same names (in the
method surface) wrap these helpers, binding
self.session, self.model, and self.schema; reach for the fr.objects
forms in custom routes that touch a model other than self.model, and in
services, workers, or tests.
Database#
Symbol |
Description |
|---|---|
|
FastAPI |
|
FastAPI |
Open an async SQLAlchemy session context manager for use outside request handling, for example in background jobs or scripts. |
|
Open a sync SQLAlchemy session context manager for use outside request handling, for example in background jobs or scripts. |
|
Configure the framework. Accepts async/sync URLs, engines, session makers, custom session generators, and the |
|
Return the configured |
|
Return the configured sync |
Restly has one public process-wide configuration. Configure it once during application startup:
fr.configure(async_database_url="sqlite+aiosqlite:///app.db")
fr.configure(...) must receive at least one setup option: an app, database URL, engine, session maker, custom session generator, or a warn_on_uncommitted / warn_on_misuse setting. A bare fr.configure() raises TypeError.
Pass warn_on_misuse=True to enable opt-in registration-time misuse warnings (fr.exc.RestlyMisuseWarning): include_view then flags route-shell overrides, direct session.commit() calls in view methods, and CRUD route sets hand-rolled on a bare View, each with the idiomatic fix named. Off by default; intended for development, project templates, and CI.
For multiple databases, use FastAPI and SQLAlchemy directly: add a custom dependency on a view, or pass a custom session generator to fr.configure(...). Restly does not provide a public multi-context or multi-engine API. See Use a custom session dependency on one view.
Restly’s write handlers own the commit: each runs before_commit → commit → after_commit around domain logic. Session dependencies do not commit on response; they roll back and close on exit.
A custom write route should use self.write_action(...) or reuse a handle_<verb> — see How Overrides Work. Commit manually only for shapes the bracket does not model, such as a batch write with one final commit.
Restly warns (RestlyUncommittedChangesWarning) when a request finishes with uncommitted session changes — the tell of a custom write route that forgot to commit. Fix the missing commit (write_action(...) or a handle_<verb>), or suppress a deliberate dry run with session.info["_fr_suppress_uncommitted"] = True. The global fr.configure(warn_on_uncommitted=False) opt-out exists but is rarely the right response to the warning.
Exceptions#
There are two families. Configuration errors subclass RestlyError; request-time HTTP errors subclass fastapi.HTTPException via RestlyHTTPError. Typed classes let you target Restly errors with app.add_exception_handler(...) — recipes, the app-wide envelope pattern, and the 422-vs-400 boundary are in Shape Error Responses.
Symbol |
Description |
|---|---|
Base class for FastAPI-Restly framework (configuration-time) errors. |
|
Raised when a public Restly helper needs configuration that has not been set up yet, such as calling |
|
Base for Restly’s request-time HTTP errors. Subclass of |
|
HTTP |
|
HTTP |
|
HTTP |
|
HTTP |
Testing#
Symbol |
Description |
|---|---|
Sync test client wrapper around FastAPI’s |
|
|
Intended for tests. Wraps a session factory in savepoint-only mode so test data never commits to the database. Use it when building your own harness without the shipped fixtures (which implement the same isolation themselves). |
|
Restore normal session behavior after testing. |
Pytest fixtures (auto-loaded by the testing extra; full behavior in
Testing):
Fixture |
Scope |
One-liner |
|---|---|---|
|
function |
Bare |
|
function |
|
|
function |
Savepoint-isolated SQLAlchemy |
|
function |
Async savepoint-isolated session; skips without an async DB. |
|
session |
|
Default Exception Handling#
FastAPI-Restly installs a default handler for SQLAlchemy IntegrityError on FastAPI apps. The handler translates database integrity conflicts — unique constraint, foreign-key, not-null, and check-constraint violations — into HTTP 409 Conflict responses using FastAPI’s normal error body shape:
{
"detail": "Unique constraint violated on user.email"
}
The exact detail text is best-effort and depends on the database driver. The handler recognizes common PostgreSQL SQLSTATE integrity codes and SQLite constraint messages; unknown dialects fall back to a generic conflict message.
Registration is automatic in either of these cases:
fr.configure(app=app, ...)is called with the defaultinstall_default_exception_handlers=True.A view is registered directly on a
FastAPIapp withfr.include_view(app). This fallback covers apps that configure database sessions separately.
Restly skips this default only when the app already has a sqlalchemy.exc.IntegrityError handler. Generic handlers do not block registration.
To opt out:
fr.configure(
app=app,
async_database_url="sqlite+aiosqlite:///app.db",
install_default_exception_handlers=False,
)
To use your own response format, register your IntegrityError handler before Restly installs its defaults:
from fastapi.responses import JSONResponse
from sqlalchemy.exc import IntegrityError
@app.exception_handler(IntegrityError)
async def integrity_error_handler(request, exc):
return JSONResponse(
status_code=409,
content={"error": {"code": "constraint_conflict"}},
)
fr.configure(app=app, async_database_url="sqlite+aiosqlite:///app.db")
Important Limitations and Capabilities#
Nested schemas are supported for responses and relation filtering, including nested aliases
Full nested schemas are not supported for create/update payloads by the default CRUD flow; write payloads must map directly to model fields, or use model-aware reference fields such as
*_id: IDRef[Model]and relationship fields typed asIDSchema[Model]Ordinary SQLAlchemy
DeclarativeBasemodels work with generated CRUD viewsUUID and other non-
intscalar primary keys are supported throughid_type,IDRef[Model], andIDSchema[Model]Composite primary keys are not supported by generated
RestView/AsyncRestViewCRUD routes; usefr.Viewfor custom route shapes