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 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 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) 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) 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) 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 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) 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; | F1 | F2 | F3 |
|---|---|---|
| 1 | 2 | 3 |
Magic command options
| Option | What it does |
|---|---|
--client CLIENT | Use a specific client variable from the notebook namespace |
--debug | Enable debug mode for detailed query information |
--show-sql | Print the translated SQL alongside results |
--hide-dataframe | Suppress the DataFrame display; the magic returns None (no Out[n] / _ frame) |
--show-slt | Print the query in SLT (SQL Logic Test) format |
--hook VARIABLE | Store 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) 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%'; See also
- Python library guide — Configuration, backend setup, error handling, and result objects
- Getting started — Overview of all entry points
- FeatureQL for the Impatient — Quick tour of the language for SQL users
- Demos Docker container — Full environment with notebooks and sample data