<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>article From Idea to Code: Building with the Databricks SDK for Python in Technical Blog</title>
    <link>https://community.databricks.com/t5/technical-blog/from-idea-to-code-building-with-the-databricks-sdk-for-python/ba-p/58894</link>
    <description>&lt;P&gt;&lt;SPAN&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-right" image-alt="Databricks Python SDK launch" style="width: 400px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6058iEF430D45F50C4705/image-size/medium?v=v2&amp;amp;px=400" role="button" title="kimberlyma_0-1706723334148.png" alt="Databricks Python SDK launch" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Databricks Python SDK launch&lt;/span&gt;&lt;/span&gt;Six months ago Databricks announced the release of the Databricks SDK for Python to much fanfare. Since then it has been adopted by over 1,000 customers and is used in several open source tools such as &lt;/SPAN&gt;&lt;A href="https://github.com/datahub-project/datahub" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Datahub&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Over the past six months I've worked with many folks - helping answer questions or creating bespoke code snippets for their projects. We have robust &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/sdk-python.html" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;documentation&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; for the SDK as well as a repository of &lt;/SPAN&gt;&lt;A href="https://github.com/databricks/databricks-sdk-py#code-examples" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;examples&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;, but, there are not examples for every single thing you may want to do with the SDK. So, I figured it will benefit some folks to walk through how I approached familiarizing myself with the codebase and how to develop new projects quickly.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The focus of this blog is to demystify the Python SDK - the authentication process and the components of the SDK by walking through the start-to-end development process. I'll also be showing how to utilize IntelliSense and the Debugger for real-time suggestions in order to reduce the amount of context-switching from the IDE to documentation and code examples.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;What is the Databricks SDK for Python&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;I&gt;&lt;SPAN&gt;And why you should use it&lt;/SPAN&gt;&lt;/I&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;The Databricks Python SDK lets you interact with the Databricks Platform programmatically using Python. It covers the entire Databricks API surface and Databricks REST operations. While you can interact directly with the API via curl or a library like '&lt;/SPAN&gt;&lt;SPAN&gt;&lt;FONT face="courier new,courier"&gt;requests&lt;/FONT&gt;'&lt;/SPAN&gt;&lt;SPAN&gt;&amp;nbsp;there are benefits to utilizing the SDKs such as:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Secure and simplified authentication via &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/auth/index.html#databricks-client-unified-authentication" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Databricks client-unified authentication&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Built-in debug logging with sensitive information automatically redacted&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Support to wait for long-running operations to finish (kicking off a job, starting a cluster)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Standard iterators for paginated APIs (we have multiple pagination types in our APIs!)&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;Retrying on transient errors&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;There are numerous practical applications, such as building multi-tenant web applications that interact with your ML models or a robust UC migration toolkit like Databricks Labs project&lt;/SPAN&gt;&lt;A href="https://github.com/databrickslabs/ucx" target="_blank" rel="noopener"&gt; &lt;SPAN&gt;UCX&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;. Don’t forget the silent workhorses; those simple utility scripts that are more limited in scope but automate an annoying task such as bulk updating cluster policies, dynamically adding users to groups, or simply writing data files to UC Volumes. Implementing these types of scripts is a great way to familiarize yourself with the Python SDK and Databricks APIs.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Scenario&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Imagine my business is establishing best practices for development and CI/CD on Databricks. We're adopting &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/bundles/index.html" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;DABs&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; to help us define and deploy workflows in our development and production Workspaces, but in the meantime, we need to audit and clean up our current environments. We have a lot of jobs people created in our dev Workspace via the UI. One of the platform admins observed many of these jobs are inadvertently configured to run on a recurring schedule, racking up unintended costs. As part of the clean-up process, we want to identify any scheduled jobs in our development Workspace with an option to pause them. We’ll need to figure out:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;How to install the SDK&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;How to connect to the Databricks Workspace&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;How to list all the jobs and examine their attributes&lt;/SPAN&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;How to log the problematic jobs - or a step further, how to call the API to pause their schedule&lt;/SPAN&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;&lt;SPAN&gt;Development environment&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;Before diving into the code, you need to set up your development environment. I highly recommend using an IDE that has a comprehensive code completion feature as well as a debugger. Code completion features, such as&lt;/SPAN&gt;&lt;A href="https://code.visualstudio.com/docs/editor/intellisense" target="_blank" rel="noopener"&gt; &lt;SPAN&gt;Intellisense in VS Code&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;, are really helpful when learning new libraries or APIs - they provide useful contextual information, autocompletion, and aid in code navigation. For this blog, I’ll be using Visual Studio Code so I can also make use of the&lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/vscode-ext/index.html" target="_blank" rel="noopener"&gt; &lt;SPAN&gt;Databricks Extension&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; as well as&lt;/SPAN&gt;&lt;A href="https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance" target="_blank" rel="noopener"&gt; &lt;SPAN&gt;Pylance&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;. You’ll also need to install the databricks-sdk (&lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/sdk-python.html#get-started-with-the-databricks-sdk-for-python&amp;amp;language-Poetry" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;docs&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;). In this blog, I’m using Poetry + Pyenv. The setup is similar for other tools - just '&lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;poetry add databricks-sdk'&lt;/FONT&gt;&lt;SPAN&gt; or alternatively&lt;/SPAN&gt;&lt;FONT face="courier new,courier"&gt;&amp;nbsp;'pip install databricks-sdk'&lt;/FONT&gt;&lt;SPAN&gt; in your environment.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Authentication&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The next step is to authorize access to Databricks so we can work with our Workspace. There are several ways to do this, but because I’m using the VS Code Extension I’ll take advantage of its authentication integration. It’s one of the tools that uses &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/auth/index.html#databricks-client-unified-authentication" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;unified client authentication&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; - that just means all these development tools follow the same process and standards for authentication and if you set up auth for one you can reuse it amongst the other tools. I set up both the CLI and VS Code Extension previously, but here is a primer on &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/cli/install.html" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;setting up the CLI &lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;and &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/vscode-ext/install.html" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;installing the extension.&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; Once you’ve connected successfully you’ll see a notification banner in the lower right-hand corner and see two hidden files generated in the&amp;nbsp;&lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;.databricks&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; folder - &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;project.json&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; and &lt;/SPAN&gt;&lt;I&gt;&lt;SPAN&gt;databricks.env&lt;/SPAN&gt;&lt;/I&gt;&lt;SPAN&gt; (don’t worry, the extension also handles adding these to .gitignore).&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;For this example, while we’re interactively developing in our IDE we’ll be using what’s called U2M (user-to-machine) OAuth. We won’t get into the technical details, but OAuth is a secure protocol that handles authorization to resources without passing sensitive user credentials such as PAT or username/password that persist much longer than the one-hour short-lived OAuth token.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-align-center"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="OAuth flow for the Databricks Python SDK" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6070iA0042C33AD0BBB8F/image-size/large?v=v2&amp;amp;px=999" role="button" title="image7.gif" alt="OAuth flow for the Databricks Python SDK" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;OAuth flow for the Databricks Python SDK&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;WorkspaceClient vs. AccountClient&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The Databricks API is split into two primary categories - Account and Workspace. They let you manage different parts of Databricks, like user access at the account level or cluster policies in a Workspace. The SDK reflects this with two clients that act as our entry points to the SDK - the &lt;FONT face="courier new,courier"&gt;WorkspaceClient&lt;/FONT&gt; and &lt;FONT face="courier new,courier"&gt;AccountClient&lt;/FONT&gt;. For our example we’ll be working at the Workspace level so I’ll be initializing the &lt;FONT face="courier new,courier"&gt;WorkspaceClient&lt;/FONT&gt;. If you're unsure which client to use, check out the &lt;/SPAN&gt;&lt;A href="https://databricks-sdk-py.readthedocs.io/en/latest/clients.html" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;SDK documentation&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;. &lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;span class="lia-unicode-emoji" title=":light_bulb:"&gt;💡&lt;/span&gt;Because we ran the previous steps to authorize access&amp;nbsp;via unified client auth, the SDK will automatically use the necessary Databricks environment variables, so there's no need for extra configurations when setting up your client. All we need are these two lines of code:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;EM&gt;Initializing our WorkspaceClient&lt;/EM&gt;&lt;LI-CODE lang="python"&gt;from databricks.sdk import WorkspaceClient

