Reasoning Flows — Configurable Objects Overview
Configurable Objects Overview
Create interactive configuration interfaces for Reasoning Flows objects using HTML forms.
Purpose
In Reasoning Flows, you can create objects in PHP or Python with an optional interactive configuration interface. By adding a config.html file to your object, you enable users to configure parameters through a form instead of editing code directly.
Form values are passed directly to the startup script (index.py or index.php) at runtime, making it easy for non-technical users to adjust settings without modifying code.
Objects without a config.html file work exactly as before — opening in the standard code editor view.
Object Types
An object must use one of the following languages:
| Language | Startup File | Runtime |
|---|---|---|
| Python | index.py | Python 3.x |
| PHP | index.php | PHP 8.x |
The startup file is required and serves as the entry point for execution. It can import or include other files within the same object.
Configuration UI (config.html)
With config.html
When an object contains a config.html file:
- Reasoning Flows renders it as an interactive configuration form
- User inputs are passed directly to the startup script at execution time
- You can still access View Code Mode to see and edit the object's files
Without config.html
When config.html is absent:
- The object opens in Code Mode by default
- Users edit code and configuration files manually
Creating a Configuration Interface
Example: config.html
<!DOCTYPE html>
<html>
<head>
<title>Data Export Configuration</title>
<style>
form { max-width: 400px; margin: 20px; }
label { display: block; margin-top: 10px; font-weight: bold; }
input, select { width: 100%; padding: 8px; margin-top: 5px; }
button { margin-top: 20px; padding: 10px 20px; }
</style>
</head>
<body>
<h2>Data Export Settings</h2>
<form id="config-form">
<label for="source_table">Source Table:</label>
<input type="text" id="source_table" name="source_table" placeholder="e.g., sales_gold" required>
<label for="row_limit">Row Limit:</label>
<input type="number" id="row_limit" name="row_limit" value="1000" min="1">
<label for="output_format">Output Format:</label>
<select id="output_format" name="output_format">
<option value="csv">CSV</option>
<option value="json">JSON</option>
<option value="excel">Excel</option>
</select>
<label for="include_headers">Include Headers:</label>
<select id="include_headers" name="include_headers">
<option value="yes">Yes</option>
<option value="no">No</option>
</select>
<button type="submit">Export Data</button>
</form>
</body>
</html>
Reading Config Values in Python (index.py)
import dkconnect
import os
import csv
import json
# Configuration values from the form
source_table = os.environ.get('source_table', 'default_table')
row_limit = int(os.environ.get('row_limit', 1000))
output_format = os.environ.get('output_format', 'csv')
include_headers = os.environ.get('include_headers', 'yes') == 'yes'
# Connect to database
conn = dkconnect.connect()
cursor = conn.cursor()
# Query data
cursor.execute(
f"SELECT * FROM {source_table} LIMIT %s",
(row_limit,)
)
columns = [desc[0] for desc in cursor.description]
rows = cursor.fetchall()
# Output based on format selection
if output_format == 'json':
data = [dict(zip(columns, row)) for row in rows]
print(json.dumps(data, indent=2, default=str))
elif output_format == 'csv':
if include_headers:
print(','.join(columns))
for row in rows:
print(','.join(str(val) for val in row))
cursor.close()
conn.close()
Reading Config Values in PHP (index.php)
<?php
require_once('datakubes-connect.php');
// Configuration values from the form
$source_table = $_POST['source_table'] ?? 'default_table';
$row_limit = (int)($_POST['row_limit'] ?? 1000);
$output_format = $_POST['output_format'] ?? 'csv';
$include_headers = ($_POST['include_headers'] ?? 'yes') === 'yes';
// Connect to database
$dk_conn = dk_connect();
// Query data
$stmt = $dk_conn->prepare("SELECT * FROM $source_table LIMIT ?");
$stmt->bind_param('i', $row_limit);
$stmt->execute();
$result = $stmt->get_result();
// Get column names
$columns = [];
$fields = $result->fetch_fields();
foreach ($fields as $field) {
$columns[] = $field->name;
}
// Output based on format selection
if ($output_format === 'json') {
header('Content-Type: application/json');
$data = [];
while ($row = $result->fetch_assoc()) {
$data[] = $row;
}
echo json_encode($data, JSON_PRETTY_PRINT);
} elseif ($output_format === 'csv') {
header('Content-Type: text/csv');
if ($include_headers) {
echo implode(',', $columns) . "\n";
}
while ($row = $result->fetch_row()) {
echo implode(',', $row) . "\n";
}
}
$stmt->close();
$dk_conn->close();
Common Use Cases
| Use Case | Description |
|---|---|
| Data Transformation Pipelines | Let users select data sources, filters, or transformation rules before processing |
| API Integration Configurations | Collect authentication keys, endpoints, and query parameters via form inputs |
| AI & Machine Learning Parameters | Adjust model settings, thresholds, or prompts before execution |
| Report Generation | Allow users to specify date ranges, departments, or output formats |
| Automation & Task Runners | Schedule or parameterize recurring backend tasks without code changes |
| Environment-Specific Settings | Switch between dev, staging, and production values dynamically |
Comparison
With config.html | Without config.html |
|---|---|
| UI rendered for configuration | Shows file/code browser |
| Inputs sent directly to main file | Edit code/config manually |
| User-friendly for non-developers | Requires code editing |
Always starts at index.* | Always starts at index.* |
Benefits
Flexibility
Choose PHP or Python based on your workflow and team expertise.
Ease of Use
Non-technical users can configure objects via forms instead of editing code.
Predictable Execution
Always starts from a single entry file (index.py or index.php).
Modularity
Startup scripts can import helper files, libraries, and shared modules.
Backward Compatibility
Objects without config.html work exactly as before.
Best Practices
Keep forms simple. Focus on the parameters users actually need to change.
Provide sensible defaults. Pre-populate form fields with common values.
Validate inputs. Check values in your startup script before using them — never trust user input directly in SQL queries.
Use clear labels. Make form fields self-explanatory for non-technical users.
Add help text. Include placeholders or descriptions to explain expected values.
Handle missing values gracefully. Always provide fallback defaults in your code.
Test both modes. Verify your object works correctly with and without the configuration form.
Related Documentation
-
App Droplet Object Overview
Deploy configured objects to production servers. -
Visual Object Overview
Create notebooks and visualization applications. -
AI Apps Overview
Orchestrate multiple objects into complete applications. -
Transform & Prepare
Use configurable objects for data transformation workflows.
Updated 16 days ago
