What you will be able to do
- Configure an artifacts mapping that builds a Python wheel with uv, Poetry or setuptools
- Declare whl, PyPI and requirements.txt dependencies on bundle job tasks
- Wire pyproject.toml dependencies into a pipeline with an editable environment
- Define and generate bundle resources in Python with the python section and load_resources
1.Building your src/ package as a wheel artifact
In a scalable bundle, shared logic belongs in a Python package under src/ that is built into a wheel, not copied between notebooks. The default-python template already does this: it builds the wheel with uv from a pyproject.toml. The build is set in the top-level artifacts mapping in databricks.yml.
# databricks.yml
...
artifacts:
python_artifact:
type: whl
build: uv build --wheel
...Checkpoint 1 of 6· Fill the gap
What artifact type tells the bundle it is building a Python wheel?
artifacts:
python_artifact:
type: ?
build: uv build --wheelBundles use whl for wheel artifacts, the same key used under a task's libraries. pypi is a library source, not an artifact type.
uv is not the only option. The documentation also shows Poetry (build: poetry build) and setuptools builds that keep the package under src/my_package with __init__.py, main.py and my_module.py. The task then runs the package through a python_wheel_task and lists the built file under libraries as ./dist/*.whl.
Deploying the bundle builds the wheel. The built file goes into the bundle's workspace folder under .bundle/<project-name>/dev/artifacts/.internal/. If the wheel was already built somewhere else, such as an earlier CI step, you leave out the artifacts mapping.
Checkpoint 2 of 6· Check yourself
A CI pipeline builds the wheel in an earlier step. The team removes the artifacts mapping from databricks.yml but keeps - whl: ./dist/*.whl under the task's libraries. What does bundle deploy do?
Without an artifacts mapping, the CLI does not build anything. It treats the wheel as already built and deploys the whl files listed under libraries.
“The Databricks CLI will then assume that the Python wheel file is already built”Source: docs.databricks.com
Sources1
2.Declaring library dependencies on tasks
Jobs and pipelines also depend on outside libraries, and these are declared in the bundle configuration too. Python dependencies on a job task go in its libraries list as wheel files, PyPI packages or a requirements file. JARs and Maven or CRAN packages are also supported.
resources:
jobs:
my_job:
# ...
tasks:
- task_key: my_task
# ...
libraries:
- whl: ./my-wheel-0.1.0.whl
- whl: /Workspace/Shared/Libraries/my-wheel-0.0.1-py3-none-any.whl
- whl: /Volumes/main/default/my-volume/my-wheel-0.1.0.whl| Mapping | Fields | Notes |
|---|---|---|
| whl | path to the .whl | From workspace files, Unity Catalog volumes, cloud object storage, or a local path |
| pypi | package (optional exact version), optional repo | Without repo, the default pip index https://pypi.org/simple/ is used |
| requirements | path to a requirements*.txt | Local, workspace, or Unity Catalog volume path |
| jar / maven | path / coordinates, repo, exclusions | For Java or Scala dependencies |
Where the files are stored matters. Storing libraries in the DBFS root is deprecated and turned off by default from Databricks Runtime 15.1, because any workspace user can change files there. Databricks recommends workspace files, Unity Catalog volumes or package repositories instead.
Checkpoint 3 of 6· Match them up
Match each libraries entry to what it installs
Tap a term, then the definition that fits it.
Each mapping names its source type directly: whl for wheel files, pypi for index packages, requirements for a requirements*.txt file, and maven for Gradle-style coordinates.
“Python library dependencies can also be specified in a requirements*.txt file that is included as part of the job task definition.”Source: docs.databricks.com
Sources2
3.pyproject.toml with uv, and the pipeline exception
The recommended way to manage Python dependencies is uv, with dependencies listed in the bundle's pyproject.toml. The template's pyproject keeps runtime dependencies apart from a dev dependency group used for local work (pytest, ruff, databricks-dlt, databricks-connect, ipykernel). The deployed code then needs only the runtime set.
To give a pipeline every dependency in pyproject.toml, add an editable environment to the pipeline resource that points to the folder where pyproject.toml is deployed. The example also shows two other structural habits: catalog and schema come from bundle variables, and the source is picked up with a glob over the transformations/ folder.
resources:
pipelines:
test_uv_etl:
name: test_uv_etl
catalog: ${var.catalog}
schema: ${var.schema}
serverless: true
root_path: '../src/test_uv_etl'
libraries:
- glob:
include: ../src/test_uv_etl/transformations/**
environment:
dependencies:
- --editable ${workspace.file_path}Checkpoint 4 of 6· Exam question
An engineer is configuring `dev` and `prod` targets in a single `databricks.yml` so the same bundle can be validated by individual developers and deployed unattended by a CI/CD pipeline into a shared production workspace. Which two configuration choices are appropriate for the `prod` target specifically? (Choose 2.)(Select 2)
Correct answers: A, B — Set `mode: production` on the `prod` target so the CLI enforces stricter checks, such as requiring a fixed `run_as` identity for every deployment to that target.; Set `run_as` on the `prod` target to a service principal so scheduled jobs execute under a shared identity instead of whichever developer last deployed the bundle.
- A. Production mode is the setting meant for shared, unattended deployments; it enforces safeguards such as requiring a fixed `run_as` identity and disabling development-only conveniences that are unsafe outside a personal workspace.
- B. Pinning `run_as` to a service principal for the production target ensures jobs run under a stable, auditable identity rather than inheriting the credentials of whichever engineer happened to trigger the deploy.
- C. Development mode is what appends a username prefix and applies other per-developer conveniences; applying it to the production target would defeat the purpose of a stable, shared deployment.
- D. Leaving `prod` pointed at the same workspace path used for local testing would let developer deployments overwrite production resources, which is the opposite of the isolation a separate target is meant to provide.
- E. Marking the `dev` target as the default only changes which target is picked when none is named on the command line; it does not configure any safeguard on the `prod` target itself and risks accidental production deploys.
Sources2
4.Defining resources in Python
Resource definitions do not have to be YAML. With Python support for bundles you can define resources in Python code alongside YAML resources. You can also generate resources from metadata during deployment, and change YAML- or Python-defined resources while deploying. It needs Databricks CLI 0.275.0 or above. The databricks bundle init pydabs template sets it up.
from databricks.bundles.jobs import Job, Task, NotebookTask
my_pydabs_project_job = Job(
name="my_pydabs_project_job",
tasks=[
Task(
task_key="notebook_task",
notebook_task=NotebookTask(
notebook_path="src/notebook.ipynb",
),
),
],
)Job.from_dict accepts the same structure as a Python dictionary. databricks.yml connects these files through a python section. That section names the virtual environment, which must contain the databricks-bundles package, and the function that loads the resources.
python:
# Activate the virtual environment before loading resources defined in
# Python. If disabled, it defaults to using the Python interpreter
# available in the current shell.
venv_path: .venv
# Functions called to load resources defined in Python.
# See resources/__init__.py
resources:
- 'resources:load_resources'By default, load_resources in resources/__init__.py loads every Python file in the resources package. The CLI calls it during deployment, and it is not used after that. Because it is ordinary Python, it can build resources in a loop. This is a scalable pattern when many jobs differ only by a parameter.
def load_resources(bundle: Bundle) -> Resources:
resources = load_resources_from_current_package_module()
for country in ["US", "NL"]:
resources.add_resource(f"my_job_{country}", create_job(country))
return resourcesCheckpoint 5 of 6· Check yourself
A team with an existing YAML bundle wants to generate 40 near-identical jobs in Python. Which statement is correct?
Existing YAML bundles are extended by adding a python section. Resources defined in Python live alongside YAML resources, and load_resources runs only at deployment.
“These definitions can coexist with resources defined in YAML.”Source: docs.databricks.com
Checkpoint 6 of 6· Exam question
A CI/CD pipeline runs `databricks bundle deploy --target prod` against the `prod` target, which has `mode: production` set. The deploy fails with an error stating that a `run_as` identity must be specified for the target. What is the most direct fix that keeps the production deployment unattended and reproducible?
Correct answer: A — Add a `run_as` block under the `prod` target that sets `service_principal_name` to the pipeline's own principal, so jobs run under that fixed identity.
- A. Production mode requires an explicit `run_as` identity precisely so unattended deploys have a fixed, known owner; setting it to the pipeline's service principal satisfies that check and keeps ownership consistent across runs.
- B. Switching to development mode would silence the error but also removes the production safeguards the team relies on, such as identity pinning and protection against concurrent-run cancellation, which is not an acceptable trade-off here.
- C. Omitting `mode` does not disable the identity check for a target already treated as production-like; the requirement comes from the mode being set to `production`, and removing it changes other safeguards without resolving the underlying need for a stable identity.
- D. A `permissions` block controls who can view or manage the deployed resources after deployment; it does not satisfy the `run_as` requirement, which specifically governs the identity jobs execute under.
Sources3
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.If a bundle has no artifacts mapping, no wheel is deployed for its python_wheel_task.Why is that wrong?
Without artifacts, the CLI treats the wheel as already built and deploys the whl files listed under libraries. Leaving out the mapping is the documented way to deploy a wheel built elsewhere.
2.Adding a package to pyproject.toml is enough for a bundle-deployed pipeline to use it during development.Why is that wrong?
Pipeline dependencies are cached during development. Declare them in the pipeline's environment section, for example as an editable install of the deployed project.
Covered in pyproject.toml with uv, and the pipeline exception
3.Uploading wheels to the DBFS root is still the standard place for bundle libraries.Why is that wrong?
Libraries in the DBFS root are deprecated and turned off by default on newer runtimes. Use workspace files, Unity Catalog volumes or package repositories.
Covered in Declaring library dependencies on tasks
Practise it for real
Create a default-python bundle that builds a wheel from src/, deploy it to the dev target, and run its job
1.Run
databricks bundle init, keep the default-python template, answer no to the notebook job and ETL pipeline, yes to the sample Python package and serverless, and enter an existing Unity Catalog catalogWhy: The template produces the standard layout: databricks.yml, resources/sample_job.job.yml, src/ and tests/
You should see: A new project folder (my_project by default) with those files
2.From the bundle root, run
databricks bundle validateWhy: Validation catches configuration errors before anything reaches the workspace
You should see: A summary of the bundle configuration and no errors
3.Run
databricks bundle deploy --target devWhy: Deploying builds the wheel from src/ and creates the job in development mode
You should see: The .whl under .bundle/<project-name>/dev/artifacts/.internal and a job named [dev <your-username>] sample_job with one python_wheel_task
4.Run
databricks bundle run --target dev sample_joband open the printed Run URLWhy: This confirms the deployed wheel's entry point runs as a job task
You should see: The task finishes with a green title bar
Stuck? Get a nudge
If you change anything after deploying, validate and deploy again before the next run.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“a bundle is created that shows how to configure a bundle that builds a Python wheel using uv and pyproject.toml.”
↩︎ Building your src/ package as a wheel artifact“Next, deploy the bundle to your remote Databricks workspace. This builds the Python wheel file.”
↩︎ Building your src/ package as a wheel artifact“modify the following bundle configuration file by omitting the artifacts mapping.”
↩︎ Exam trap 1“The Databricks CLI will then assume that the Python wheel file is already built”
↩︎ Checkpoint - 2.
“Library dependencies are declared in your bundle configuration files.”
↩︎ Declaring library dependencies on tasks“Databricks recommends uploading all libraries, including Python libraries, JAR files, and Spark connectors, to workspace files or Unity Catalog volumes”
↩︎ Declaring library dependencies on tasks“uv is the recommended method for managing Python library dependencies.”
↩︎ pyproject.toml with uv, and the pipeline exception“adding an editable environment that points to the folder where pyproject.toml is deployed”
↩︎ pyproject.toml with uv, and the pipeline exception“add dependencies to the 'environment' section of your pipeline.yml file instead”
↩︎ Exam trap 2“storing library files in the DBFS root is deprecated and disabled by default in Databricks Runtime 15.1 and above.”
↩︎ Exam trap 3“Python library dependencies can also be specified in a requirements*.txt file that is included as part of the job task definition.”
↩︎ Checkpoint“LIMITATION: for pipelines, dependencies are cached during development;”
↩︎ Prediction - 3.
“Python files are loaded through an entry point specified in the python section in databricks.yml:”
↩︎ Defining resources in Python“After deployment, this function is not used.”
↩︎ Defining resources in Python“The specified virtual environment must contain the installed databricks-bundles PyPi package.”
↩︎ Defining resources in Python“You can use Python to create resources programmatically.”
↩︎ Defining resources in Python“These definitions can coexist with resources defined in YAML.”
↩︎ Checkpoint