Lightweight library for providing filtering mechanism for your APIs using SQLAlchemy

Overview

example workflow example workflow codecov

sqlalchemy-filters-plus is a light-weight extendable library for filtering queries with sqlalchemy.

Install

pip install sqlalchemy-fitlers-plus

Usage

This library provides an easy way to filter your SQLAlchemy queries, which can for example be used by your users as a filtering mechanism for your exposed models via an API.

Let's define an example of models that will be used as a base query.

from sqlalchemy import Column, Date, Integer, String, ForeignKey
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref

Base = declarative_base()


class User(Base):
    id = Column(Integer, primary_key=True)
    email = Column(String)
    age = Column(Integer)
    birth_date = Column(Date, nullable=False)


class Article(Base):
    id = Column(Integer, primary_key=True)
    title = Column(String)
    user_id = Column(Integer, ForeignKey(User.id), nullable=False)
    user = relationship(
        User,
        uselist=False,
        lazy="select",
        backref=backref("articles", uselist=True, lazy="select"),
    )

Define your first filter

Let's then define our first Filter class for the Article model

from sqlalchemy_filters import Filter, StringField
from sqlalchemy_filters.operators import ContainsOperator


class ArticleFilter(Filter):
    title = StringField(lookup_operator=ContainsOperator)
    email = StringField(field_name="user.email")

    class Meta:
        model = Article
        session = my_sqlalchemy_session

The example above defines a new filter class attached to the Article model, we declared two fields to filter with, title with the lookup_operator ContainsOperator and an email field which points to the user's email, hence the field_name="user.email" without any lookup_operator (default value is EqualsOperator) that will be used to filter with on the database level. We will see other operators that can also be used.

To apply the filter class, we instantiate it and pass it the data(as a dictionary) to filter with.

my_filter = ArticleFilter(data={"email": "[email protected]", "title": "python"})
query = my_filter.apply()  # query is a SQLAlchemy Query object

Please read the full documentation here https://sqlalchemy-filters-plus.readthedocs.io/

You might also like...
flask-apispec MIT flask-apispec (🥉24 · ⭐ 520) - Build and document REST APIs with Flask and apispec. MIT

flask-apispec flask-apispec is a lightweight tool for building REST APIs in Flask. flask-apispec uses webargs for request parsing, marshmallow for res

Flask + marshmallow for beautiful APIs

Flask-Marshmallow Flask + marshmallow for beautiful APIs Flask-Marshmallow is a thin integration layer for Flask (a Python web framework) and marshmal

A template for Flask APIs.
A template for Flask APIs.

FlaskAPITempate A template for a Flask API. Why tho? I just wanted an easy way to create a Flask API. How to setup First, use the template. You can do

Seamlessly serve your static assets of your Flask app from Amazon S3

flask-s3 Seamlessly serve the static assets of your Flask app from Amazon S3. Maintainers Flask-S3 is maintained by @e-dard, @eriktaubeneck and @SunDw

Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.

Flask-Bcrypt Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application. Due to the recent increased prevelance of

A basic JSON-RPC implementation for your Flask-powered sites
A basic JSON-RPC implementation for your Flask-powered sites

Flask JSON-RPC A basic JSON-RPC implementation for your Flask-powered sites. Some reasons you might want to use: Simple, powerful, flexible and python

:rocket: Generate a Postman collection from your Flask application
:rocket: Generate a Postman collection from your Flask application

flask2postman A tool that creates a Postman collection from a Flask application. Install $ pip install flask2postman Example Let's say that you have a

Adds GraphQL support to your Flask application.

Flask-GraphQL Adds GraphQL support to your Flask application. Usage Just use the GraphQLView view from flask_graphql from flask import Flask from flas

A basic JSON-RPC implementation for your Flask-powered sites
A basic JSON-RPC implementation for your Flask-powered sites

Flask JSON-RPC A basic JSON-RPC implementation for your Flask-powered sites. Some reasons you might want to use: Simple, powerful, flexible and python

