fiftyone.core.expression_ast#

Serializable syntax trees for view expressions.

Copyright 2017-2026, Voxel51, Inc.

ViewExpression.to_mongo() lowers an expression to a MongoDB aggregation expression, and that lowering is one-way: F("x") & F("y") and F("x").all([...]) both produce {"$and": [...]}, F("x").exists() produces the same shape as a comparison against null, and 20 operators lower into multi-node idioms (length() becomes {"$size": {"$ifNull": ["$x", []]}}). Nothing downstream of the lowering can tell which operator the caller used.

This module records the construction itself, so an expression built in the App can be reconstructed here as the same F(...) / E(...) calls, and one built in Python can be rendered in the App as structure rather than as opaque MongoDB. The lowering is unchanged and remains what the aggregation pipeline consumes.

Node forms:

{"t": "field",  "path": "conf"}                      a ViewField
{"t": "lit",    "v": 0.5}                            a JSON literal
{"t": "call",   "op": "__gt__", "self": <node>,
                "args": [<node>], "kwargs": {}}      an instance method
{"t": "static", "op": "any",
                "args": [<node>], "kwargs": {}}      a static constructor
{"t": "list",   "items": [<node>]}                   a list operand
{"t": "dict",   "entries": [[<node>, <node>]]}       a dict operand
{"t": "mongo",  "expr": {...}}                       raw MongoDB, no syntax

The mongo form is the fallback: expressions built by passing MongoDB directly to E({...}), and expressions arriving from a view saved before this module existed, carry no construction to record. They round trip losslessly as MongoDB, and callers can tell the difference by checking is_reconstructible().

Classes:

FieldNode

A fiftyone.core.expressions.ViewField.

LiteralNode

CallNode

An instance method or operator applied to a target expression.

StaticNode

A static constructor such as E.any or E.literal.

ListNode

A list operand, whose items may themselves be expressions.

DictNode

A dict operand, whose keys and values may themselves be expressions.

MongoNode

Raw MongoDB, for an expression that recorded no syntax.

Data:

AST_VERSION

Version of the syntax tree format.

AST_KEY

Envelope key identifying a serialized expression.

Functions:

records_expression_syntax(cls)

Class decorator that records how each expression was constructed.

node_of(expr)

Returns the syntax tree node for an expression.

is_reconstructible(expr)

Whether an expression can be rendered as Python source.

to_envelope(expr)

Serializes an expression as a versioned envelope.

is_envelope(value)

Whether a serialized value is an expression envelope.

from_envelope(value)

Reconstructs an expression from a versioned envelope.

from_node(node)

Reconstructs an expression from a syntax tree node.

to_python(expr[,Β field_var,Β expr_var])

Renders an expression as Python source.

class fiftyone.core.expression_ast.FieldNode#

Bases: TypedDict

A fiftyone.core.expressions.ViewField.

Attributes:

Methods:

clear()

Remove all items from the dict.

copy()

Return a shallow copy of the dict.

fromkeys(iterable[,Β value])

Create a new dictionary with keys from iterable and values set to value.

get(key[,Β default])

Return the value for key if key is in the dictionary, else default.

items()

Return a set-like object providing a view on the dict's items.

keys()

Return a set-like object providing a view on the dict's keys.

pop(k[,d])

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()

Remove and return a (key, value) pair as a 2-tuple.

setdefault(key[,Β default])

Insert key with a value of default if key is not in the dictionary.

update([E,Β ]**F)

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()

Return an object providing a view on the dict's values.

t: Literal['field']#
path: str#
clear()#

Remove all items from the dict.

copy()#

Return a shallow copy of the dict.

classmethod fromkeys(iterable, value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)#

Return the value for key if key is in the dictionary, else default.

items()#

Return a set-like object providing a view on the dict’s items.

keys()#

Return a set-like object providing a view on the dict’s keys.

pop(k[, d]) → v, remove specified key and return the corresponding value.#

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()#

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault(key, default=None, /)#

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) → None.  Update D from mapping/iterable E and F.#

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()#

Return an object providing a view on the dict’s values.

class fiftyone.core.expression_ast.LiteralNode#

Bases: TypedDict

Methods:

