This release is a pre-release and may not be stable for production use.
Flask-Filter
Filtering Extension for Flask / SQLAlchemy
Check out our GitHub Pages site for the full documentation.
Flask-Filter is a simple Flask extension for standardizing behavior of REST API resource search endpoints. It is designed to integrate with the Flask-SQLAlchemy extension and Marshmallow, a popular serialization library.
Out-of-the-box, Flask-Filter provides search functionality on top-level object fields via an array of filter objects provided in the JSON body of a POST request. For configuring filtering on derived or nested fields see the "Filtering on Nested Fields" section of the documentation.
Installation
Flask-Filter is available on PyPi. To use this library, we recommend you install it via pip:
(venv)$ pip install flask-filter
Default Filters
Flask-Filter supports searching resources based on an array of filters, JSON objects with the following structure:
{"field": "<field_name>", "op": "<operator>", "value": "<some_value>"}
The built-in filters support the following operators:
| symbol | operator | python filter class |
|---|---|---|
| < | less-than | LTFilter |
| <= | less-than or equal to | LTEFilter |
| = | equal to | EqualsFilter |
| > | greater-than | GTFilter |
| >= | greater-than or equal to | GTEFilter |
| in | in | InFilter |
| != | not equal to | NotEqualsFilter |
| like | like | LikeFilter |
| contains | many-to-many associated | ContainsFilter |
Note: Be careful with typing around comparator operators. This version does not provide rigorous type-checking, which could cause problems for a user who submits a search like "find Pets with name greater than 'Fido'"
Many-to-many associations can be searched using the contains operator.
For a Dog object with a many-to-many relationship with "favorite toys"
defined as Dog.toys = [Toy(), Toy()], you can set the field to "toys.name",
the operator to "contains" and the value to "Tennis Ball". This will perform
a SQL "any" search on that field / value and return any Dog objects who like
tennis balls.
Examples
This section demonstrates simplified use-cases for Flask-Filter. For
a complete example app (a Pet Store API), see the /example folder.
Note: examples in this readme define simple /search endpoints that
assume a working Flask app has already been initialized, and other
required classes have been defined in a pet_store directory. To see
a full implementation, go to /examples/pet_store
Example 1: Manually implementing filters in a flask view
Using the FilterSchema class directly, you can deserialize an
array of JSON filters into a list of flask_filter.Filter objects
and directly apply the filters using Filter.apply to craft a
SQLAlchemy query with a complex set of filters.
filter_schema = FilterSchema()
pet_schema = PetSchema()
@app.route('/api/v1/pets/search', methods=['POST'])
def pet_search():
filters = filter_schema.load(request.json.get("filters"), many=True)
query = Pet.query
for f in filters:
query = f.apply(query, Pet, PetSchema)
return jsonify(pet_schema.dump(query.all())), 200
Example 2: Automatically filtering using the query_with_filters function
from flask_filter import query_with_filters
pet_schema = PetSchema()
@app.route('/api/v1/pets/search', methods=['POST']
def pet_search():
pets = query_with_filters(Pet, request.json.get("filters"), PetSchema)
return jsonify(pet_schema.dump(pets)), 200
Example 3: Initializing and using the Flask extension object
from flask import Flask
from pet_store import Pet, PetSchema # Model defined as subclass of `db.Model`
from pet_store.extensions import db, filtr # SQLAlchemy and FlaskFilter objects
app = Flask(__name__)
db.init_app(app)
filtr.init_app(app)
@app.route('/api/v1/pets/search', methods=['POST'])
def pet_search():
pets = filtr.search(Pet, request.json.get("filters"), PetSchema)
return jsonify(pet_schema.dump(pets)), 200
or alternatively, if you pre-register the Model and Schema with the
FlaskFilter object you do not need to pass the Schema directly to
the search method:
filtr.register_model(Dog, DogSchema) # Register in the app factory
followed by the search execution (without an explicitly-defined schema):
pets = filtr.search(Pet, request.json.get("filters"))
Example 4: Ordering Search Responses
By default, searches return objects ordered on id, ascending. This behavior
can be customized with the optional order_by argument.
If you don't have an id parameter for your database objects or you wish to
sort by other fields, you should populate the order_by argument to the search
function when you call it.
This approach does not allow API consumers to set the order_by argument, but allows the developer to override the default id ordering.
@app.route('/api/v1/pets/search', methods=['POST'])
def pet_search():
pets = filtr.search(Pet, request.json.get("filters"), PetSchema,
order_by=Pet.name)
return jsonify(pet_schema.dump(pets)), 200
Alternatively, if you wish to allow users to customize the order of the
objects in the response, use a string for the order_by argument.
@app.route('/api/v1/pets/search', methods=['POST'])
def pet_search():
order_by = json.get("orderBy") or "name"
pets = filtr.search(Pet, request.json.get("filters"), PetSchema,
order_by=order_by)
return jsonify(pet_schema.dump(pets)), 200
Metadata
Release files for Flask-Filter 0.1.2a3
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 | Actions |
|---|---|---|---|---|
| Flask-Filter-0.1.2a3.tar.gz | 7.4 kB | Without provenance | Details for Flask-Filter-0.1.2a3.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| Flask_Filter-0.1.2a3-py3-none-any.whl | Python 3 | none | any | Details for Flask_Filter-0.1.2a3-py3-none-any.whl |
Total release size: 15.9 kB
Release files / Flask-Filter-0.1.2a3.tar.gz
| Download URL | Flask-Filter-0.1.2a3.tar.gz |
|---|---|
| Size | 7.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d3c65f44585ca5adaf32a0a1c0999c147b0d07f3abea0b722bd54f7c27955908
|
|
BLAKE2b-256 checksum How to use checksums |
34d4fefebb436a4079c5f6f8ab73b64e9e7e3f74f34521f0d06d4f2e5a0b32e9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.9.14
|
Release files / Flask_Filter-0.1.2a3-py3-none-any.whl
| Download URL | Flask_Filter-0.1.2a3-py3-none-any.whl |
|---|---|
| Size | 8.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e69ec29eb562f108602467515ff73eb42cd658d3429f1f0edeee83bcca3493c5
|
|
BLAKE2b-256 checksum How to use checksums |
ec03a2482b9b76da582a9689684d84b5b730d4bef94e6fc77887fa538fd1296d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/4.0.1 CPython/3.9.14
|
Security for Flask-Filter 0.1.2a3
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.