FIQL Parser API

© Copyright 2014 Serge Domkowski.

Note

This code includes a few modifications to rules in the FIQL draft.

The rule defined for Comparison has been modified to deal with an inconsistency in the draft documentation. The change fixes an issue where the string “==” was NOT a valid Comparison and thus made most of the examples in the FIQL draft incorrect.

The accepted arg chars have been modified to include “:”. This change fixes the issue where RFC 3339 compliant DateTime values were not valid unless the “:” was percent-encoded. This contradicted the FIQL draft date_str examples. Since “:” is a valid character in an HTTP query *( pchar / "/" / "?" ), I opted to fix the issue by simply allowing the “:” in addition to the other arg chars.

Constants

Compiled and uncompiled regular expressions representing the various syntax rules used in the FIQL specification.

fiql_parser.constants.PCT_ENCODING_REGEX

Regular expression representing Percent-Encoding (RFC 3986#section-2.1).

fiql_parser.constants.UNRESERVED_REGEX

Regular expression repesenting Unreserved Characters (RFC 3986#section-2.3).

fiql_parser.constants.FIQL_DELIM_REGEX

Regular expression representing the FIQL Delimiter (FIQL Draft#section-3.2).

fiql_parser.constants.COMPARISON_REGEX

Regular expression representing the FIQL Comparison operator; e.g., “=gt=” (FIQL Draft#section-3.2). This rule includes a modification to the rule in the FIQL draft that correctly allows for a string with no ALPHA characters (Example: “==”).

fiql_parser.constants.SELECTOR_REGEX

Regular expression representing the FIQL Selector (FIQL Draft#section-3.2). The Selector identifies the portion of an entry that a Constraint applies to.

fiql_parser.constants.ARG_CHAR_REGEX

Regular expression representing the characters allowed in a FIQL Argument (FIQL Draft#section-3.2). This rule includes a modification to the rule in the FIQL draft that allows for “:” in arguments (Example: “2015-08-27T10:30:00Z”).

fiql_parser.constants.ARGUMENT_REGEX

Regular expression represeting the FIQL Argument (FIQL Draft#section-3.2). The Argument identifies the value that the Comparison operator should use when validating the Constraint.

fiql_parser.constants.CONSTRAINT_REGEX

Regular expression representing the FIQL Constraint (FIQL Draft#section-3.2). The Constraint, when processed, yields a boolean value.

fiql_parser.constants.CONSTRAINT_COMP

Compiled version of CONSTRAINT_REGEX.

fiql_parser.constants.COMPARISON_COMP

Compiled version of CONSTRAINT_REGEX as a full string.

fiql_parser.constants.COMPARISON_MAP

Mappings for common FIQL comparisons.

Type:dict

Exceptions

The code in this package is intended to be used in one of two ways; Building the object representation of a FIQL expression directly, or building the object representation of a FIQL expression by parsing it from a FIQL string.

The Exception classes contained in this module are intended to provide the flexibility to differentiate between errors resulting from attempting to construct the expression object and those resulting from incorrectly formatted FIQL strings.

exception fiql_parser.exceptions.FiqlException

Bases: exceptions.Exception

Base Exception class for FIQL errors.

exception fiql_parser.exceptions.FiqlFormatException

Bases: fiql_parser.exceptions.FiqlParserException

Exception class for FIQL string parsing errors.

exception fiql_parser.exceptions.FiqlObjectException

Bases: fiql_parser.exceptions.FiqlException

Exception class for FIQL expression object errors.

exception fiql_parser.exceptions.FiqlParserException

Bases: fiql_parser.exceptions.FiqlException

Exception class for FIQL input parsing errors.

Operator

FIQL has two operators. “;” which is the logical AND and “,” for the logical OR where AND has a logical precedence which is higher than that of OR.

The operator module includes the code used for managing comparison operator acceptance, precedence, and representation of the FIQL Operator.

fiql_parser.operator.OPERATOR_MAP

Mappings of FIQL operators to common terms and their associated precedence.

Type:dict of tuple
fiql_parser.operator.REV_OPERATOR_MAP

Reverse mappings for common FIQL operators.

Type:dict
class fiql_parser.operator.Operator(fiql_op_str)

Bases: object

The comparison Operator is the representation of the FIQL comparison operator.

value

The FIQL operator.

Type:string
to_python()

Deconstruct the Operator instance to a string.

Returns:The deconstructed Operator.
Return type:string

Constraint

The FIQL Constraint is the building block of the FIQL Expression. A FIQL Constraint is, on its own, a very simple Expression.

The constraint module includes the code used for managing comparison acceptance and representation of the FIQL Constraint.

fiql_parser.constraint.REV_COMPARISON_MAP

Reverse mappings for common FIQL comparisons.

Type:dict
class fiql_parser.constraint.Constraint(selector, comparison=None, argument=None)

Bases: fiql_parser.expression.BaseExpression

The Constraint is the smallest logical unit for a FIQL Expression. It itself must evaluate to True or False and contains no smaller unit which itself can evaluate to True or False.

selector

Constraint selector.

Type:string
comparison

Constraint comparison operator.

Type:string
argument

Constraint argument.

Type:string
op_and(*elements)

Create an Expression using this Constraint and the specified additional elements joined using an “AND” Operator

Parameters:*elements (BaseExpression) – The Expression and/or Constraint elements which the “AND” Operator applies to in addition to this Constraint.
Returns:
Newly created Expression including this
Constraint, the elements passed in, and the “AND” Operator.
Return type:Expression
op_or(*elements)

Create an Expression using this Constraint and the specified additional elements joined using an “OR” Operator

Parameters:*elements (BaseExpression) – The Expression and/or Constraint elements which the “OR” Operator applies to in addition to this Constraint.
Returns:
Newly created Expression including this
Constraint, the elements passed in, and the “OR” Operator.
Return type:Expression
to_python()

Deconstruct the Constraint instance to a tuple.

Returns:The deconstructed Constraint.
Return type:tuple

Expression

It would be very difficult to build a FIQL Expressions without taking into account the Expressions part of it.

The expression module includes the code used for ensuring that any FIQL Expression created with this package is a valid FIQL Expression.

class fiql_parser.expression.BaseExpression

Bases: object

Both Constraint and Expression classes extend the BaseExpression class. A FIQL Constraint is a simple FIQL Expression. As such, they share certain attributes.

Note

The parent of any child of BaseExpression is always an Expression. This is a bit contrary to what might be expected as an Expression itself is a child class of BaseExpression.

This quark is a side effect of the definition of the FIQL Constraint. A FIQL Constraint can not be contained within another FIQL Constraint as a sub-expression. Both a FIQL Constraint and FIQL Expression can only be sub-expressions of an actual FIQL Expression.

parent

The Expression which contains this object.

Type:Expression
get_parent()

Get the parent Expression for this object.

Returns:The Expression which contains this object.
Return type:Expression
Raises:FiqlObjectException – Parent is None.
set_parent(parent)

Set parent Expression for this object.

Parameters:parent (Expression) – The Expression which contains this object.
Raises:FiqlObjectException – Parent must be of type Expression.
class fiql_parser.expression.Expression

Bases: fiql_parser.expression.BaseExpression

The Expression is the largest logical unit of a FIQL Expression. It must, like the Constraint evaluate to True or False. The Expression can both contain and be contained by an Expression. It, unlike the Operator and Constraint, MUST contain specific attributes in order to be valid.

This class contains the bulk of the logic to ensure that an Expression generated by this code is a valid FIQL Expression.

Note

This Expression class uses a single Operator to join multiple Constraints. This format has the advantage of working cleanly with many ORMs and being far more easily converted to the more string friendly format of Constraint, Operator, Constraint, etc. than the more string friendly format can be converted to the other.

elements

List of Constraint and Expression elements in this Expression.

Type:list
operator

The Operator which relates the elements in this Expression.

Type:Operator
add_element(element)

Add an element of type Operator, Constraint, or Expression to the Expression.

Parameters:elementConstraint, Expression, or Operator.
Returns:self
Return type:Expression
Raises:FiqlObjectException – Element is not a valid type.
add_operator(operator)

Add an Operator to the Expression.

The Operator may result in a new Expression if an Operator already exists and is of a different precedence.

There are three possibilities when adding an Operator to an Expression depending on whether an Operator already exists:

  • No Operator on the working Expression; Simply set the Operator and return self.
  • Operator already exists and is higher in precedence; The Operator and last Constraint belong in a sub-expression of the working Expression.
  • Operator already exists and is lower in precedence; The Operator belongs to the parent of the working Expression whether one currently exists or not. To remain in the context of the top Expression, this method will return the parent here rather than self.
Parameters:operator (Operator) – What we are adding.
Returns:self or related Expression.
Return type:Expression
Raises:FiqlObjectExpression – Operator is not a valid Operator.
create_nested_expression()

Create a nested Expression, add it as an element to this Expression, and return it.

Returns:The newly created nested Expression.
Return type:Expression
has_constraint()

Return whether or not the working Expression has any Constraints.

Returns:Number of logical elements within this Expression.
Return type:integer
op_and(*elements)

Update the Expression by joining the specified additional elements using an “AND” Operator

Parameters:*elements (BaseExpression) – The Expression and/or Constraint elements which the “AND” Operator applies to.
Returns:self or related Expression.
Return type:Expression
op_or(*elements)

Update the Expression by joining the specified additional elements using an “OR” Operator

Parameters:*elements (BaseExpression) – The Expression and/or Constraint elements which the “OR” Operator applies to.
Returns:self or related Expression.
Return type:Expression
to_python()

Deconstruct the Expression instance to a list or tuple (If Expression contains only one Constraint).

Returns:The deconstructed Expression.
Return type:list or tuple

Parser

The parser module includes the code used to convert a string representing a FIQL Expression into an object representing the same FIQL Expression.

The Expression object returned is ideally suited for use in filtering database queries with many ORMs.

fiql_parser.parser.from_python_to_expression(constraints)

Construct the Expression instance from a list or tuple (If it contains only one constraint).

Parameters:constraints (list or tuple) – Expression as a tuple or list containing the constraints.
Returns:The constructed Expression.
Return type:Expression
Raises:FiqlParserException – Unable to determine the input is expression or constraint.

Example

>>> expression = from_python_to_expression(
...     [
...         'OR',
...         ('a', '==', 'wee'),
...         ['AND',
...             ['AND', ('foo', None, None), ('bar', '>', '45')],
...             ('key', None, None)
...         ]
...     ]
... )
fiql_parser.parser.iter_parse(fiql_str)

Iterate through the FIQL string. Yield a tuple containing the following FIQL components for each iteration:

  • preamble: Any operator or opening/closing parenthesis preceding a constraint or at the very end of the FIQL string.
  • selector: The selector portion of a FIQL constraint or None if yielding the last portion of the string.
  • comparison: The comparison portion of a FIQL constraint or None if yielding the last portion of the string.
  • argument: The argument portion of a FIQL constraint or None if yielding the last portion of the string.

For usage see parse_str_to_expression().

Parameters:fiql_str (string) – The FIQL formatted string we want to parse.
Yields:tuple – Preamble, selector, comparison, argument.
fiql_parser.parser.parse_str_to_expression(fiql_str)

Parse a FIQL formatted string into an Expression.

Parameters:fiql_str (string) – The FIQL formatted string we want to parse.
Returns:An Expression object representing the parsed FIQL string.
Return type:Expression
Raises:FiqlFormatException – Unable to parse string due to incorrect formatting.

Example

>>> expression = parse_str_to_expression(
...     "name==bar,dob=gt=1990-01-01"
... )