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:
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.
Metadata
Release files for filterify 0.0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| filterify-0.0.1.tar.gz | 55.3 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| filterify-0.0.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 65.5 kB
Release files / filterify-0.0.1.tar.gz
| Download URL | filterify-0.0.1.tar.gz |
|---|---|
| Size | 55.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c57b4a703975b5787a1581de5b8ff2941319db38c1abd069dec93f39b16ce39c
|
|
BLAKE2b-256 checksum How to use checksums |
ed1c7023d51bd771877b8ca48ad84f6678b054bbfe6456d2c804f2b9764bcd5a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-requests/2.28.1
|
Release files / filterify-0.0.1-py3-none-any.whl
| Download URL | filterify-0.0.1-py3-none-any.whl |
|---|---|
| Size | 10.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
7e06fd204d92db0f730dbf3e16662e564dabf8732701a6264048358950319a4d
|
|
BLAKE2b-256 checksum How to use checksums |
a768b0b10b41066d82d72f732a41313474ec3c8af7f07a1209b1d24a361164b0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
python-requests/2.28.1
|
Security for filterify 0.0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.