Skip to main content
Version: v2.10.0

What Is Supported

We implement a Databricks-style dbutils object for Yeedu Spark notebooks and jobs. Six namespaces, roughly seventy per cent of the calls a real Databricks codebase actually uses, and no pretending about the rest.

This page is the inventory. Call by call, what we implement, what we don't, and what you do instead.

Getting a dbutils object

LanguageHow it is obtainedNotes
Pythonfrom dbutils import dbutilsExplicit import
PythonAlready in scope as a builtinAvailable once sitecustomize.py from the dbutils package is installed into the runtime's site-packages
Scala / JavaDBUtils.get()Root entry point is com.databricks.sdk.scala.dbutils.DBUtils

With sitecustomize.py installed, the runtime also exposes YeeduDeltaTable and its alias YeeduDeltaTables as builtins, so Delta table handles work without an import too.

The object itself is a lazy proxy. Importing it starts no Spark session and touches no JVM. Each namespace is constructed the first time you reach for it, which is why a Python REPL that imports dbutils doesn't spend ten seconds booting Spark before it shows you a prompt.

Namespace accessedWhat gets loaded
dbutils.fsdbutils.fs_utils.fs.FS, which creates or attaches a SparkSession
dbutils.secretsdbutils.secrets.secrets.Secrets
dbutils.widgetsdbutils.widgets.widgets.Widgets
dbutils.notebookdbutils.notebook.notebook_utils.NotebookUtils
dbutils.librarydbutils.library.library.Library
dbutils.jobsdbutils.jobs.task_values.TaskValues, exposed as dbutils.jobs.taskValues

Six names resolve. Everything else raises AttributeError.

warning

dbutils.jobs.taskValues is the path that works. Databricks code written that way runs unchanged. A bare top-level dbutils.taskValues does not resolve, because there is no such attribute on the proxy.

How to read the support matrix

The Migration check column says whether our job-readiness analyser recognises the call. That analyser compares each dbutils call it finds against a fixed set, and anything outside the set lands in job_readiness_report.csv as a blocker.

The set is deliberately conservative and slightly smaller than what we actually implement, which is why a handful of calls below are marked "Supported" and "Not on the list" at the same time: dbutils.widgets.set, dbutils.widgets.getArgument, dbutils.secrets.list, dbutils.secrets.init, every namespace's help, and YeeduDeltaTable.forName all run perfectly well and none of them appear in the analyser's allowlist, so a job using them gets flagged as not ready even though it will execute. Treat those flags as false positives.

The reverse never happens. Nothing on the allowlist is missing from the runtime.

dbutils.fs

CallPython signatureStatusMigration checkNotes
lsls(path, recurse=False)SupportedRecognisedReturns file-info objects with path, name, size, modificationTime, isDir, isFile. recurse=True walks subdirectories
headhead(file, maxBytes=65536)SupportedRecognisedRaises if file is a directory. Reads UTF-8, stopping on the byte budget
putput(file, contents, overwrite=False)SupportedRecognisedRaises if the target exists and overwrite=False
cpcp(src, dst, recurse=False, overwrite=False)SupportedRecognisedRaises if src is a directory and recurse=False
mvmv(src, dst, recurse=False)SupportedRecognisedImplemented as copy-then-delete
rmrm(path, recurse=False)SupportedRecognisedRaises IOError on a non-empty directory when recurse=False
mkdirsmkdirs(path)SupportedRecognisedCreates parents as needed
helphelp(function_name=None)SupportedNot on the listWith no argument, lists the available fs functions
mountNot implementedNot on the listNo mount API exists in Yeedu dbutils
mountsNot implementedNot on the list
unmountNot implementedNot on the list
refreshMountsNot implementedNot on the list
updateMountNot implementedNot on the list
cacheFiles / cacheTableNot implementedNot on the list
uncacheFiles / uncacheTableNot implementedNot on the list

Path handling