clear()

Remove all items from the dict.

copy()

Return a shallow copy of the dict.

fromkeys(iterable[,Β value])

Create a new dictionary with keys from iterable and values set to value.

get(key[,Β default])

Return the value for key if key is in the dictionary, else default.

items()

Return a set-like object providing a view on the dict's items.

keys()

Return a set-like object providing a view on the dict's keys.

pop(k[,d])

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()

Remove and return a (key, value) pair as a 2-tuple.

setdefault(key[,Β default])

Insert key with a value of default if key is not in the dictionary.

update([E,Β ]**F)

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()

Return an object providing a view on the dict's values.

Attributes:

t

clear()#

Remove all items from the dict.

copy()#

Return a shallow copy of the dict.

classmethod fromkeys(iterable, value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)#

Return the value for key if key is in the dictionary, else default.

items()#

Return a set-like object providing a view on the dict’s items.

keys()#

Return a set-like object providing a view on the dict’s keys.

pop(k[, d]) → v, remove specified key and return the corresponding value.#

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()#

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault(key, default=None, /)#

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) → None.  Update D from mapping/iterable E and F.#

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()#

Return an object providing a view on the dict’s values.

t: Literal['lit']#
v: None | bool | int | float | str | List[None | bool | int | float | str | List[JSONValue] | Dict[str, JSONValue]] | Dict[str, None | bool | int | float | str | List[JSONValue] | Dict[str, JSONValue]]#
as: Literal['date', 'timedelta']#
class fiftyone.core.expression_ast.CallNode#

Bases: TypedDict

An instance method or operator applied to a target expression.

Attributes:

Methods:

clear()

Remove all items from the dict.

copy()

Return a shallow copy of the dict.

fromkeys(iterable[,Β value])

Create a new dictionary with keys from iterable and values set to value.

get(key[,Β default])

Return the value for key if key is in the dictionary, else default.

items()

Return a set-like object providing a view on the dict's items.

keys()

Return a set-like object providing a view on the dict's keys.

pop(k[,d])

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()

Remove and return a (key, value) pair as a 2-tuple.

setdefault(key[,Β default])

Insert key with a value of default if key is not in the dictionary.

update([E,Β ]**F)

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()

Return an object providing a view on the dict's values.

t: Literal['call']#
op: str#
self: FieldNode | LiteralNode | CallNode | StaticNode | ListNode | DictNode | MongoNode#
args: List[FieldNode | LiteralNode | CallNode | StaticNode | ListNode | DictNode | MongoNode]#
kwargs: Dict[str, FieldNode | LiteralNode | CallNode | StaticNode | ListNode | DictNode | MongoNode]#
clear()#

Remove all items from the dict.

copy()#

Return a shallow copy of the dict.

classmethod fromkeys(iterable, value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)#

Return the value for key if key is in the dictionary, else default.

items()#

Return a set-like object providing a view on the dict’s items.

keys()#

Return a set-like object providing a view on the dict’s keys.

pop(k[, d]) → v, remove specified key and return the corresponding value.#

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()#

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault(key, default=None, /)#

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) → None.  Update D from mapping/iterable E and F.#

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()#

Return an object providing a view on the dict’s values.

class fiftyone.core.expression_ast.StaticNode#

Bases: TypedDict

A static constructor such as E.any or E.literal.

Attributes:

Methods:

clear()

Remove all items from the dict.

copy()

Return a shallow copy of the dict.

fromkeys(iterable[,Β value])

Create a new dictionary with keys from iterable and values set to value.

get(key[,Β default])

Return the value for key if key is in the dictionary, else default.

items()

Return a set-like object providing a view on the dict's items.

keys()

Return a set-like object providing a view on the dict's keys.

pop(k[,d])

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()

Remove and return a (key, value) pair as a 2-tuple.

setdefault(key[,Β default])

Insert key with a value of default if key is not in the dictionary.

update([E,Β ]**F)

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()

Return an object providing a view on the dict's values.

t: Literal['static']#
op: str#
args: List[FieldNode | LiteralNode | CallNode | StaticNode | ListNode | DictNode | MongoNode]#
kwargs: Dict[str, FieldNode | LiteralNode | CallNode | StaticNode | ListNode | DictNode | MongoNode]#
clear()#