Comments
  • ArgumentError on pre-joined query

    ArgumentError on pre-joined query

    I'm not totally sure what's causing this so apologies for the somewhat vague issue. Hopefully you'll have a better idea!

    I have a query with a couple of joins on it already and when I attempt to filter it, I'm getting the following exception:

      File "/usr/local/lib/python3.9/site-packages/sqlalchemy_filters/filters.py", line 563, in apply
        query = self._apply_join(query)
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy_filters/filters.py", line 364, in _apply_join
        if is_already_joined(query, join[0]):
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy_filters/utils.py", line 37, in is_already_joined
        return join_table in [_[0] for _ in query._legacy_setup_joins]
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy/sql/operators.py", line 366, in __eq__
        return self.operate(eq, other)
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/attributes.py", line 317, in operate
        return op(self.comparator, *other, **kwargs)
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/relationships.py", line 1302, in __eq__
        self.property._optimized_compare(
      File "/usr/local/lib/python3.9/site-packages/sqlalchemy/orm/relationships.py", line 1690, in _optimized_compare
        raise sa_exc.ArgumentError(
    sqlalchemy.exc.ArgumentError: Mapped instance expected for relationship comparison to object.   Classes, queries and other SQL elements are not accepted in this context; for comparison with a subquery, use DataSource.owner.has(**criteria).
    
    opened by TWeatherston 3
  • Using filter on query with a join creates a duplicate join

    Using filter on query with a join creates a duplicate join

    I have these two related models eg:

    class Organisation(Base):
        __tablename__ = "organisations"
        id = Column(INTEGER, primary_key=True)
        name = Column(VARCHAR(64))
    
    
    class User(Base):
        __tablename__ = "users"
        id = Column(INTEGER, primary_key=True)
        name = Column(VARCHAR(64))
        email = Column(VARCHAR(64))
        organisation_id = Column(Integer, ForeignKey("organisations.id"))
        organisation = relationship("Organisation")
    

    And then a filter for filtering users:

    class UserFilter(Filter):
        name = Field()
        email = Field(lookup_operator=ContainsOperator)
        organisation = Field(field_name="organisation.name")
    
        class Meta:
            model = User
    

    If I then create a query with a join and attempt to apply the filter to the query:

    query = db_session.query(User).join(Organisation)
    my_filter = UserFilter(data={"organisation": "test_org"}, query=query)
    query = my_filter.apply()
    print(str(query))
    

    It creates this second joining of the organisations table:

    SELECT 
        users.id AS users_id, 
        users.name AS users_name, 
        users.email AS users_email, 
        users.organisation_id AS users_organisation_id
    FROM users 
        JOIN organisations ON organisations.id = users.organisation_id
        JOIN organisations ON organisations.id = users.organisation_id
    WHERE organisations.name = ?
    
    opened by TWeatherston 1
  • Ordering by UnaryExpression raises TypeError

    Ordering by UnaryExpression raises TypeError

    Hey,

    Really love the package, great work! :+1:

    I've just been having some difficulty using the order_by with a UnaryExpression. Example from the docs:

    MyFilter(data={"order_by": User.first_name.asc()})
    

    This results in:

    TypeError: Boolean value of this clause is not defined

    It seems that this is the offending line. Would it be possible to get this changed to something like this?

    order_by = self.data.get("order_by", self._order_by)
    

    Here's a minimal working example that I was using to test this:

    from sqlalchemy import Column, VARCHAR, INTEGER, create_engine
    from sqlalchemy.orm import declarative_base, Session
    from sqlalchemy_filters import Filter, Field
    
    
    Base = declarative_base()
    
    
    class User(Base):
        __tablename__ = "users"
        id = Column(INTEGER, primary_key=True)
        name = Column(VARCHAR(64))
        email = Column(VARCHAR(64))
    
    
    class UserFilter(Filter):
        name = Field()
    
        class Meta:
            model = User
    
    
    engine = create_engine("sqlite://")
    with Session(engine) as session:
        query = session.query(User)
        my_filter = UserFilter(data={"order_by": User.name.desc()}, query=query)
        query = my_filter.apply()
    

    Thanks!

    opened by TWeatherston 1
  • Doesn't seem to apply the specific filter

    Doesn't seem to apply the specific filter

    Hi, Using your library, and this seemed to be not filtering with address_id and business_id base_filter = ScreeningHistoryFilter(data={"address_id":f"{address_id}", "business_id":f"{business_id}", "page":pagination_params.page_index, "page_size": pagination_params.page_size, "order_by": sort_params.sort_fields}, session= self.db)

    Below is the filter class: `class ScreeningHistoryFilter(Filter): address_id: Field() business_id: Field() # start_range: DateTimeField(field_name ='create_tz', lookup_operator = GTEOperator) # end_range: DateTimeField(field_name ='create_tz', lookup_operator = LTEOperator)

    class Meta:
        model = V_Address_Screening_History`
    
    opened by jaballe 4
Releases(1.1.5)
Owner
Karami El Mehdi
Karami El Mehdi
Serve angular production application from python flask backend. Quick and Easy

Serve angular production application from python flask backend. Quick and Easy

mark 1 Dec 01, 2022
PatientDB is a flask app to store patient information.

PatientDB PatientDB on Heroku "PatientDB is a simple web app that stores patient information, able to edit the information, and able to query the data

rbb 2 Jan 31, 2022
Flask-app scaffold, generate flask restful backend

Flask-app scaffold, generate flask restful backend

jacksmile 1 Nov 24, 2021
A weather report application build with Python, Flask, and Geopy.

A weather report application build with Python, Flask, and Geopy. Requirements Python 3

Brandon Wallace 6 May 07, 2022
Rich implementation for Flask

Flask Rich Implements the Rich programming library with Flask. All features are toggleable, including: Better logging Colorful tracebacks Usage Import

BD103 13 Jun 06, 2022
Control YouTube, streaming sites, media players on your computer using your phone as a remote.

Media Control Control Youtube, streaming sites, media players on your computer using your phone as a remote. Installation pip install -r requirements.

Shreyas Daniel 10 Dec 08, 2022
A flask template with Bootstrap 4, asset bundling+minification with webpack, starter templates, and registration/authentication.

cookiecutter-flask A Flask template for cookiecutter. (Supports Python ≥ 3.6) See this repo for an example project generated from the most recent vers

4.3k Jan 06, 2023
:rocket: Generate a Postman collection from your Flask application

flask2postman A tool that creates a Postman collection from a Flask application. Install $ pip install flask2postman Example Let's say that you have a

Numberly 137 Nov 08, 2022
This is a API/Website to see the attendance recorded in your college website along with how many days you can take days off OR to attend class!!

Bunker-Website This is a GUI version of the Bunker-API along with some visualization charts to see your attendance progress. Website Link Check out th

Mathana Mathav 11 Dec 27, 2022
a flask profiler which watches endpoint calls and tries to make some analysis.

Flask-profiler version: 1.8 Flask-profiler measures endpoints defined in your flask application; and provides you fine-grained report through a web in

Mustafa Atik 718 Dec 20, 2022
Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application.

Flask-Bcrypt Flask-Bcrypt is a Flask extension that provides bcrypt hashing utilities for your application. Due to the recent increased prevelance of

Max Countryman 310 Dec 14, 2022
Basic flask system for login, api, and status system

Flask Multi Site With Login This is a basic website login system with an uncomplete api system NOTICE : This is NOT complete and is made to be a bare

MrShoe 0 Feb 02, 2022
An python flask app with webserver example

python-flask-example-keepalive How it works? Basically its just a python flask webserver which can be used to keep any repl/herokuapp or any other ser

KangersHub 2 Sep 28, 2022
Seamlessly serve your static assets of your Flask app from Amazon S3

flask-s3 Seamlessly serve the static assets of your Flask app from Amazon S3. Maintainers Flask-S3 is maintained by @e-dard, @eriktaubeneck and @SunDw

Edd Robinson 188 Aug 24, 2022
SeaSurf is a Flask extension for preventing cross-site request forgery (CSRF).

Flask-SeaSurf SeaSurf is a Flask extension for preventing cross-site request forgery (CSRF). CSRF vulnerabilities have been found in large and popular

Max Countryman 183 Dec 28, 2022
Sample Dockerized flask app deployed on Kubernetes on Azure using AKS

Sample Dockerized flask app deployed on Kubernetes on Azure using AKS

Ahmed khémiri 22 Sep 08, 2021
An Instagram Clone using Flask, Python, Redux, Thunk, React

An Instagram Clone using Flask, Python, Redux, Thunk, React

1 Dec 09, 2021
Set up a modern flask web server by running one command.

Build Flask App · Set up a modern flask web server by running one command. Installing / Getting started pip install build-flask-app Usage build-flask-

Kushagra Bainsla 5 Jul 16, 2022
Flask RESTful Web services using API to communicate between client and server.

Welcome! Open up two terminals, one for client and for server each Terminal 1 Terminal 2 Now navigate to the CW2_code directory in both like so $ cd C

Sehra Elahi 1 Nov 23, 2021
Flask-Rebar combines flask, marshmallow, and swagger for robust REST services.

Flask-Rebar Flask-Rebar combines flask, marshmallow, and swagger for robust REST services. Features Request and Response Validation - Flask-Rebar reli

PlanGrid 223 Dec 19, 2022