w = WorkspaceClient()&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H2&gt;&lt;SPAN&gt;Making API calls and interacting with data&amp;nbsp;&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;The Workspace client we instantiated will allow us to interact with different APIs across the Databricks Workspace services. A &lt;/SPAN&gt;&lt;STRONG&gt;service&lt;/STRONG&gt;&lt;SPAN&gt; is a smaller component of the Databricks Platform i.e. Jobs, Compute, Model Registry. In our example, we’ll need to call the Jobs API in order to retrieve a list of all the jobs in the Workspace.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Services accessible via the Python SDK" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6065i797064EA27742E20/image-size/large?v=v2&amp;amp;px=999" role="button" title="image1.png" alt="Services accessible via the Python SDK" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Services accessible via the Python SDK&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;This is where Intellisense really comes in handy. Instead of context switching between the IDE and the Documentation page I can use autocomplete to provide a list of methods as well as examine the method description, the parameters, and return types from within the IDE. I know the first step is getting a list of all the jobs in the Workspace:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="image6.png" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6066i793334FB97CEC8B5/image-size/large?v=v2&amp;amp;px=999" role="button" title="image6.png" alt="image6.png" /&gt;&lt;/span&gt;&lt;BR /&gt;&lt;SPAN&gt;As you can see it returns an iterator over an object called BaseJob. Before we talk about what a BaseJob actually is it’ll be helpful to understand how data is used in the SDK. To interact with data you are sending to and receiving from the API, the Python SDK takes advantage of Python &lt;A href="https://docs.python.org/3/library/dataclasses.html" target="_self"&gt;&lt;STRONG&gt;Data Classes&lt;/STRONG&gt;&lt;/A&gt; and &lt;A href="https://docs.python.org/3/library/enum.html" target="_self"&gt;&lt;STRONG&gt;Enums&lt;/STRONG&gt;&lt;/A&gt;. The main advantage of this approach over passing around dictionaries is improved readability while also minimizing errors through enforced type checks and validations.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;You can construct objects with Data Classes and interact with enums. For example:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;I&gt;&lt;SPAN&gt;Creating an Employee via Employee DataClass and company departments, using Enums for possible department values&lt;/SPAN&gt;&lt;/I&gt;&lt;I&gt;&lt;/I&gt;&lt;LI-CODE lang="python"&gt;from dataclasses import dataclass
from enum import Enum
from typing import Optional