Remove all items from the dict.

copy()#

Return a shallow copy of the dict.

classmethod fromkeys(iterable, value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)#

Return the value for key if key is in the dictionary, else default.

items()#

Return a set-like object providing a view on the dict’s items.

keys()#

Return a set-like object providing a view on the dict’s keys.

pop(k[, d]) → v, remove specified key and return the corresponding value.#

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()#

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault(key, default=None, /)#

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) → None.  Update D from mapping/iterable E and F.#

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()#

Return an object providing a view on the dict’s values.

class fiftyone.core.expression_ast.ListNode#

Bases: TypedDict

A list operand, whose items may themselves be expressions.

Attributes:

t

Methods:

items()

Return a set-like object providing a view on the dict's items.

clear()

Remove all items from the dict.

copy()

Return a shallow copy of the dict.

fromkeys(iterable[,Β value])

Create a new dictionary with keys from iterable and values set to value.

get(key[,Β default])

Return the value for key if key is in the dictionary, else default.

keys()

Return a set-like object providing a view on the dict's keys.

pop(k[,d])

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()

Remove and return a (key, value) pair as a 2-tuple.

setdefault(key[,Β default])

Insert key with a value of default if key is not in the dictionary.

update([E,Β ]**F)

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()

Return an object providing a view on the dict's values.

t: Literal['list']#
items()#

Return a set-like object providing a view on the dict’s items.

clear()#

Remove all items from the dict.

copy()#

Return a shallow copy of the dict.

classmethod fromkeys(iterable, value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)#

Return the value for key if key is in the dictionary, else default.

keys()#

Return a set-like object providing a view on the dict’s keys.

pop(k[, d]) → v, remove specified key and return the corresponding value.#

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()#

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault(key, default=None, /)#

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) → None.  Update D from mapping/iterable E and F.#

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()#

Return an object providing a view on the dict’s values.

class fiftyone.core.expression_ast.DictNode#

Bases: TypedDict

A dict operand, whose keys and values may themselves be expressions.

Attributes:

Methods:

clear()

Remove all items from the dict.

copy()

Return a shallow copy of the dict.

fromkeys(iterable[,Β value])

Create a new dictionary with keys from iterable and values set to value.

get(key[,Β default])

Return the value for key if key is in the dictionary, else default.

items()

Return a set-like object providing a view on the dict's items.

keys()

Return a set-like object providing a view on the dict's keys.

pop(k[,d])

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()

Remove and return a (key, value) pair as a 2-tuple.

setdefault(key[,Β default])

Insert key with a value of default if key is not in the dictionary.

update([E,Β ]**F)

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()

Return an object providing a view on the dict's values.

t: Literal['dict']#
entries: List[List[FieldNode | LiteralNode | CallNode | StaticNode | ListNode | DictNode | MongoNode]]#
clear()#

Remove all items from the dict.

copy()#

Return a shallow copy of the dict.

classmethod fromkeys(iterable, value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)#

Return the value for key if key is in the dictionary, else default.

items()#

Return a set-like object providing a view on the dict’s items.

keys()#

Return a set-like object providing a view on the dict’s keys.

pop(k[, d]) → v, remove specified key and return the corresponding value.#

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()#

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault(key, default=None, /)#

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) → None.  Update D from mapping/iterable E and F.#

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()#

Return an object providing a view on the dict’s values.

class fiftyone.core.expression_ast.MongoNode#

Bases: TypedDict

Raw MongoDB, for an expression that recorded no syntax.

Attributes:

Methods:

clear()

Remove all items from the dict.

copy()

Return a shallow copy of the dict.

fromkeys(iterable[,Β value])

Create a new dictionary with keys from iterable and values set to value.

get(key[,Β default])

Return the value for key if key is in the dictionary, else default.

items()

Return a set-like object providing a view on the dict's items.

keys()

Return a set-like object providing a view on the dict's keys.

pop(k[,d])

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()

Remove and return a (key, value) pair as a 2-tuple.

setdefault(key[,Β default])

Insert key with a value of default if key is not in the dictionary.

update([E,Β ]**F)

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()

