Python library

The featuremesh Python package translates FeatureQL to SQL and executes it against your database. It works in two modes: local (default, zero-config) and managed (remote FeatureMesh infrastructure).

Installation

pip install featuremesh
bash

Quick start — local mode

Local mode bundles the transpilation engine and uses SQLite for persistence. No server, no account — works immediately:

from featuremesh import BatchClient

client = BatchClient()

result = client.query("""
    SELECT
        F1 := 1,
        F2 := 2,
        F3 := F1 + F2;
""")

print(result.dataframe)  # Pandas DataFrame
print(result.sql)        # Generated SQL
print(result.success)    # True if query succeeded
python

Translate without executing:

result = client.translate("""
    WITH
        ID := INPUT(BIGINT)
    SELECT
        ID,
        DOUBLED := ID * 2
    FOR
        ID := BIND_VALUES(ARRAY[1, 2, 3]);
""")

print(result.sql)
python

Managed mode — batch analytics

For team collaboration with shared feature definitions and access control, switch to managed mode. Transpilation and persistence happen on FeatureMesh infrastructure:

from featuremesh import BatchClient, Backend, Registry, set_default

set_default("registry", Registry.MANAGED)

# Get your access token from https://console.featuremesh.com/login
ACCESS_TOKEN = "your_access_token"

# Provide a SQL executor for your database
def query_duckdb(sql: str):
    import duckdb
    return duckdb.sql(sql).df()

client = BatchClient(
    access_token=ACCESS_TOKEN,
    backend=Backend.DUCKDB,
    sql_executor=query_duckdb,
)

result = client.query("""
    WITH
        ID := INPUT(BIGINT)
    SELECT
        ID,
        DOUBLED := ID * 2
    FOR
        ID := BIND_VALUES(ARRAY[1, 2, 3])
""")

print(result.dataframe)
python

Real-time serving

The serving client sends queries to FeatureMesh's managed DataFusion engine for low-latency execution against real-time data sources (Redis, JDBC, HTTP):

from featuremesh import Registry, ServingClient, set_default

set_default("registry", Registry.MANAGED)
client = ServingClient(access_token=ACCESS_TOKEN)

result = client.query("""
    WITH
        ID := INPUT(BIGINT)
    SELECT
        ID,
        DOUBLED := ID * 2
    FOR
        ID := BIND_VALUES(ARRAY[1, 2, 3])
""")

print(result.dataframe)
python

How it works

FeatureMesh has two independent axes:

Transpilation + Persistence — where FeatureQL is translated and feature definitions are stored:

  • Local (default): bundled engine + SQLite. No network.
  • Managed: FeatureMesh infrastructure. Requires access token.

Execution — who runs the final SQL:

  • BatchClient: your database (DuckDB, Trino, BigQuery, DataFusion). For analytics, ETL, experimentation.
  • ServingClient: FeatureMesh's engine (DataFusion). For real-time serving. Managed-only.

Local mode note: with registry=LOCAL, BatchClient only executes with DuckDB today; other backends require managed mode plus a matching sql_executor.

Jupyter notebook integration

The %%featureql cell magic lets you write FeatureQL directly in notebook cells and see results as DataFrames. Load the extension first:

%load_ext featuremesh
python

Then set a default client so the magic command knows where to send queries:

from featuremesh import set_default, BatchClient

client = BatchClient()
set_default("client", client)
python

If you skip set_default but have exactly one BatchClient or ServingClient in the notebook namespace, the magic will use it automatically; with several clients, use set_default("client", ...) or --client.

Now you can write FeatureQL directly in cells:

%%featureql

SELECT
    F1 := 1,
    F2 := 2,
    F3 := F1 + F2;
python
F1F2F3
123

Magic command options

OptionWhat it does
--client CLIENTUse a specific client variable from the notebook namespace
--debugEnable debug mode for detailed query information
--show-sqlPrint the translated SQL alongside results
--hide-dataframeSuppress the DataFrame display; the magic returns None (no Out[n] / _ frame)
--show-sltPrint the query in SLT (SQL Logic Test) format
--hook VARIABLEStore QueryResult.to_dict() in VARIABLE: a plain dict, not a QueryResult. The "dataframe" key is None or a list of row dicts (JSON-style), not a pandas.DataFrame. Use VARIABLE["dataframe"], not attribute access.

Getting a real pandas.DataFrame in a notebook: use df = client.query("""...""").dataframe, or run %%featureql without --hide-dataframe and capture the cell output in the next cell (df = _ or df = Out[n]). To rebuild from a hook dict: pandas.DataFrame(hook["dataframe"]) when that key is not None.

Discovery helpers — BatchClient

On a batch client you can search bundled docs and introspect queries without writing raw SHOW SQL:

client.help("zip", "date_diff").display()   # HelpResult: docs, samples, signatures, tests
client.describe("fm.demo").display()        # DescribeResult: persisted features under prefix(es)
client.validate("SELECT F := 1;").display() # ValidateResult: FORMAT (FIX) + output schema
summary = client.sltest()                   # dict: SLT checks on CODE_SAMPLE docs (`source=`, `labels=` — see guide)
python

featuremesh.help() (module-level) prints how to use BatchClient.help.

Quick reference

Run featuremesh.help() in Python for a cheatsheet of common patterns.

To discover FeatureQL syntax interactively, run these as queries:

SHOW SIGNATURES WHERE NAME = 'EXTEND';
SHOW TESTS WHERE FUNCTION_NAME = 'TRANSFORM';
SHOW DOCS WHERE CONTENT LIKE '%RELATED%';
sql

See also

Last update at: 2026/04/27 15:40:31