Execute Stage¶
The execute stage runs queries and retrieves data for compiled dashboards.
Entry Points¶
Executor¶
The main class for executing queries:
Executor
¶
Executor(board: CompiledBoard, adapter_registry: Optional[Any] = None, query_registry: Optional[Dict[str, CompiledQuery]] = None)
Executes queries for dashboards.
Stage: EXECUTE (Service Module)
The executor manages query execution for a compiled dashboard. It handles: - Query lookup from the board - Adapter selection based on query type - Result caching for efficiency - Variable substitution
Does NOT: - Compile dashboards (use compile module) - Render charts (use render module)
| ATTRIBUTE | DESCRIPTION |
|---|---|
board |
The compiled dashboard
|
adapter_registry |
Registry of adapters (optional)
|
query_registry |
Complete query registry (for cross-references)
|
Example
from dataface.compile import compile from dataface.execute import Executor
result = compile(yaml_content) executor = Executor(result.board, query_registry=result.query_registry)
Execute a query¶
data = executor.execute_query("sales", {"year": 2024}) print(data) # [{"date": "2024-01", "amount": 1000}, ...]
Initialize executor.
| PARAMETER | DESCRIPTION |
|---|---|
board
|
Compiled dashboard
TYPE:
|
adapter_registry
|
Optional adapter registry (uses default if not provided)
TYPE:
|
query_registry
|
Optional query registry for cross-file references
TYPE:
|
Source code in dataface/execute/executor.py
execute_query
¶
execute_query(query_name: str, variables: Optional[VariableValues] = None, use_cache: bool = True) -> List[Dict[str, Any]]
Execute a query and return results.
Stage: EXECUTE (Main Entry Point)
Looks up the query by name, resolves the appropriate adapter, executes the query, and returns the data.
| PARAMETER | DESCRIPTION |
|---|---|
query_name
|
Name of query to execute (may include "queries." prefix)
TYPE:
|
variables
|
Variable values for query resolution
TYPE:
|
use_cache
|
Whether to use cached results if available
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
List[Dict[str, Any]]
|
List of dictionaries with query results (each dict is a row) |
| RAISES | DESCRIPTION |
|---|---|
ExecutionError
|
If query not found or execution fails |
Example
data = executor.execute_query("sales", {"year": 2024}) for row in data: ... print(f"{row['date']}: {row['amount']}")
Source code in dataface/execute/executor.py
143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 | |
execute_chart
¶
execute_chart(chart: Union[CompiledChart, str], variables: Optional[VariableValues] = None, use_cache: bool = True) -> List[Dict[str, Any]]
Execute the query for a chart.
Convenience method that handles chart → query lookup.
| PARAMETER | DESCRIPTION |
|---|---|
chart
|
CompiledChart or chart name string
TYPE:
|
variables
|
Variable values
TYPE:
|
use_cache
|
Whether to use cache
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
List[Dict[str, Any]]
|
Query results for the chart |
Example
chart = board.charts["revenue"] data = executor.execute_chart(chart, {"year": 2024})
Source code in dataface/execute/executor.py
Adapters¶
Adapters connect to different data sources. Each query type has a corresponding adapter.
Base Adapter¶
BaseAdapter
¶
Bases: ABC
Base interface for query adapters.
All adapters must implement this interface to execute queries against different backends (MetricFlow, SQL, HTTP, CSV, etc.).
The unified interface pattern uses:
- supported_types: Property returning set of query types this adapter handles
- Type guards for type-safe field access in execute methods
Subclasses must implement
- supported_types: Property returning Set[str] of supported query types
- _execute(): Perform the actual query execution
Optional override
- _can_execute(): Override for custom eligibility logic beyond type matching
Example
class MyAdapter(BaseAdapter): ... @property ... def supported_types(self) -> Set[str]: ... return {"sql"} ... ... def _execute(self, query, variables): ... if is_sql_query(query): ... # Type checker knows query.sql exists ... return self._run_sql(query.sql)
supported_types
abstractmethod
property
¶
Query types this adapter can execute.
| RETURNS | DESCRIPTION |
|---|---|
Set[str]
|
Set of query type strings (e.g., {"sql"}, {"csv", "http"}) |
Example
adapter.supported_types
can_execute
¶
Check if this adapter can execute the given query.
Uses supported_types for type-based routing. Override _can_execute() for additional custom eligibility logic.
| PARAMETER | DESCRIPTION |
|---|---|
query
|
CompiledQuery object (guaranteed by compiler)
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
bool
|
True if this adapter can execute the query, False otherwise |
Source code in dataface/execute/adapters/base.py
execute
¶
Execute a query and return results.
| PARAMETER | DESCRIPTION |
|---|---|
query
|
CompiledQuery object (guaranteed by compiler)
TYPE:
|
variables
|
Optional dictionary of variable values for query resolution
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
QueryResult
|
QueryResult containing data or error information |
Source code in dataface/execute/adapters/base.py
SQL Adapter¶
For executing SQL queries against databases (DuckDB, PostgreSQL, etc.):
SqlAdapter
¶
SqlAdapter(dbt_project_path: Optional[str] = None, use_example_db: bool = False, connection_string: Optional[str] = None)
Bases: BaseAdapter
Adapter for executing raw SQL queries via dbt's adapter system.
This adapter leverages dbt's adapter API to execute SQL queries. It uses the user's existing dbt configuration (profiles.yml) for database connections, supporting all dbt-compatible databases.
Supported query types: sql
Example
adapter = SqlAdapter() query = SqlQuery(sql="SELECT * FROM users WHERE id = {{ user_id }}") result = adapter.execute(query, {"user_id": 1})
Initialize SQL adapter.
| PARAMETER | DESCRIPTION |
|---|---|
dbt_project_path
|
Path to dbt project (default: current directory)
TYPE:
|
use_example_db
|
If True, use DuckDB example database instead of dbt config
TYPE:
|
connection_string
|
DuckDB connection string (e.g., ":memory:" or file path)
TYPE:
|
Source code in dataface/execute/adapters/sql_adapter.py
CSV Adapter¶
For loading data from CSV files:
CsvAdapter
¶
Bases: BaseAdapter
Adapter for executing queries against CSV files.
Supported query types: csv
Loads data from CSV files and supports: - Column selection - Row filtering (exact match, AND logic) - Result limiting
Example
adapter = CsvAdapter() query = CsvQuery(file="data/sales.csv", columns=["date", "amount"]) result = adapter.execute(query)
Initialize CSV adapter.
| PARAMETER | DESCRIPTION |
|---|---|
project_root
|
Root directory of the project (for resolving relative paths)
TYPE:
|
Source code in dataface/execute/adapters/csv_adapter.py
HTTP Adapter¶
For fetching data from REST APIs:
HttpAdapter
¶
Bases: BaseAdapter
Adapter for executing HTTP/REST API queries.
Supported query types: http
Fetches data from REST API endpoints with support for: - Multiple HTTP methods (GET, POST, PUT, DELETE, PATCH) - Custom headers - Query parameters - Request body (JSON)
Example
adapter = HttpAdapter() query = HttpQuery( ... url="https://api.example.com/users", ... headers={"Authorization": "Bearer {{ token }}"} ... ) result = adapter.execute(query, {"token": "xyz"})
Initialize HTTP adapter.
| PARAMETER | DESCRIPTION |
|---|---|
timeout
|
Request timeout in seconds
TYPE:
|
Source code in dataface/execute/adapters/http_adapter.py
dbt Adapter¶
For integrating with dbt models:
DbtAdapter
¶
DbtAdapter(dbt_project_path: Optional[Path] = None, profile_name: Optional[str] = None, target_name: Optional[str] = None)
Bases: BaseAdapter
Adapter for executing SQL queries via dbt's adapter system.
Supported query types: sql
Leverages dbt's adapter API to execute SQL queries with support for dbt-specific features like ref(), source(), etc.
This adapter requires dbt-core to be installed and a valid dbt project with profiles.yml configuration.
Example
adapter = DbtAdapter(dbt_project_path=Path("./my_dbt_project")) query = SqlQuery(sql="SELECT * FROM {{ ref('customers') }}") result = adapter.execute(query)
Initialize dbt adapter.
| PARAMETER | DESCRIPTION |
|---|---|
dbt_project_path
|
Path to dbt project (default: current directory)
TYPE:
|
profile_name
|
dbt profile name (default: from dbt_project.yml)
TYPE:
|
target_name
|
dbt target name (default: 'dev')
TYPE:
|
Source code in dataface/execute/adapters/dbt_adapter.py
MetricFlow Adapter¶
For querying MetricFlow metrics:
MetricFlowAdapter
¶
Bases: BaseAdapter
Adapter for executing MetricFlow (dbt Semantic Layer) queries.
Supported query types: metricflow
Executes queries against dbt's Semantic Layer using MetricFlow. In a full implementation, this uses the MetricFlow Python API or CLI.
Example
adapter = MetricFlowAdapter() query = MetricFlowQuery( ... metrics=["revenue", "orders"], ... dimensions=["date", "region"] ... ) result = adapter.execute(query)
Initialize MetricFlow adapter.
| PARAMETER | DESCRIPTION |
|---|---|
config_path
|
Optional path to MetricFlow configuration
TYPE:
|
Source code in dataface/execute/adapters/metricflow_adapter.py
Adapter Registry¶
AdapterRegistry
¶
Registry for managing and selecting query adapters.
The registry uses type-based routing from the unified query interface.
Adapters declare their supported types via the supported_types property,
and the registry routes queries to the appropriate adapter.
Priority order: 1. First registered adapter that supports the query type wins 2. dbt adapter is registered first for SQL (with dbt features) 3. Fallback SQL adapter for plain SQL without dbt
Example
registry = AdapterRegistry() query = SqlQuery(sql="SELECT 1") result = registry.execute(query)
Initialize adapter registry with default adapters.
Source code in dataface/execute/adapters/adapter_registry.py
supported_types
property
¶
Get all query types supported by registered adapters.
| RETURNS | DESCRIPTION |
|---|---|
Set[str]
|
Set of query type strings |
register
¶
Register an adapter.
Adapters are indexed by their supported types for fast lookup.
| PARAMETER | DESCRIPTION |
|---|---|
adapter
|
Adapter instance to register
TYPE:
|
Source code in dataface/execute/adapters/adapter_registry.py
get_adapters_for_type
¶
Get all adapters that support a given query type.
| PARAMETER | DESCRIPTION |
|---|---|
query_type
|
Query type string (e.g., "sql", "csv")
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
List[BaseAdapter]
|
List of adapters supporting this type (in registration order) |
Source code in dataface/execute/adapters/adapter_registry.py
get_adapter
¶
Get an adapter that can execute the given query.
Uses type-based routing for fast lookup, then checks additional eligibility via can_execute().
| PARAMETER | DESCRIPTION |
|---|---|
query
|
CompiledQuery object
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
Optional[BaseAdapter]
|
Adapter instance or None if no adapter can execute the query |
Source code in dataface/execute/adapters/adapter_registry.py
execute
¶
Execute a query using the appropriate adapter.
| PARAMETER | DESCRIPTION |
|---|---|
query
|
CompiledQuery object
TYPE:
|
variables
|
Variable values for query resolution
TYPE:
|
| RETURNS | DESCRIPTION |
|---|---|
QueryResult
|
QueryResult with data or error |
Source code in dataface/execute/adapters/adapter_registry.py
Errors¶
errors
¶
Execution error types.
Stage: EXECUTE Purpose: Define error types for query execution failures.
These errors are raised during: - Query execution (QueryError) - Adapter resolution/execution (AdapterError) - Connection failures (ConnectionError)
All errors inherit from ExecutionError for easy catching.
ExecutionError
¶
Bases: Exception
Base error for all execution failures.
This is the parent class for all execution-related errors. Catch this to handle any execution error.
| ATTRIBUTE | DESCRIPTION |
|---|---|
message |
Human-readable error description
|
query_name |
Name of query that failed (if applicable)
|
Source code in dataface/execute/errors.py
QueryError
¶
Bases: ExecutionError
Error during query execution.
Raised when: - SQL syntax is invalid - Table/column doesn't exist - Query returns unexpected results
Example
try: ... executor.execute_query("broken_query") ... except QueryError as e: ... print(f"Query failed: {e}")
Source code in dataface/execute/errors.py
AdapterError
¶
Bases: ExecutionError
Error with adapter resolution or execution.
Raised when: - Adapter not found for query type - Adapter initialization fails - Adapter-specific error occurs
Example
try: ... executor.execute_query("unknown_type_query") ... except AdapterError as e: ... print(f"Adapter error: {e}")