Return an object providing a view on the dict's values.

t: Literal['mongo']#
expr: None | bool | int | float | str | List[None | bool | int | float | str | List[JSONValue] | Dict[str, JSONValue]] | Dict[str, None | bool | int | float | str | List[JSONValue] | Dict[str, JSONValue]]#
clear()#

Remove all items from the dict.

copy()#

Return a shallow copy of the dict.

classmethod fromkeys(iterable, value=None, /)#

Create a new dictionary with keys from iterable and values set to value.

get(key, default=None, /)#

Return the value for key if key is in the dictionary, else default.

items()#

Return a set-like object providing a view on the dict’s items.

keys()#

Return a set-like object providing a view on the dict’s keys.

pop(k[, d]) → v, remove specified key and return the corresponding value.#

If the key is not found, return the default if given; otherwise, raise a KeyError.

popitem()#

Remove and return a (key, value) pair as a 2-tuple.

Pairs are returned in LIFO (last-in, first-out) order. Raises KeyError if the dict is empty.

setdefault(key, default=None, /)#

Insert key with a value of default if key is not in the dictionary.

Return the value for key if key is in the dictionary, else default.

update([E, ]**F) → None.  Update D from mapping/iterable E and F.#

If E is present and has a .keys() method, then does: for k in E.keys(): D[k] = E[k] If E is present and lacks a .keys() method, then does: for k, v in E: D[k] = v In either case, this is followed by: for k in F: D[k] = F[k]

values()#

Return an object providing a view on the dict’s values.

fiftyone.core.expression_ast.AST_VERSION = 1#

Version of the syntax tree format.

Bump this when a node form changes meaning. Readers reject envelopes they don’t understand rather than guessing, and fall back to the MongoDB the envelope is serialized alongside.

fiftyone.core.expression_ast.AST_KEY = '_fo_expr'#

Envelope key identifying a serialized expression.

Chosen so it cannot collide with a MongoDB operator (which are $-prefixed), which is what lets a decoder distinguish a persisted expression from a raw aggregation expression without ambiguity.

fiftyone.core.expression_ast.records_expression_syntax(cls: type) → type#

Class decorator that records how each expression was constructed.

Wraps every expression-building method on the class so that the returned expression carries the operator and operands that produced it. Applied to fiftyone.core.expressions.ViewExpression, this covers all ~130 operators without touching them individually.

fiftyone.core.expression_ast.node_of(expr: ViewExpression) → FieldNode | LiteralNode | CallNode | StaticNode | ListNode | DictNode | MongoNode#

Returns the syntax tree node for an expression.

Expressions built from raw MongoDB have no recorded syntax and yield a mongo node.

fiftyone.core.expression_ast.is_reconstructible(expr: ViewExpression) → bool#

Whether an expression can be rendered as Python source.

False for expressions built by handing MongoDB to E({...}), and for anything containing such a subexpression.

fiftyone.core.expression_ast.to_envelope(expr: ViewExpression) → Dict[str, Dict[str, int | FieldNode | LiteralNode | CallNode | StaticNode | ListNode | DictNode | MongoNode]]#

Serializes an expression as a versioned envelope.

fiftyone.core.expression_ast.is_envelope(value: Any) → bool#

Whether a serialized value is an expression envelope.

fiftyone.core.expression_ast.from_envelope(value: Dict[str, Dict[str, int | FieldNode | LiteralNode | CallNode | StaticNode | ListNode | DictNode | MongoNode]]) → ViewExpression#

Reconstructs an expression from a versioned envelope.

Raises:

ValueError – if the envelope’s version is not understood, so callers can fall back to the MongoDB representation rather than misread a tree

fiftyone.core.expression_ast.from_node(node: FieldNode | LiteralNode | CallNode | StaticNode | ListNode | DictNode | MongoNode) → ViewExpression#

Reconstructs an expression from a syntax tree node.

fiftyone.core.expression_ast.to_python(expr: ViewExpression, field_var: str = 'F', expr_var: str = 'E') → str#

Renders an expression as Python source.

Parameters:
Returns:

Python source for the expression. Subexpressions built from raw MongoDB render as E(<mongo>), which is accurate but opaque.