Path formHow it resolves
/files/...Yeedu workspace file, served over the Yeedu REST API, for put, cp, mv, rm, and mkdirs only
s3://...Rewritten to s3a:// before the Hadoop FileSystem call
Anything else (abfss://, file:/, hdfs://, bare paths)Resolved through the Hadoop FileSystem API using the session's Hadoop configuration

cp and mv bridge those two worlds, and all four direction combinations work: workspace to workspace, external to workspace, workspace to external, external to external. When the destination is a directory, or ends with /, the source filename is appended.

warning

ls and head have no /files/ branch, in either the Python or the Scala implementation. They always resolve through the Hadoop FileSystem API. Listing or previewing a Yeedu workspace file by its /files/ path is not covered by those two calls.

dbutils.fs

dbutils.widgets

CallPython signatureStatusMigration checkNotes
texttext(name, default_value="", label=None)SupportedRecognisedlabel defaults to name
dropdowndropdown(name, default_value, choices, label=None)SupportedRecognised
comboboxcombobox(name, default_value, choices, label=None)SupportedRecognised
multiselectmultiselect(name, default_value, choices, label=None)SupportedRecognised
getget(name)SupportedRecognisedRaises KeyError if the widget does not exist, matching Databricks
getAllgetAll()SupportedRecognisedReturns {name: value}
removeremove(name)SupportedRecognisedIdempotent; a missing widget is not an error
removeAllremoveAll()SupportedRecognised
setset(name, value)SupportedNot on the listA Yeedu addition, absent from the Databricks dbutils.widgets API
getArgumentgetArgument(name, default=None)SupportedNot on the listDoes not create a widget. Raises KeyError if the widget is absent and no default is given
helphelp(function_name=None)SupportedNot on the list

dbutils.widgets.get resolves a value from the first source that has one.

PrioritySourceSet by
1Runtime bindingsThe arguments passed to dbutils.notebook.run in the parent notebook
2Airflow XComThe surrounding Airflow task context
3Widget backend stateWidgets created or edited in the notebook itself

Values from sources 2 and 3 containing {{ ... }} are template-resolved before they come back. Runtime bindings are returned literally. Requests against the widget backend retry up to five times before a missing widget is reported.

note

Arguments passed to dbutils.notebook.run are stringified. None becomes an empty string, and every key and value is coerced with str().

Widget values at run time

dbutils.secrets

CallPython signatureStatusMigration checkNotes
getget(scope, key)SupportedRecognisedReturns a SecretValue, a str subclass whose repr is [REDACTED]
getBytesgetBytes(scope, key)SupportedRecognisedReturns a SecretBytes, a bytes subclass whose str and repr are [REDACTED]
listScopeslistScopes()SupportedRecognised
listlist(scope)SupportedNot on the listLists secret names within a scope
initinit(host=None, token=None)SupportedNot on the listNot part of the Databricks API. Optional, since the namespace auto-initialises from configuration on first use
helphelp(function_name=None)SupportedNot on the list

Secrets are fetched from the Databricks Secrets API at /api/2.0/secrets using the configured host and token. Your scopes and keys stay exactly where they are.

We also mask them.

BehaviourDetail
print() maskingThe package replaces builtins.print, so a retrieved secret value comes out as [REDACTED]
Notebook cell output maskingWith IPython present, the display formatter's text/plain output is wrapped and masked the same way
Explicit revealSecretValue.reveal() returns the real str; SecretBytes.reveal() returns the real bytes
String concatenationSecretValue + other returns a plain str, so concatenations are not themselves registered as secrets
SecretBytes concatenationConcatenating with a str raises TypeError. Use bytes
warning

Masking is substring-based over values the process has already retrieved. It hides secrets from print and from notebook cell output. It is not a guarantee against every exfiltration path.

dbutils.secrets

dbutils.notebook

CallPython signatureStatusMigration checkNotes
runrun(path, timeout_seconds, arguments=None)SupportedRecognisedSee the constraints below
exitexit(msg="")SupportedRecognisedInside a run, raises an internal CleanExit so the parent receives msg. Outside a run, returns msg
entry_point.getCurrentBindingsgetCurrentBindings()SupportedNot on the listReturns the current runtime bindings dictionary
getContextNot implementedNot on the list

dbutils.notebook.run is implemented, and it's the call most people expect to lose. The child notebook is driven over a WebSocket connection to the Yeedu notebook kernel. In Scala it's overloaded for a java.util.Map, a Scala Map, and a JSON String.

Four constraints are enforced in code, and one of them differs from Databricks.

RuleBehaviour
path is requiredOmitting it raises ValueError
Extension inferenceIf the final path segment has no ., .ipynb is appended
timeout_seconds is required0, None, or omitting it raises ValueError. Unlike Databricks, there is no "no timeout" mode
arguments typeA dict, a JSON string, or None. Anything else raises TypeError; malformed JSON raises ValueError

dbutils.jobs.taskValues

CallPython signatureStatusMigration checkNotes
setset(key, value)SupportedRecognisedvalue must be JSON-serialisable, otherwise TypeError
getget(taskKey, key, default=None, debugValue=None)SupportedRecognisedOn a missing value, returns debugValue, then default, otherwise raises KeyError

Task values are stored as Airflow XCom entries through the Yeedu API, so they need Airflow context to be configured.

ConstraintValue
Maximum serialised payload49152 bytes, 48 KiB; exceeding it raises ValueError
Requiresdag_id, dag_run_id, and task_id to be resolvable

dbutils.library

CallPython signatureStatusMigration checkNotes
restartPythonrestartPython()SupportedRecognisedRestarts the active IPython kernel via IPython.Application.instance().kernel.do_shutdown(restart=True). Raises if no IPython kernel is present
YeeduDeltaTable.forNameforName(spark, table)Supported, a Yeedu additionNot on the listResolves the table's storage location with DESCRIBE DETAIL, then returns DeltaTable.forPath
install, installPyPINot implementedNot on the listThere is no library install API. Only restartPython exists
note

The Scala and Java Library.restartPython() takes a different route. It calls the Yeedu REST endpoint workspace/{workspace_id}/notebook/run/{notebook_id}/kernel/restart rather than driving IPython.

dbutils.library

Namespaces we do not implement

Databricks namespaceAlternative
dbutils.dataNo equivalent. Use Spark SQL or DataFrame operations directly
dbutils.credentialsNo equivalent
dbutils.apiNo equivalent
dbutils.metaNo equivalent
dbutils.previewNo equivalent
dbutils.taskValues (top-level)Use dbutils.jobs.taskValues

Working code

from dbutils import dbutils

# Filesystem
for info in dbutils.fs.ls("/data"):
print(info.path, info.size, info.isDir)

dbutils.fs.put("/files/reports/summary.txt", "row_count=42", overwrite=True)
dbutils.fs.cp("/files/reports/summary.txt", "abfss://container@account.dfs.core.windows.net/archive/")

# Widgets
dbutils.widgets.text("input", "default_value", "Input Parameter")
dbutils.widgets.dropdown("env", "dev", ["dev", "qa", "prod"], "Environment")
user_input = dbutils.widgets.get("input")

# Secrets
secret = dbutils.secrets.get("my_scope", "my_key")
print(secret) # [REDACTED]
print(secret.reveal()) # actual value

# Notebook orchestration; timeout_seconds is mandatory
result = dbutils.notebook.run(
"/Workspace/Team/child",
timeout_seconds=600,
arguments={"limit": 10},
)

# Task values
dbutils.jobs.taskValues.set("row_count", 42)
count = dbutils.jobs.taskValues.get("upstream_task", "row_count", default=0)

SQL that does not carry across

These constructs are common against Databricks Delta tables and unsupported in Yeedu. Alternatives where one exists.

Unsupported featureDatabricks formYeedu alternative
DELETE FROM with a subqueryDELETE FROM <table> WHERE id IN (SELECT id FROM <table>)Build a replacement table using MINUS
UPDATE with a subqueryUPDATE <table> SET <column> = <value> WHERE <condition>Use MERGE INTO for conditional updates
TRUNCATE TABLETRUNCATE TABLE <table>Use DELETE FROM <table>
USE DATABASE syntaxUSE DATABASE <database_name>Use USE <database_name>
SHOW EXTERNAL LOCATIONSSHOW EXTERNAL LOCATIONSNo equivalent. Our utility flags any job using it as not ready
SHOW GRANTS ON EXTERNAL LOCATIONSSHOW GRANTS ON EXTERNAL LOCATION <name>No equivalent. Also flagged as not ready

Identity-bound SQL functions

Four built-in functions resolve against the Databricks identity running the query. Our utility detects each of them and records an OAuth requirement, because validating them needs Databricks OAuth credentials.

Function
current_user()
session_user()
is_member()
is_account_group_member()
warning

Behaviour after migration depends on the identity Yeedu executes under, which is often not the identity Databricks executed under. Review every use before trusting the result.

Databricks features with no Yeedu equivalent

Databricks Workflows

Yeedu has no native multi-task workflow engine with dependencies. Orchestration runs on Airflow or Prefect, and we generate the Airflow DAGs from your Databricks job definitions. See Job Migration.

Multi-language notebooks

One language per notebook. Pick Scala or Python. Databricks-style %python and %scala switching inside a single notebook isn't available, so mixed notebooks have to be split before they'll run.

DBFS

No DBFS, and no mount API, since dbutils.fs.mount and its siblings aren't implemented. Job task files under /dbfs/ are skipped by the migration utility rather than downloaded. Move them to fully qualified storage URIs such as abfss:// and s3a://, or to Yeedu workspace paths under /files/.

Delta Lake table handles

DeltaTable.forName(spark, "catalog.schema.table") becomes YeeduDeltaTable.forName(spark, "catalog.schema.table"), which resolves the table's physical location before opening it. Our utility performs this rewrite for you and comments out the from delta.tables import DeltaTable import.

Configuring dbutils

Settings come from Spark configuration entries and environment variables.

warning

Precedence differs between the two implementations. The Python package reads the Spark configuration entry first and falls back to the environment variable. The Scala and Java package reads the environment variable first and falls back to the Spark configuration entry. Where both may be set, set them consistently.

Full configuration reference

Settings with both a Spark conf key and an environment variable:

PurposeSpark conf keyEnvironment variableDefault in code
Yeedu API tokenspark.yeedu.tokenYEEDU_TOKENdefault-token
Workspace IDspark.yeedu.workspace_idYEEDU_WORKSPACE_ID-1
Notebook run IDspark.yeedu.job_idYEEDU_JOB_ID-1
Default catalog namespark.sql.defaultCatalogYEEDU_CATALOG_NAMEdefault_catalog
Databricks host for secretsspark.sql.catalog.<catalog>.uriYEEDU_DATABRICKS_HOSTdefault-host
Databricks token for secretsspark.sql.catalog.<catalog>.tokenYEEDU_DATABRICKS_TOKENdefault-token
Airflow DAG IDspark.yeedu.dag_idYEEDU_DAG_IDempty
Airflow DAG run IDspark.yeedu.dag_run_idYEEDU_DAG_RUN_IDempty
Airflow task IDspark.yeedu.task_idYEEDU_TASK_IDempty
Mapped-task indexspark.yeedu.map_indexYEEDU_MAP_INDEX-1

<catalog> in the secrets keys is the resolved default catalog name.

Environment-variable-only settings:

VariableDefaultPurpose
YEEDU_RESTAPI_SSL_ENABLEDtruetrue selects https, anything else selects http
YEEDU_RESTAPI_HOSTNAMElocalhostYeedu REST API host
YEEDU_RESTAPI_PORT8080Yeedu REST API port
YEEDU_AIRFLOW_VERIFY_SSLfalsetrue enables TLS verification for notebook orchestration calls
YEEDU_SSL_CERT_FILEunsetCustom CA bundle path, used when YEEDU_AIRFLOW_VERIFY_SSL=true
YEEDU_TASK_ID_JOB_CONF_KEYtask_idJob-conf key from which the Airflow task ID is read

The API base URL is assembled as <protocol>://<hostname>:<port>/api/v1.