Skip to main content

A query string parsing library for REST server queries

Project description

rest-filter

rest-filter aims to ba a light weight fast parser written in pure Python, meant for use in REST API servers. It was inspired by the OData standard, but this query is a bit simpler and less feature rich.

Goals

  • An easily extendable querying syntax
  • Be able to query any data source by writing a simple translator
  • Usable in any Python REST framework

Installation

pip install rest-filter

Example usage

Here is an example of the most basic usage

from rest_filter.encoder.common import encoder
from rest_filter.translator import get_mongo_translator

# The raw input expression
expression = r"((age gt 20) and (age ge 10))"

# Generate the encoded expression
encoded_expression = encoder.encode_expression(expression)
print(encoded_expression)

# Translate into a mongo query
mongo_query = get_mongo_translator().translate(encoded_expression)
print(mongo_query)

The resulting encoded expression looks like this:

And(operands=[
    GraterThan(field=Field(name='age'), value=20.0), 
    GraterEqualsTo(field=Field(name='age'), value=10.0)
])

And the resulting mongo query looks like this:

{
    '$and': [
        {'age': {'$gt': 20.0}}, 
        {'age': {'$ge': 10.0}}
    ]
}

This uses the default pre built expression encoding elements & the pre build translation elements. you can add additional elements like this:

import re

from rest_filter.encoder.common import encoder, And
from rest_filter.encoder import BinaryOperation
from rest_filter.translator import get_mongo_translator


mongo_translator = get_mongo_translator()
encoder.register_binary_logical_operator('&&')(And)


@encoder.register_ratio('contains')
class Contains(BinaryOperation):
    pass


@mongo_translator.register_binary_operation_translator(Contains)
def translate_equals(operation: Contains):
    return {
        operation.field.name: f'/{re.escape(operation.value)}/'
    }


# The raw input expression
expression = r"((age gt 20) && (name contains 'a string with special **^^ chars'))"

# Generate the encoded expression
encoded_expression = encoder.encode_expression(expression)
print(encoded_expression)

# Translate into a mongo query
mongo_query = get_mongo_translator().translate(encoded_expression)
print(mongo_query)

If you want you can forgo the pre loaded encoder & translator objects and create ones of your one with completely custom elements:

from rest_filter.encoder import Encoder
from rest_filter.encoder import BooleanOperation, BinaryOperation

from rest_filter.translator import get_mongo_translator, Translator

encoder = Encoder()


# Register encoders
@encoder.register_binary_logical_operator('and')
class And(BooleanOperation):
    pass


@encoder.register_ratio('eq')
class Equals(BinaryOperation):
    pass

@encoder.register_type(r'-?\d+')
def number(text: str):
    return int(text)

mongo_translator = get_mongo_translator()

# Register translators
@mongo_translator.register_boolean_operation_translator(And)
def translate_and(operation: And, translator: Translator):
    return {
        '$and': [
            translator.translate(operand) for operand in operation.operands
        ]
    }


@mongo_translator.register_binary_operation_translator(Equals)
def translate_equals(operation: Equals):
    return {
        operation.field.name: {
            '$eq': operation.value
        }
    }

expression = "((age eq 3) and (height eq 18))"

# Generate the encoded expression
encoded_expression = encoder.encode_expression(expression)
print(encoded_expression)

# Translate into a mongo query
mongo_query = mongo_translator.translate(encoded_expression)
print(mongo_query)

Limitations

  • Expressions can only be parentheses complete (for now). For example, these expressions are not allowed:
    • age gt 10 and name eq 'eric' and city eq 'tlv'
    • (age gt 10 and name eq 'eric' and city eq 'tlv')
    • (age gt 10) and (name eq 'eric') and (city eq 'tlv')
      But this expression is valid:
    • (((age gt 10) and (name eq 'eric')) and (city eq 'tlv'))
  • You cannot register new value types (for now), you must use the prebuilt boolean, string or number values

Encoder Translator design

This utility is separated into two parts: Encoder & Translator

Encoder

The encoder is responsible for parsing the input string into a structured expression object, that can be easily read & parsed by code

The encoder can encodes grammar elements that are registered to it. each registered grammar is a ratio between a field & a value, or a logical operation between two logical values or expressions

Translator

The translator translates the generic expression format given from the encoder into a target language.
There is a basic mongo translator built into this package (more yet to come), but you can easily write a translator of your own.

Contributors

  • Sagiv Oulu

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rest-filter-1.0.2.tar.gz (9.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rest_filter-1.0.2-py3-none-any.whl (10.6 kB view details)

Uploaded Python 3

File details

Details for the file rest-filter-1.0.2.tar.gz.

File metadata

  • Download URL: rest-filter-1.0.2.tar.gz
  • Upload date:
  • Size: 9.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/52.0.0 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.6.12

File hashes

Hashes for rest-filter-1.0.2.tar.gz
Algorithm Hash digest
SHA256 da96bc59f3a9421fc42856b7e1269684db6e2a4482bc4c42cc0489d814a533a7
MD5 583d1eb7f0b8dea570fd3e35fec288cd
BLAKE2b-256 587da0a0375d81e94dffee03696d221c472a3d8b08d65f08f271177e114dafe4

See more details on using hashes here.

File details

Details for the file rest_filter-1.0.2-py3-none-any.whl.

File metadata

  • Download URL: rest_filter-1.0.2-py3-none-any.whl
  • Upload date:
  • Size: 10.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.3.0 pkginfo/1.7.0 requests/2.25.1 setuptools/52.0.0 requests-toolbelt/0.9.1 tqdm/4.56.0 CPython/3.6.12

File hashes

Hashes for rest_filter-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 0cd57224151b030cbf4656456c6c45a5f73f0d7e704982099eeb594b58c1af87
MD5 4fb886e8a8a08046fdf5d59fa02f16d4
BLAKE2b-256 206287d50a5ac6531c517eeec9f42d5b0da807887e50462461745c2eeffee0c0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page