Configuration¶
Customize FSPManager behavior with FSPConfig:
from fastapi_fsp import FSPConfig, FSPPresets
# Custom configuration
config = FSPConfig(
max_per_page=50,
default_per_page=20,
strict_mode=True, # Raise errors for unknown fields
max_page=100,
allow_deep_pagination=False,
)
# Or use presets
config = FSPPresets.strict() # strict_mode=True
config = FSPPresets.limited_pagination(max_page=50) # Limit deep pagination
config = FSPPresets.high_volume(max_per_page=500) # High-volume APIs
# Apply configuration
@app.get("/heroes/")
def read_heroes(session: Session = Depends(get_session), fsp: FSPManager = Depends(FSPManager)):
fsp.apply_config(config)
return fsp.generate_response(select(Hero), session)
Search Backend Optimization¶
By default, tokenized search generates N tokens x M fields = N*M individual ILIKE conditions, each requiring a full table scan. For PostgreSQL, you can choose a faster search backend:
| Backend | SQL strategy | Substring match? | Indexable? |
|---|---|---|---|
ILIKE (default) |
N*M individual ILIKEs | Yes | No (full scan) |
TSVECTOR |
to_tsvector @@ to_tsquery |
Prefix only | GIN index |
TRIGRAM |
concat + N ILIKEs | Yes | GIN + pg_trgm |
Key tradeoff: TSVECTOR is fastest (single expression) but only matches word prefixes — "media" matches "Medialaan" but "laan" does not. TRIGRAM preserves full substring semantics while reducing N*M to N operations.
from fastapi_fsp import FSPConfig, SearchBackend
# Use tsvector for fast prefix-matching search (PostgreSQL only)
config = FSPConfig(search_backend=SearchBackend.TSVECTOR)
# Use trigram for full substring search with fewer operations (PostgreSQL only)
config = FSPConfig(search_backend=SearchBackend.TRIGRAM)
# Limit maximum search tokens (default: 10)
config = FSPConfig(
search_backend=SearchBackend.TSVECTOR,
max_search_tokens=5,
)
@app.get("/heroes/")
def read_heroes(
session: Session = Depends(get_session),
fsp: FSPManager = Depends(FSPManager),
):
fsp.apply_config(config)
return fsp.generate_response(select(Hero), session)
Non-search OR groups (mixed operators, phrase mode, custom with_or_filters()) automatically fall back to the standard ILIKE path regardless of the configured backend.
Strict Mode¶
When strict_mode=True, FSPManager raises HTTP 400 errors for unknown filter/sort fields:
# With strict_mode=True, this raises HTTP 400:
# GET /heroes/?field=unknown_field&operator=eq&value=test
# Error: "Unknown field 'unknown_field'. Available fields: age, id, name, secret_name"