class CompanyDepartment(Enum):
    MARKETING = 'MARKETING'
    SALES = 'SALES'
    ENGINEERING = 'ENGINEERING'

@dataclass
class Employee:
    name: str
    email: str
    department: Optional[CompanyDepartment] = None


emp = Employee('Bob', 'bob@company.com', CompanyDepartment.ENGINEERING)&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;In the Python SDK all of the data classes, enums, and APIs belong to the same module for a service located under&lt;/SPAN&gt; &lt;STRONG&gt;databricks.sdk.service&lt;/STRONG&gt;&lt;SPAN&gt; - e.g. &lt;FONT face="courier new,courier"&gt;databricks.sdk.service.&lt;STRONG&gt;jobs&lt;/STRONG&gt;, databricks.sdk.service.&lt;STRONG&gt;billing&lt;/STRONG&gt;, databricks.sdk.service.&lt;STRONG&gt;sql&lt;/STRONG&gt;.&lt;BR /&gt;&lt;BR /&gt;&lt;/FONT&gt;&lt;/SPAN&gt;&lt;SPAN&gt;For our example, we'll need to loop through all of the jobs and make a decision on whether or not they should be paused. I'll be using a &lt;/SPAN&gt;&lt;A href="https://code.visualstudio.com/docs/editor/debugging" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;debugger&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; in order to look at a few example jobs and get a better understanding of what a ‘&lt;FONT face="courier new,courier"&gt;BaseJob&lt;/FONT&gt;’ looks like. The Databricks VS Code extension comes with a debugger that can be used to troubleshoot code issues interactively on Databricks via&lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/vscode-ext/dev-tasks/databricks-connect.html" target="_blank" rel="noopener"&gt; &lt;SPAN&gt;Databricks Connect&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;. But, because I do not need to run my code on a cluster I'll just be using the standard&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://code.visualstudio.com/docs/python/debugging" target="_blank" rel="noopener"&gt;Python debugger&lt;/A&gt;&lt;SPAN&gt;. I’ll set a breakpoint inside my for loop and use the VS Code Debugger to examine a few examples. A breakpoint allows us to stop code execution and interact with variables during our debugging session. This is preferable over print statements, as you can use the debugging console to interact with the data as well as progress the loop. In this example I’m looking at the &lt;/SPAN&gt;&lt;STRONG&gt;settings&lt;/STRONG&gt;&lt;SPAN&gt; field and drilling down further in the debugging console to take a look at what an example job schedule looks like:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Inspecting BaseJob in the VS Code debugger" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6067iCA37E83B73FB65AC/image-size/large?v=v2&amp;amp;px=999" role="button" title="image5.png" alt="Inspecting BaseJob in the VS Code debugger" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Inspecting BaseJob in the VS Code debugger&lt;/span&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;We can see a &lt;FONT face="courier new,courier"&gt;BaseJob&lt;/FONT&gt; has a few top-level attributes and has a more complex &lt;FONT face="courier new,courier"&gt;Settings&lt;/FONT&gt; type that contains most of the information we care about.&amp;nbsp;&lt;/SPAN&gt;&lt;SPAN&gt;At this point, we have our Workspace client and are iterating over the jobs in our Workspace. To flag problematic jobs and potentially take some action we’ll need to better understand &lt;/SPAN&gt;&lt;STRONG&gt;job.settings.schedule&lt;/STRONG&gt;&lt;SPAN&gt;. We need to figure out how to programmatically identify if a job has a schedule and flag if it’s not paused. For this we’ll be using another handy utility for code navigation - &lt;/SPAN&gt;&lt;A href="https://code.visualstudio.com/docs/editor/editingevolved#_go-to-definition" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Go to Definition&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;. I’ve opted to Open Definition to the Side (⌘K F12) in order to reduce switching to a new window. This will allow us to quickly navigate through the DataClass definitions without having to switch to a new window or exit our IDE:&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-align-center"&gt;&lt;IFRAME src="https://www.youtube.com/embed/C5UQviJg93c?si=R1eZEtJHWtjpnq7m" width="760" height="515" frameborder="0" allowfullscreen="" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"&gt;&lt;/IFRAME&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;As we can see, a &lt;FONT face="courier new,courier"&gt;BaseJob&lt;/FONT&gt; contains some top-level fields that are common amongst Jobs such as 'job_id' or 'created_time'. A job can also have various settings (&lt;FONT face="courier new,courier"&gt;JobSettings&lt;/FONT&gt;). These configurations often differ between Jobs and encompass aspects like notification settings, tasks, tags, and the schedule. We’ll be focusing on the schedule field, which is represented by the &lt;FONT face="courier new,courier"&gt;CronSchedule&lt;/FONT&gt; data class. &lt;FONT face="courier new,courier"&gt;CronSchedule&lt;/FONT&gt; contains information about the pause status (&lt;FONT face="courier new,courier"&gt;PauseStatus&lt;/FONT&gt;) of a job. &lt;FONT face="courier new,courier"&gt;PauseStatus&lt;/FONT&gt; in the SDK is represented as an enum with two possible values - &lt;STRONG&gt;PAUSED&lt;/STRONG&gt; and &lt;STRONG&gt;UNPAUSED&lt;/STRONG&gt;.&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P class="lia-indent-padding-left-30px"&gt;&lt;STRONG&gt;&lt;span class="lia-unicode-emoji" title=":light_bulb:"&gt;💡&lt;/span&gt;&lt;/STRONG&gt;&lt;STRONG&gt;Tip&lt;/STRONG&gt;&lt;SPAN&gt;: &lt;/SPAN&gt;&lt;SPAN&gt;VSCode + Pylance provides code suggestions and you can enable auto imports in your &lt;/SPAN&gt;&lt;A href="https://code.visualstudio.com/docs/getstarted/settings" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;User Settings or on a per-project basis in Workspace Settings&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;.&lt;/SPAN&gt; &lt;SPAN&gt;By default, only top-level symbols are suggested for auto import and suggested code (&lt;/SPAN&gt;&lt;A href="https://github.com/microsoft/pylance-release/issues/2533#issuecomment-1089268739" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;see original GitHub issue&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;). However, the SDK has nested elements we want to generate suggestions for. We actually need to go down 5 levels - databricks.sdk.service.jobs.&amp;lt;Enum|Dataclass&amp;gt;. In order to take full advantage of these features for the SDK I added a couple of Workspace settings:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;SPAN&gt;&lt;I&gt;Selection of theVSCode Workspace settings.json&lt;/I&gt;&lt;/SPAN&gt;&lt;LI-CODE lang="javascript"&gt;... 
  "python.analysis.autoImportCompletions": true,
  "python.analysis.indexing": true,
 "python.analysis.packageIndexDepths": [
{
            "name": "databricks",
            "depth": 5,
            "includeAllSymbols": true
        }
]
...
&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;H3&gt;Putting it all together:&lt;/H3&gt;
&lt;P&gt;&lt;SPAN&gt;I broke out the policy logic into its own function for unit testing, added some logging, and expanded the example to check for any jobs tagged as an exception to our policy. Now we have:&lt;/SPAN&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;&lt;I&gt;&lt;SPAN&gt;Logging out of policy jobs&lt;/SPAN&gt;&lt;/I&gt;&lt;I&gt;&lt;/I&gt;&lt;LI-CODE lang="python"&gt;import logging

