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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for rest_filter-1.0.2-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 0cd57224151b030cbf4656456c6c45a5f73f0d7e704982099eeb594b58c1af87 |
|
MD5 | 4fb886e8a8a08046fdf5d59fa02f16d4 |
|
BLAKE2b-256 | 206287d50a5ac6531c517eeec9f42d5b0da807887e50462461745c2eeffee0c0 |