You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The integration allows users to switch between SQL-based queries (traditional Redash) and OLAP exploration (Turnilo), with automatic SQL translation via the Plywood server.
Database-specific parsers that extract column metadata:
PostgresAttributeParser.ts
MySqlAttributeParser.ts
BigQueryParser.ts
AthenaParser.ts
DruidParser.ts
JsonAttributeParser.ts
Data Flow
SQL Query Execution
1. Frontend submits query
POST /api/queries/{id}/results
2. Backend handler (queries.py)
├── Validate permissions
├── Collect parameters
└── Enqueue to RQ
3. RQ Worker executes
├── Load DataSource
├── Get QueryRunner (postgres, bigquery, etc.)
├── Execute SQL
└── Store QueryResult
4. Return to frontend
├── Serialize results
└── Render visualization
Turnilo Report Execution
1. TurniloComponent UI
└── User builds query (drag/drop dimensions)
2. Plywood translation
├── Send query state to Plywood server
├── AttributeParser extracts dimensions/measures
└── Generate SQL hash
3. Report creation
POST /api/reports { hash, model_id, ... }
4. Report execution
├── hash_to_result() in hash_manager.py
├── PlywoodApi.convert_hash_to_expression()
├── Translate hash → SQL
├── Execute via QueryRunner
└── Return results to Turnilo UI
Schema Discovery
1. Add data source
POST /api/data_sources
2. Background refresh (every 30 min)
├── For each DataSource
├── QueryRunner.get_schema()
└── Store in DataSource.schema
3. Auto-generate data cube (optional)
POST /api/model_configs/generate
├── Call PlywoodApi.convert_attributes()
├── Parse dimensions vs measures
└── Create Model (data cube)
Database Engine Mapping
Redash data source types map to Plywood engines:
Redash Type
Plywood Engine
pg
postgres
mysql
mysql
bigquery
bigquery
athena
athena
druid
druid
json
json
API Reference
Main API (/api/)
Endpoint
Methods
Purpose
/api/queries
GET, POST
List/create queries
/api/queries/{id}
GET, PUT, DELETE
Query CRUD
/api/queries/{id}/results
POST
Execute query
/api/queries/format
POST
Format SQL
/api/dashboards
GET, POST
List/create dashboards
/api/dashboards/{id}
GET, PUT, DELETE
Dashboard CRUD
/api/dashboards/{id}/widgets
POST
Add widget
/api/reports
GET, POST
List/create reports
/api/reports/{id}
GET, DELETE
Report CRUD
/api/reports/{id}/results
POST
Execute report (hash)
/api/visualizations
GET, POST
Visualization types
/api/data_sources
GET, POST
Data source management
/api/model_configs
GET, POST
Data cube configs
/api/model_configs/generate
POST
Auto-generate cubes
/api/users
GET, POST
User management
/api/groups
GET, POST
Group management
/api/alerts
GET, POST
Alert management
Plywood API (http://plywood:3000/api/v1/)
Endpoint
Method
Purpose
/status
GET
Health check
/plywood
POST
Query translation
/plywood/attributes
POST
Extract dimensions/measures
/plywood/attributes/engines
GET
List supported engines
/plywood/expression
POST
Hash to expression
/plywood/filter-to-hash
POST
Serialize filter
/plywood/hash-to-filter
POST
Deserialize filter
/plywood/response-shape
POST
Detect result schema
Configuration
Environment Variables
Core:
REDASH_COOKIE_SECRET # Session encryption (REQUIRED)
REDASH_DATABASE_URL # PostgreSQL connection
REDASH_REDIS_URL # Redis for cache/sessions
RQ_REDIS_URL # Redis for job queue
REDASH_MAIL_SERVER # SMTP server
REDASH_MAIL_PORT # SMTP port
REDASH_MAIL_USERNAME # SMTP credentials
REDASH_MAIL_PASSWORD
REDASH_MAIL_USE_TLS # TLS flag
Security:
REDASH_ENFORCE_HTTPS # Redirect HTTP to HTTPS
REDASH_COOKIES_SECURE # Secure cookie flag
REDASH_AUTH_TYPE # Auth method
Performance:
SQLALCHEMY_POOL_SIZE # DB connection pool
WORKERS_COUNT # Background workers
QUEUES # RQ queues to process
REDASH_SCHEMAS_REFRESH_SCHEDULE # Minutes between refresh
Docker Services
Service
Port
Purpose
server
5000
Flask API
scheduler
-
RQ scheduler
worker-server
5001
Worker HTTP
redis
6379
Cache/queue
postgres
5432
Database
plywood
3000
OLAP server
email
1080, 1025
Mail (dev)
Development
Quick Start
# Start all services
docker compose up --build
# Initialize database
docker compose run server create_db
# Create test database
docker compose run --rm postgres psql -h postgres -U postgres -c "create database tests"# Watch frontend
npm run watch
Entry Points (bin/docker-entrypoint)
Command
Purpose
server
Production Flask (gunicorn)
dev_server
Development Flask (auto-reload)
debug
Flask with debugger (PTVSD)
worker
RQ worker (supervisord)
dev_worker
Dev RQ worker (watch)
dev_scheduler
RQ scheduler
worker_server
Worker HTTP server
create_db
Initialize tables
shell
Python shell
manage
CLI commands
tests
Run pytest
NPM Scripts
npm run build # Production build
npm run watch # Watch mode
npm run test# Jest tests
npm run cypress # E2E tests
npm run lint # ESLint
npm run build:plywood # Build Plywood
npm run build:viz # Build viz-lib
Makefile
make up # Start services
make create_database # Init DB
make tests # Backend tests
make frontend-unit-tests # Frontend tests
make lint # Linting
make build # Production build
make clean # Clean Docker
Key Files Reference
Backend Core
File
Purpose
redash/__init__.py
Global init (Redis, RQ, Mail)
redash/app.py
Flask app factory
redash/wsgi.py
Production entry
redash/settings/__init__.py
Configuration (400+ vars)
redash/models/__init__.py
ORM models (1,771 lines)
redash/handlers/queries.py
Query API
redash/handlers/reports.py
Report API
redash/handlers/dashboards.py
Dashboard API
Plywood Integration
File
Purpose
redash/plywood/plywood.py
PlywoodApi client
redash/plywood/hash_manager.py
Hash serialization
redash/plywood/objects/data_cube.py
OLAP model
Frontend
File
Purpose
client/app/index.js
React entry
client/app/components/TurniloComponent/
OLAP UI
client/app/pages/queries/
Query editor
client/app/pages/reports/
Report viewer
Plywood Server
File
Purpose
plywood/src/app.ts
Express app
plywood/src/endpoint/
API endpoints
plywood/src/formatter/attributesFormatter/
Column parsing
Build & Config
File
Purpose
Dockerfile
Multi-stage build
docker-compose.yml
Dev services
pyproject.toml
Python deps
client/package.json
Frontend deps
bin/docker-entrypoint
Container entry
Authentication & Security
Auth Methods
API Key - Token-based for scripts
OAuth 2.0 - Google, GitHub
SAML 2.0 - Enterprise SSO
LDAP - Directory services
Permission Levels
Level
Access
View
Read-only
Edit
Modify objects
Admin
Full control + sharing
Security Features
CSRF protection (Flask-WTF)
Rate limiting (Flask-Limiter)
CSP headers (Flask-Talisman)
Secure cookies
Encrypted credentials (FernetEngine)
SSH tunneling (Paramiko)
Visualization Types
Built-in (viz-lib/)
Chart (line, bar, scatter, area)
Table
Heatmap
Map (Leaflet)
Funnel
Gauge
Number
Pivot table
Sankey
Word cloud
Turnilo Visualizations
Pivot table with drill-down
Detailed records
Dimension/measure cross-tabs
Time series with aggregations
Generated for development reference. Last updated: 2026-02-04