from databricks.sdk import WorkspaceClient
from databricks.sdk.service.jobs import CronSchedule, JobSettings, PauseStatus

# Initialize WorkspaceClient
w = WorkspaceClient()


def update_new_settings(job_id, quarts_cron_expression, timezone_id):
    """Update out of policy job schedules to be paused"""
    new_schedule = CronSchedule(
        quartz_cron_expression=quarts_cron_expression,
        timezone_id=timezone_id,
        pause_status=PauseStatus.PAUSED,
    )
    new_settings = JobSettings(schedule=new_schedule)

    logging.info(f"Job id: {job_id}, new_settings: {new_settings}")
    w.jobs.update(job_id, new_settings=new_settings)


def out_of_policy(job_settings: JobSettings):
    """Check if a job is out of policy.
    If it unpaused and has a schedule and is not tagged as keep_alive
    Return true if out of policy, false if in policy
    """

    tagged = bool(job_settings.tags)
    proper_tags = tagged and "keep_alive" in job_settings.tags
    paused = job_settings.schedule.pause_status is PauseStatus.PAUSED

    return not paused and not proper_tags

all_jobs = w.jobs.list()
for job in all_jobs:
    job_id = job.job_id
    if job.settings.schedule and out_of_policy(job.settings):
        schedule = job.settings.schedule

        logging.info(
            f"Job name: {job.settings.name}, Job id: {job_id}, creator: {job.creator_user_name}, schedule: {schedule}"
        )
	....​&lt;/LI-CODE&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;P&gt;&lt;SPAN&gt;Now we have not only a working example but also a great foundation for building out a generalized job monitoring tool. We're successfully connecting to our Workspace, listing all the jobs, and analyzing their settings, and, when we're ready, we can simply call our `&lt;/SPAN&gt;&lt;FONT face="andale mono,times"&gt;update_new_settings function&lt;/FONT&gt;&lt;SPAN&gt;` to apply the new paused schedule. It's fairly straightforward to expand this to meet other requirements you may want to set for a Workspace - for example, swap job owners to service principles, add tags, edit notifications, or audit job permissions.&amp;nbsp;See the example in the&lt;A href="https://github.com/kimberlyma/dev-job-monitoring" target="_blank" rel="noopener"&gt; GitHub repository&lt;/A&gt;.&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Scheduling a job on Databricks&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;You can run your script anywhere, but you may want to schedule scripts that use the SDK to run as a Databricks Workflow or job on a small single-node cluster. When running a Python notebook interactively or via automated workflow you can take advantage of default Databricks Notebook authentication. If you're working with the Databricks Workspace client and your cluster meets the &lt;/SPAN&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/sdk-python.html#use-the-databricks-sdk-for-python-from-a-databricks-notebook" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;requirements listed in the docs&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt; you can initialize your WorkspaceClient without needing to specify any other configuration options or environment variables - it works automatically out of the box.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Using the Python SDK in a job" style="width: 999px;"&gt;&lt;img src="https://community.databricks.com/t5/image/serverpage/image-id/6069i883C72E5E7C7A1E5/image-size/large?v=v2&amp;amp;px=999" role="button" title="image4.png" alt="Using the Python SDK in a job" /&gt;&lt;span class="lia-inline-image-caption" onclick="event.preventDefault();"&gt;Using the Python SDK in a job&lt;/span&gt;&lt;/span&gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;H2&gt;&lt;SPAN&gt;Conclusion&lt;/SPAN&gt;&lt;/H2&gt;
