# pydantic-filters
[![Testing](https://github.com/so-saf/pydantic-filters/actions/workflows/test.yaml/badge.svg)](https://github.com/so-saf/pydantic-filters/actions/workflows/test.yaml)
[![Coverage](https://codecov.io/gh/so-saf/pydantic-filters/branch/master/graph/badge.svg)](https://codecov.io/gh/so-saf/pydantic-filters)
[![pypi](https://img.shields.io/pypi/v/pydantic-filters.svg)](https://pypi.python.org/pypi/pydantic-filters)
[![license](https://img.shields.io/github/license/so-saf/pydantic-filters.svg)](https://github.com/so-saf/pydantic-filters/blob/main/LICENSE)
[![versions](https://img.shields.io/pypi/pyversions/pydantic-filters.svg)](https://github.com/so-saf/pydantic-filters)
**Documentation:** https://so-saf.github.io/pydantic-filters/
**Source Code:** https://github.com/so-saf/pydantic-filters
---
Describe the filters, not implement them!
A declarative and intuitive way to describe data filtering and sorting in your application.
# Features
- Filtering by the models themselves as well as by related.
- Built-in pagination and sorting.
- Lots of settings and possible customizations.
- The only required dependency is Pydantic.
You can use the basic features without being attached to specific frameworks,
or use one of the supported plugins and drivers:
- Plugins:
- FastAPI >= 0.100.0
- Drivers:
- SQLAlchemy >= 2
# Installation
```shell
pip install pydantic-filters
```
# A Simple Example
`BaseFilter` is just a pydantic model, it should be treated similarly
Let's imagine you have a simple user service with the following SQLAlchemy model:
```python
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class User(Base):
__tablename__ = "users"
id: Mapped[int] = mapped_column(primary_key=True)
name: Mapped[str]
age: Mapped[int]
```
Describe how you would like to filter users using BaseFilter.
```python
from typing import List
from pydantic_filters import BaseFilter
class UserFilter(BaseFilter):
id: List[int]
name: List[str]
name__ilike: str
age__lt: int
age__gt: int
```
`BaseFilter` is just a pydantic model, it should be treated similarly
Next, you need to apply a filter to some query:
```python
from sqlalchemy import select
from pydantic_filters.drivers.sqlalchemy import append_filter_to_statement
statement = select(User)
filter_ = UserFilter(name__ilike="kate", age__lt=23)
stmt = append_filter_to_statement(
statement=statement, model=User, filter_=filter_,
)
```
And get something like:
```sql
SELECT users.id, users.name, users.age
FROM users
WHERE users.name ILIKE 'kate' AND users.age < 23
```
The filter can be used in conjunction with one of the supported web frameworks:
```python
from typing import Annotated
from fastapi import FastAPI, APIRouter
from pydantic_filters.plugins.fastapi import FilterDepends
router = APIRouter()
@router.get("/")
async def get_multiple(
filter_: Annotated[UserFilter, FilterDepends(UserFilter)],
):
...
app = FastAPI(title="User Service")
app.include_router(router, prefix="/users", tags=["User"])
```
![fastapi-simple-example.png](docs/docs/images/fastapi-simple-example.png)
Raw data
{
"_id": null,
"home_page": "https://github.com/so-saf/pydantic-filters",
"name": "pydantic-filters",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": null,
"keywords": "pydantic, sqlalchemy, fastapi",
"author": "Nureev Insaf",
"author_email": "uneenymain@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/2d/1b/a3b86e1c8d49af7febb7b0bc0b5734c137cf5528c6d59f688561c7fc89b3/pydantic_filters-0.3.4.tar.gz",
"platform": null,
"description": "\n# pydantic-filters\n\n[![Testing](https://github.com/so-saf/pydantic-filters/actions/workflows/test.yaml/badge.svg)](https://github.com/so-saf/pydantic-filters/actions/workflows/test.yaml)\n[![Coverage](https://codecov.io/gh/so-saf/pydantic-filters/branch/master/graph/badge.svg)](https://codecov.io/gh/so-saf/pydantic-filters)\n[![pypi](https://img.shields.io/pypi/v/pydantic-filters.svg)](https://pypi.python.org/pypi/pydantic-filters)\n[![license](https://img.shields.io/github/license/so-saf/pydantic-filters.svg)](https://github.com/so-saf/pydantic-filters/blob/main/LICENSE)\n[![versions](https://img.shields.io/pypi/pyversions/pydantic-filters.svg)](https://github.com/so-saf/pydantic-filters)\n\n**Documentation:** https://so-saf.github.io/pydantic-filters/\n\n**Source Code:** https://github.com/so-saf/pydantic-filters\n\n---\n\nDescribe the filters, not implement them! \nA declarative and intuitive way to describe data filtering and sorting in your application.\n\n# Features\n\n- Filtering by the models themselves as well as by related.\n- Built-in pagination and sorting.\n- Lots of settings and possible customizations.\n- The only required dependency is Pydantic.\nYou can use the basic features without being attached to specific frameworks, \nor use one of the supported plugins and drivers: \n - Plugins:\n - FastAPI >= 0.100.0\n - Drivers: \n - SQLAlchemy >= 2\n\n# Installation\n\n```shell\npip install pydantic-filters\n```\n\n# A Simple Example\n\n`BaseFilter` is just a pydantic model, it should be treated similarly\n\nLet's imagine you have a simple user service with the following SQLAlchemy model:\n\n\n```python\nfrom sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column\n\n\nclass Base(DeclarativeBase):\n pass\n\n\nclass User(Base):\n __tablename__ = \"users\"\n id: Mapped[int] = mapped_column(primary_key=True)\n name: Mapped[str]\n age: Mapped[int]\n```\n\nDescribe how you would like to filter users using BaseFilter.\n\n```python\nfrom typing import List\nfrom pydantic_filters import BaseFilter\n\n\nclass UserFilter(BaseFilter):\n id: List[int]\n name: List[str]\n name__ilike: str\n age__lt: int\n age__gt: int\n```\n\n`BaseFilter` is just a pydantic model, it should be treated similarly\n\nNext, you need to apply a filter to some query:\n\n```python\nfrom sqlalchemy import select\nfrom pydantic_filters.drivers.sqlalchemy import append_filter_to_statement\n\nstatement = select(User)\nfilter_ = UserFilter(name__ilike=\"kate\", age__lt=23)\n\nstmt = append_filter_to_statement(\n statement=statement, model=User, filter_=filter_,\n)\n```\n\nAnd get something like:\n\n```sql\nSELECT users.id, users.name, users.age \nFROM users \nWHERE users.name ILIKE 'kate' AND users.age < 23\n```\n\nThe filter can be used in conjunction with one of the supported web frameworks:\n\n```python\nfrom typing import Annotated\nfrom fastapi import FastAPI, APIRouter\nfrom pydantic_filters.plugins.fastapi import FilterDepends\n\n\nrouter = APIRouter()\n\n\n@router.get(\"/\")\nasync def get_multiple(\n filter_: Annotated[UserFilter, FilterDepends(UserFilter)],\n):\n ...\n\n\napp = FastAPI(title=\"User Service\")\napp.include_router(router, prefix=\"/users\", tags=[\"User\"])\n```\n\n![fastapi-simple-example.png](docs/docs/images/fastapi-simple-example.png)\n\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "A declarative and intuitive way to describe data filtering and sorting in your application.",
"version": "0.3.4",
"project_urls": {
"Documentation": "https://so-saf.github.io/pydantic-filters/",
"Homepage": "https://github.com/so-saf/pydantic-filters",
"Repository": "https://github.com/so-saf/pydantic-filters"
},
"split_keywords": [
"pydantic",
" sqlalchemy",
" fastapi"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "9d19866cc4e7eabc7911cb63fcb3f271ff95a47d56628d7cc0d64072cb3f2d74",
"md5": "3fc63f3dfa20bf0b8c8e3dbd64486704",
"sha256": "c9d66334eb1248ccf7f4410b9e33fd4acde36b230c8cc5d618a87dfa5422416b"
},
"downloads": -1,
"filename": "pydantic_filters-0.3.4-py3-none-any.whl",
"has_sig": false,
"md5_digest": "3fc63f3dfa20bf0b8c8e3dbd64486704",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.8",
"size": 20412,
"upload_time": "2024-09-30T08:08:56",
"upload_time_iso_8601": "2024-09-30T08:08:56.135793Z",
"url": "https://files.pythonhosted.org/packages/9d/19/866cc4e7eabc7911cb63fcb3f271ff95a47d56628d7cc0d64072cb3f2d74/pydantic_filters-0.3.4-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2d1ba3b86e1c8d49af7febb7b0bc0b5734c137cf5528c6d59f688561c7fc89b3",
"md5": "4d3d2ff1366e7b9724c541e4471af9cb",
"sha256": "4fc6adf212850e8352e5cc90eb6051830e3217127ff0591a862127149e05331c"
},
"downloads": -1,
"filename": "pydantic_filters-0.3.4.tar.gz",
"has_sig": false,
"md5_digest": "4d3d2ff1366e7b9724c541e4471af9cb",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 14611,
"upload_time": "2024-09-30T08:08:58",
"upload_time_iso_8601": "2024-09-30T08:08:58.474105Z",
"url": "https://files.pythonhosted.org/packages/2d/1b/a3b86e1c8d49af7febb7b0bc0b5734c137cf5528c6d59f688561c7fc89b3/pydantic_filters-0.3.4.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-09-30 08:08:58",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "so-saf",
"github_project": "pydantic-filters",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pydantic-filters"
}