Skip to main content

A filter library for FastAPI with SQLAlchemy support.

Project description

fastapi_advanced_filters

PyPI package name: fastapi_advanced_filters.

Type-safe, declarative filtering for FastAPI with first-class SQLAlchemy support.

  • Define filters once, map them to SQLAlchemy columns, and get query conditions, sorting, selection, and q-search out of the box.
  • Pydantic v2 models with a metaclass generate the filter schema from a simple FilterConfig.
  • Dialect-agnostic SQL assertions in tests via compiled literal SQL.

Installation

Python 3.9+ is supported.

Using pip:

pip install fastapi_advanced_filters

If you plan to use SQLAlchemy features, install the extra:

pip install "fastapi_advanced_filters[sqlalchemy]"

With Poetry:

poetry add fastapi_advanced_filters
# or, with extras
poetry add fastapi_advanced_filters -E sqlalchemy

Quickstart

Define your SQLAlchemy model and a filter class. The filter class uses an inner FilterConfig to describe the fields and behaviors.

from sqlalchemy import Column, Integer, String, Boolean, Date
from sqlalchemy.orm import declarative_base

from fastapi_advanced_filters import (
	BaseFilter,
	FieldCriteria,
	LogicalOperator,
	OperationEnum,
	PaginationEnum,
	QSearch,
	Selectable,
	SortBy,
)

Base = declarative_base()

class User(Base):
	__tablename__ = "users"
	id = Column(Integer, primary_key=True)
	first_name = Column(String)
	last_name = Column(String)
	age = Column(Integer)
	is_working = Column(Boolean)
	birthday = Column(Date)


class UserFilter(BaseFilter):
	class FilterConfig:
		model = User
		pagination = PaginationEnum.OFFSET_BASED
		# Map sortable and selectable attributes by name
		sort_by = SortBy(
			model_attrs={
				"first_name": User.first_name,
				"age": User.age,
			},
			alias_as_camelcase=True,
		)
		select_only = Selectable(
			model_attrs={
				"first_name": User.first_name,
				"age": User.age,
			},
			alias_as_camelcase=True,
		)
		# Free-text search across multiple columns
		q_search = QSearch(
			model_attrs=[User.first_name, User.last_name],
			op=OperationEnum.ILIKE,
			logical_op=LogicalOperator.OR,
		)
		# Field-level filtering rules
		fields = [
			FieldCriteria(
				name="first_name",
				field_type=str,
				model_attr=User.first_name,
				op=(OperationEnum.EQ, OperationEnum.ILIKE),
			),
			FieldCriteria(
				name="age",
				field_type=int,
				model_attr=User.age,
				op=(OperationEnum.GTE, OperationEnum.LTE, OperationEnum.IN),
			),
		]

# Use it
f = UserFilter(
	user__first_name__ilike="ali",
	age__gte=18,
	sort_by="-age",
	select="firstName,age",
	q_search="ali",
)
result = f.get_filter_model()
print(result.filters)          # list of SQLAlchemy conditions
print(result.sorting)          # list of (column, direction)
print(result.selected_columns) # mapped selected columns
print(result.q_search)         # OR/AND expression for search
print(result.pagination)       # limit/offset or page/page_size

FastAPI integration

from fastapi import Depends, FastAPI
from sqlalchemy.orm import Session

app = FastAPI()

@app.get("/users")
def list_users(filters: UserFilter = Depends(), db: Session = Depends(get_db)):
	q = db.query(User)
	model = filters.get_filter_model()
	if model.filters:
		q = q.filter(*model.filters)
	if model.q_search is not None:
		q = q.filter(model.q_search)
	if model.sorting:
		for col, direction in model.sorting:
			q = q.order_by(direction(col)) if callable(direction) else q.order_by(col)
	if model.selected_columns:
		q = q.with_entities(*model.selected_columns)
	if model.pagination:
		q = q.limit(model.pagination.limit).offset(model.pagination.offset)
	return q.all()

Documentation

Full docs index:

Direct links:

  • Installation — How to install and optional extras
  • API reference — FilterConfig, FieldCriteria, QSearch, SortBy, Selectable, Pagination
  • Examples — End-to-end examples
  • Extending — Adding operations, custom filters, advanced usage
  • Types — Enums and core dataclasses overview

Development

  • Run tests: pytest -q
  • Lint/type: pre-commit run --all-files
  • Python: 3.9+

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fastapi_advanced_filters-0.1.0.tar.gz (13.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fastapi_advanced_filters-0.1.0-py3-none-any.whl (22.4 kB view details)

Uploaded Python 3

File details

Details for the file fastapi_advanced_filters-0.1.0.tar.gz.

File metadata

  • Download URL: fastapi_advanced_filters-0.1.0.tar.gz
  • Upload date:
  • Size: 13.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fastapi_advanced_filters-0.1.0.tar.gz
Algorithm Hash digest
SHA256 295b6ba59d9a608eb484959efef7ead2186fc59b1defa701dcd65895486899b5
MD5 e6f8f92fbcb208b859324c289f744eb8
BLAKE2b-256 92fb38e89b912dd527db8390500898225f090c7b1de11bc481ac41e0cfeee697

See more details on using hashes here.

File details

Details for the file fastapi_advanced_filters-0.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for fastapi_advanced_filters-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 3800eec81e0791363bf5449395f3c86cc91d3542e2c3deb96885fac30abab886
MD5 b1532ebea64941bdd724767d0da1c560
BLAKE2b-256 541e7453ceca2c1cc4af21226ebde53c614e4ad3a088a2a25e231ff8008b1098

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page