&lt;P&gt;&lt;SPAN&gt;In conclusion, the Databricks SDKs offer limitless potential for a variety of applications. We saw how the Databricks SDK for Python can be used to automate a simple yet crucial maintenance task and also saw an example of an OSS project that uses the Python SDK to integrate with the Databricks Platform. Regardless of the application you want to build, the SDKs streamline development for the Databricks Platform and allow you to focus on your particular use case. The key to quickly mastering a new SDK such as the Databricks Python SDK is setting up a proper development environment. Developing in an IDE allows you to take advantage of features such as a debugger, parameter info, and code completion, so you can quickly navigate and familiarize yourself with the codebase. Visual Studio Code is a great choice for this as it provides the above capabilities and you can utilize the VSCode extension for Databricks to benefit from unified authentication.&lt;/SPAN&gt;&lt;/P&gt;
&lt;P&gt;&lt;SPAN&gt;Any feedback is greatly appreciated and welcome. Please raise any issues in the&lt;/SPAN&gt;&lt;A href="https://github.com/databricks/databricks-sdk-py" target="_blank" rel="noopener"&gt; &lt;SPAN&gt;Python SDK GitHub repository&lt;/SPAN&gt;&lt;/A&gt;&lt;SPAN&gt;.&amp;nbsp;&amp;nbsp;Happy developing! &lt;/SPAN&gt;&lt;/P&gt;
&lt;H3&gt;&lt;SPAN&gt;Additional resources:&lt;/SPAN&gt;&lt;/H3&gt;
&lt;UL&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://databricks-sdk-py.readthedocs.io/en/latest/" target="_self"&gt;&lt;SPAN&gt;Databricks SDK for Python Documentation&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;DAIS Presentation: &lt;/SPAN&gt;&lt;A href="https://www.youtube.com/watch?v=HWKJV_cRT9M" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Unlocking the Power of Databricks SDKs&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;SPAN&gt;How to install Python libraries in your local development environment:&amp;nbsp;&lt;/SPAN&gt;&lt;A href="https://www.youtube.com/watch?v=0f3moPe_bhk" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;How to Create and Use Virtual Environments in Python With Poetry&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;LI style="font-weight: 400;" aria-level="1"&gt;&lt;A href="https://docs.databricks.com/en/dev-tools/vscode-ext/install.html" target="_blank" rel="noopener"&gt;&lt;SPAN&gt;Installing the Databricks extension for Visual Studio Code&lt;/SPAN&gt;&lt;/A&gt;&lt;/LI&gt;
&lt;/UL&gt;</description>
    <pubDate>Thu, 01 Feb 2024 19:25:48 GMT</pubDate>
    <dc:creator>kimberlyma</dc:creator>
    <dc:date>2024-02-01T19:25:48Z</dc:date>
    <item>
      <title>From Idea to Code: Building with the Databricks SDK for Python</title>
      <link>https://community.databricks.com/t5/technical-blog/from-idea-to-code-building-with-the-databricks-sdk-for-python/ba-p/58894</link>
      <description>&lt;P&gt;&lt;SPAN&gt;This blog unpacks the components of the Databricks SDK for Python and gives helpful tips along the way in order to accelerate your development cycle. We'll walk through a simple, but powerful, real-world example of bulk-auditing and updating jobs in a Databricks workspace.&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Thu, 01 Feb 2024 19:25:48 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/from-idea-to-code-building-with-the-databricks-sdk-for-python/ba-p/58894</guid>
      <dc:creator>kimberlyma</dc:creator>
      <dc:date>2024-02-01T19:25:48Z</dc:date>
    </item>
    <item>
      <title>Re: From Idea to Code: Building with the Databricks SDK for Python</title>
      <link>https://community.databricks.com/t5/technical-blog/from-idea-to-code-building-with-the-databricks-sdk-for-python/bc-p/88827#M265</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;I’m looking to create a dependency between jobs. Specifically, I need to add a task in Job2 that checks the recent run status of Job1, as Job2 depends on Job1. Is there a function (similar to an external job sensor) or a specific method to achieve this?&lt;/P&gt;&lt;P&gt;Thanks in advance!&lt;/P&gt;</description>
      <pubDate>Fri, 06 Sep 2024 05:36:02 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/from-idea-to-code-building-with-the-databricks-sdk-for-python/bc-p/88827#M265</guid>
      <dc:creator>mohan_2724</dc:creator>
      <dc:date>2024-09-06T05:36:02Z</dc:date>
    </item>
    <item>
      <title>Re: From Idea to Code: Building with the Databricks SDK for Python</title>
      <link>https://community.databricks.com/t5/technical-blog/from-idea-to-code-building-with-the-databricks-sdk-for-python/bc-p/90808#M279</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/119518"&gt;@mohan_2724&lt;/a&gt;&amp;nbsp;. Have you already tried the Run Job task type? We do have a Workflows-native way to do this using a Python interface along with some other trigger types. Feel free to e-mail me &lt;A href="mailto:kimberly.mahoney@databricks.com" target="_blank"&gt;kimberly.mahoney@databricks.com&lt;/A&gt;&amp;nbsp;to discuss further and I can help loop in the correct folks.&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Wed, 18 Sep 2024 03:19:23 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/from-idea-to-code-building-with-the-databricks-sdk-for-python/bc-p/90808#M279</guid>
      <dc:creator>kimberlyma</dc:creator>
      <dc:date>2024-09-18T03:19:23Z</dc:date>
    </item>
    <item>
      <title>Re: From Idea to Code: Building with the Databricks SDK for Python</title>
      <link>https://community.databricks.com/t5/technical-blog/from-idea-to-code-building-with-the-databricks-sdk-for-python/bc-p/90814#M280</link>
      <description>&lt;P&gt;Hi &lt;a href="https://community.databricks.com/t5/user/viewprofilepage/user-id/28632"&gt;@kimberlyma&lt;/a&gt;&amp;nbsp;,&lt;/P&gt;&lt;P&gt;Thanks for your response.&lt;/P&gt;&lt;P&gt;We can't use Run Job Task Type, because those are not sequential and they scheduled for different timings. Please help me with any other approch.&lt;/P&gt;&lt;P&gt;Thanks &amp;amp; Regards,&lt;/P&gt;&lt;P&gt;&lt;SPAN&gt;Mohan&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;</description>
      <pubDate>Wed, 18 Sep 2024 03:58:59 GMT</pubDate>
      <guid>https://community.databricks.com/t5/technical-blog/from-idea-to-code-building-with-the-databricks-sdk-for-python/bc-p/90814#M280</guid>
      <dc:creator>mohan_2724</dc:creator>
      <dc:date>2024-09-18T03:58:59Z</dc:date>
    </item>
  </channel>
</rss>

