Usage in Python

jonq ships with a small Python API for compiling and executing queries directly.

Quick Start

Use query(...) when you want Python data back immediately:

from jonq import query

data = [
    {"name": "Alice", "age": 30, "city": "New York"},
    {"name": "Bob", "age": 25, "city": "LA"},
]

rows = query(data, "select name, city if age > 26")
print(rows)
[{"name": "Alice", "city": "New York"}]

Compiling Once, Reusing Many Times

Use compile_query(...) when you want to reuse the generated jq filter:

from jonq import compile_query, query

compiled = compile_query("select name if age > 25")

result_1 = query([{"name": "Alice", "age": 30}], compiled)
result_2 = query([{"name": "Bob", "age": 20}], compiled)

print(compiled.jq_filter)
print(result_1)
print(result_2)

Structured Results

Use execute(...) when you want metadata such as the generated jq filter or raw text output:

from jonq import execute

result = execute(
    [{"name": "Alice", "age": 30}],
    "select name, age",
    format="csv",
)

print(result.output_format)
print(result.text)
print(result.compiled.jq_filter)

The Python API supports format="json", format="jsonl", and format="csv". Table and YAML rendering are CLI-only conveniences.

Use format="jsonl" when you want newline-delimited JSON for downstream tools:

result = execute(
    [{"name": "Alice"}, {"name": "Bob"}],
    "select name",
    format="jsonl",
)

print(result.text)

Supported Inputs

The high-level API accepts:

  • Python objects like dict and list

  • Raw JSON strings

  • File paths (str or pathlib.Path)

Validation and Limits

File inputs are validated against the sampled JSON schema by default. Disable that check only when you know a query refers to fields that are absent from the sample:

rows = query("data.json", "select future_field", validate=False)

Use limit= when you want to cap returned rows after query execution:

rows = query("data.json", "select name, age", limit=10)

Streaming

Set streaming=True for row-wise queries over a root-array JSON file:

rows = query("large.json", "select id, name if active = true", streaming=True)

Streaming requires a filesystem path. It rejects aggregations, group by, sort, distinct, and limit because those operations need the full input.

Async Usage

Async variants are also available:

import asyncio
from jonq import query_async

async def main():
    rows = await query_async([{"name": "Alice"}], "select name")
    print(rows)

asyncio.run(main())

CLI Fallback

If you still prefer the CLI from Python, subprocess works as expected:

import json
import subprocess

result = subprocess.run(
    ["jonq", "simple.json", "select name, age if age > 25"],
    capture_output=True,
    text=True,
    check=True,
)
rows = json.loads(result.stdout)