Custom Database Class ​
RobotFramework Dashboard supports custom database implementations. This page explains how to create your own database class, which interfaces must be implemented, and how to use it with the dashboard command line interface.
The Dashboard processes Robot Framework output files and stores them in a database. By default it uses a SQLite3 database, but you are free to implement any backend you want—MySQL, PostgreSQL, MongoDB, flat-file systems, cloud storage, or fully custom solutions.
Example Implementations ​
The project includes several reference implementations. These demonstrate how to structure your own custom database class and how to correctly implement all required methods.
Available examples:
- abstractdb.py: base abstract class to extend
- sqlite3.py: default implementation used by RobotDashboard
- mysql.py: example MySQL implementation
These files define the required structure and show how each method should behave. If you create your own custom database implementation, you are encouraged to submit it via pull request or github issue so it can be added to the example folder to help others.
Basic Custom Class Structure ​
To implement your own database class, extend the AbstractDatabaseProcessor from the example folder.
A minimal structure looks like this:
from robotframework_dashboard.abstractdb import AbstractDatabaseProcessor
class DatabaseProcessor(AbstractDatabaseProcessor):
# implement all abstract methods hereYou may name the Python file anything you want. The only rule is that your class must be named:
DatabaseProcessor
This is the class name the dashboard dynamically loads at runtime.
Custom Class Requirements ​
Your custom database class must implement the following methods:
__init__(self, database_path: Path) ​
- Responsible for initial setup.
- Should create the database file (if applicable) and initialize tables or structures.
database_pathis provided by the dashboard and points to the configured database file or directory.
open_database(self) ​
- Opens a database connection.
- Must set a property such as
self.connectionfor later use.
close_database(self) ​
- Closes the connection.
- Must be implemented to ensure resources are cleaned up properly.
run_start_exists(self, run_start: str) -> bool ​
- Checks whether a run with the given
run_starttimestamp already exists. - Returning
Falsealways is acceptable but inefficient—duplicate processing will occur.
insert_output_data(self, output_data: dict, tags: list, run_alias: str, path: Path, project_version: str) ​
This method handles the actual insertion of all run-related data.
You must process:
output_data— contains runs, suites, tests, and keywordstags— list of tags associated with the runrun_alias— a human-friendly alias chosen by the user or systempath— path tooutput.xmlproject_version— version string associated with this run (from--projectversionorversion_tags), may beNone
You can inspect the example implementations for the exact structure of output_data and how each record is inserted.
get_data(self) -> dict ​
Must return all data in this dictionary format:
{
"runs": [
{
"run_start": "2024-10-13 22:33:19",
"full_name": "Robotframework-Dashboard",
"name": "Robotframework-Dashboard",
"total": 6,
"passed": 4,
"failed": 1,
"skipped": 1,
"elapsed_s": "6.313",
"start_time": "2024-10-13 22:33:19.673821",
"tags": "",
"run_alias": "output-20241013-223319",
"path": "results/output-20241013-223319.xml",
"metadata": "[]",
"project_version": "1.2.1"
},
{...etc}
],
"suites": [
{
"run_start": "2024-10-13 22:33:19",
"full_name": "Robotframework-Dashboard.01 Login",
"name": "01 Login",
"total": 2,
"passed": 2,
"failed": 0,
"skipped": 0,
"elapsed_s": "1.21",
"start_time": "2024-10-13 22:33:20.120000",
"run_alias": "output-20241013-223319",
"id": "s1-s1"
},
{...etc}
],
"tests": [
{
"run_start": "2024-10-13 22:33:19",
"full_name": "Robotframework-Dashboard.01 Login.Valid Login",
"name": "Valid Login",
"passed": 1,
"failed": 0,
"skipped": 0,
"elapsed_s": "0.55",
"start_time": "2024-10-13 22:33:20.125000",
"message": "",
"tags": "[\"sanity\"]",
"run_alias": "output-20241013-223319",
"id": "s1-s1-t1"
},
{...etc}
],
"keywords": [
{
"run_start": "2024-10-13 22:33:19",
"name": "Open Browser",
"passed": 6,
"failed": 0,
"skipped": 0,
"times_run": "6",
"total_time_s": "2.100",
"average_time_s": "0.350",
"min_time_s": "0.200",
"max_time_s": "0.500",
"run_alias": "output-20241013-223319",
"owner": "SeleniumLibrary"
},
{...etc}
]
}Each type must be a list of dictionaries matching what RobotDashboard expects.
list_runs(self) ​
- Prints all runs in the database with identifiable information.
- This is required for CLI features like:bash
robotdashboard --database list - You may leave this function empty if you do not need command-line listing, but it must exist.
remove_runs(self, remove_runs: list) ​
remove_runs may contain any of the following:
index=<n>— remove by index (supports ranges with:and lists with;)run_start=<timestamp>— remove by exact run_start timestampalias=<alias>— remove by run aliastag=<tag>— remove all runs matching the given taglimit=<n>— keep only the N most recent runs, removing all older ones
You must correctly interpret and remove runs accordingly. If you only want to support removing based on run_start or index you could only implement those usages.
(Optional) vacuum_database(self) ​
Called after run removal when the --novacuum flag is not set.
In the default SQLite implementation, this runs VACUUM to reclaim disk space after deletions.
If your database backend does not need compaction, you can safely omit this method or implement it as a no-op. Make sure you then provide the --novacuum flag when running the dashboard to avoid errors.
(Optional) update_output_path(self, log_path: str) ​
This is only required when using:
- The Dashboard Server, and
uselogs=Trueoption
In this approach, you store log.html and related files on the server, and this method updates the stored path.
If you do not use server-side log storage, you can safely omit this method.
(Optional) _get_run_paths(self) -> dict ​
Returns a dict mapping run_start to path for all runs currently in the database, e.g.:
{
"2024-10-13 22:33:19.673821": "robot_logs/log-20241013-223319.html",
...
}This is used by the server's /remove-outputs endpoint to automatically delete the corresponding log.html file from the robot_logs folder whenever an output is removed.
If not implemented, the default returns {} and no log files will be automatically cleaned up on output removal. Only relevant when using the Dashboard Server with uselogs=True.
Important Notes ​
Do not use relative imports.
Custom classes run dynamically and relative paths will fail.Class name must be exactly
DatabaseProcessor.Your Python file name can be anything.
Look at the examples before implementing your own:
- abstractdb.py: base abstract class to extend
- sqlite3.py: default implementation used by RobotDashboard
- mysql.py: example MySQL implementation