Skip to main content

Filterify

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

Test Coverage Package version Code style: black Imports: isort


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)

Source distribution for filterify 0.0.1
File Size Uploaded Provenance
filterify-0.0.1.tar.gz 55.3 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for filterify 0.0.1
File Interpreter ABI Platform
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.

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page