filterify 0.0.1

Creator: bradpython12

Last updated:

Add to Cart

Description:

filterify 0.0.1

filterify is a pydantic-based library to handle filters from the query params.















Documentation: https://filterify.boardpack.org
Source Code: https://github.com/boardpack/filterify

Requirements
Python 3.8+
filterify has the next dependencies:

Pydantic

Installation

$ pip install filterify

---> 100%


First steps
To start to work with filterify, you just need to have some Pydantic model you want to have as filters.
Let's define simple Address and Shipment models. Then just pass the Shipment model to the Filterify constructor
and you will get a callable object to parse query params. By default, the parser returns a dictionary structure with
the parsing results.
from pydantic import BaseModel
from filterify import Filterify


class Address(BaseModel):
street: str
city: str
country: str


class Shipment(BaseModel):
name: str
sender: Address
recipient: Address
weight: float


model_filter = Filterify(Shipment)

print(model_filter('name=shoes&sender__country=US&recipient__country__ne=CA'))
# [
# {
# 'field': [
# 'name'
# ],
# 'value': 'shoes',
# 'operation': 'eq'
# },
# {
# 'field': [
# 'sender',
# 'country'
# ],
# 'value': 'US',
# 'operation': 'eq'
# },
# {
# 'field': [
# 'recipient',
# 'country'
# ],
# 'value': 'CA',
# 'operation': 'ne'
# }
# ]

(This script is complete, it should run "as is")
Filterify supports nested models and uses __ as a delimiter for the nested models and operations. If you want to
change it, pass the needed delimiter to the constructor as it's shown in the next example.
from pydantic import BaseModel
from filterify import Filterify


class Address(BaseModel):
country: str


class Shipment(BaseModel):
sender: Address


model_filter = Filterify(Shipment, delimiter='$')

print(model_filter('sender$country$ne=US'))
# [
# {
# 'field': [
# 'sender',
# 'country'
# ],
# 'value': 'US',
# 'operation': 'ne'
# }
# ]

(This script is complete, it should run "as is")
Also, by default unknown fields are ignored, but you can change this behavior by passing False to the constructor
parameter ignore_unknown_name.
from pydantic import BaseModel
from filterify import Filterify


class User(BaseModel):
name: str


model_filter = Filterify(User, ignore_unknown_name=False)

print(model_filter('sender=US'))
# filterify.exceptions.UnknownFieldError: Filter name is not presented in the model: sender

(This script is complete, it should run "as is")
Ordering option
You can add an ordering field that accepts all model field names. Currently, it's used a django-like style when desc
is passed as -field_name.
from pydantic import BaseModel
from filterify import Filterify


class Address(BaseModel):
country: str


class Shipment(BaseModel):
name: str
sender: Address


model_filter = Filterify(Shipment, ordering=True)

print(model_filter('ordering=unknown_field'))
# raises standard pydantic ValidationError with the next message:
# unexpected value; permitted: 'name', '-name', 'sender__country', '-sender__country'

(This script is complete, it should run "as is")
If you want to change the accepted field name list, you can pass a list instead of the True value.
from pydantic import BaseModel
from filterify import Filterify


class Address(BaseModel):
country: str


class Shipment(BaseModel):
name: str
sender: Address


model_filter = Filterify(Shipment, ordering=['name'])

print(model_filter('ordering=unknown_field'))
# raises standard pydantic ValidationError with the next message:
# unexpected value; permitted: 'name', '-name'

(This script is complete, it should run "as is")
Usage with FastAPI
Most validation work is done by pydantic, so filterify can be easily used with FastAPI.
The internal validation model is wrapped by fastapi.Depends and exposed by the as_dependency method.
import uvicorn
from fastapi import FastAPI
from pydantic import BaseModel

from filterify import Filterify


class Address(BaseModel):
street: str
city: str
country: str


class Shipment(BaseModel):
name: str
sender: Address
recipient: Address
weight: float
length: float
height: float


shipment_filter = Filterify(Shipment)


app = FastAPI()


@app.get('/shipments', dependencies=[shipment_filter.as_dependency()])
def shipments():
return []


@app.get('/another_shipments')
def another_shipments(filters=shipment_filter.as_dependency()):
print(filters)
return []


if __name__ == '__main__':
uvicorn.run(app)

(This script is complete, it should run "as is")
Acknowledgments
Special thanks to Sebastián Ramírez and his FastAPI project, some scripts and documentation structure and parts were used from there.
License
This project is licensed under the terms of the MIT license.

License

For personal and professional use. You cannot resell or redistribute these repositories in their original state.

Customer Reviews

There are no reviews.