Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ test-output.json

# Built by make for 'make fmt' and yamlcheck.py in acceptance tests
tools/yamlfmt
tools/golangci-lint
tools/yamlfmt.exe

# Cache for tools/gh_report.py
Expand Down
3 changes: 2 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,6 @@
"script": "shellscript",
"script.prepare": "shellscript",
"script.cleanup": "shellscript"
}
},
"cursorpyright.analysis.stubPath": ".vscode"
}
17 changes: 17 additions & 0 deletions acceptance/bundle/python/apps-support/databricks.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
bundle:
name: my_project

sync: {paths: []} # don't need to copy files

experimental:
python:
resources:
- "resources:load_resources"
mutators:
- "mutators:update_app"

resources:
apps:
my_app_1:
name: "My App"
description: "My first app"
11 changes: 11 additions & 0 deletions acceptance/bundle/python/apps-support/mutators.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from dataclasses import replace

from databricks.bundles.core import app_mutator
from databricks.bundles.apps import App


@app_mutator
def update_app(app: App) -> App:
assert isinstance(app.name, str)

return replace(app, name=f"{app.name} (updated)")
15 changes: 15 additions & 0 deletions acceptance/bundle/python/apps-support/resources.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from databricks.bundles.core import Resources


def load_resources() -> Resources:
resources = Resources()

resources.add_app(
"my_app_2",
{
"name": "My App (2)",
"description": "My second app",
},
)

return resources
6 changes: 6 additions & 0 deletions acceptance/bundle/python/apps-support/script
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
echo "$DATABRICKS_BUNDLES_WHEEL" > "requirements-latest.txt"

trace uv run $UV_ARGS -q $CLI bundle validate --output json | \
jq "pick(.experimental.python, .resources)"

rm -fr .databricks __pycache__
1 change: 1 addition & 0 deletions experimental/python/codegen/codegen/packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"resources.Pipeline": "pipelines",
"resources.Schema": "schemas",
"resources.Volume": "volumes",
"resources.App": "apps",
}

RESOURCE_TYPES = list(RESOURCE_NAMESPACE.keys())
Expand Down
81 changes: 81 additions & 0 deletions experimental/python/databricks/bundles/apps/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from databricks.bundles.apps._models.app import App, AppDict, AppParam
from databricks.bundles.apps._models.app_config import (
AppConfigDict,
AppConfigParam,
AppEnvVarDict,
)
from databricks.bundles.apps._models.app_permission import (
AppPermission,
AppPermissionDict,
AppPermissionLevel,
AppPermissionParam,
)
from databricks.bundles.apps._models.app_resource import (
AppResource,
AppResourceJob,
AppResourceJobDict,
AppResourceJobParam,
AppResourceParam,
AppResourceSecret,
AppResourceSecretDict,
AppResourceSecretParam,
AppResourceServingEndpoint,
AppResourceServingEndpointDict,
AppResourceServingEndpointParam,
AppResourceSqlWarehouse,
AppResourceSqlWarehouseDict,
AppResourceSqlWarehouseParam,
AppResourceUcSecurable,
AppResourceUcSecurableDict,
AppResourceUcSecurableParam,
JobPermission,
SecretPermission,
ServingEndpointPermission,
SqlWarehousePermission,
UcSecurablePermission,
UcSecurableType,
)
from databricks.bundles.apps._models.lifecycle import (
Lifecycle,
LifecycleDict,
LifecycleParam,
)

__all__ = [
"App",
"AppConfigDict",
"AppConfigParam",
"AppDict",
"AppEnvVarDict",
"AppParam",
"AppPermission",
"AppPermissionDict",
"AppPermissionLevel",
"AppPermissionParam",
"AppResource",
"AppResourceJob",
"AppResourceJobDict",
"AppResourceJobParam",
"AppResourceParam",
"AppResourceSecret",
"AppResourceSecretDict",
"AppResourceSecretParam",
"AppResourceServingEndpoint",
"AppResourceServingEndpointDict",
"AppResourceServingEndpointParam",
"AppResourceSqlWarehouse",
"AppResourceSqlWarehouseDict",
"AppResourceSqlWarehouseParam",
"AppResourceUcSecurable",
"AppResourceUcSecurableDict",
"AppResourceUcSecurableParam",
"JobPermission",
"Lifecycle",
"LifecycleDict",
"LifecycleParam",
"SecretPermission",
"ServingEndpointPermission",
"SqlWarehousePermission",
"UcSecurablePermission",
"UcSecurableType",
]
126 changes: 126 additions & 0 deletions experimental/python/databricks/bundles/apps/_models/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
from dataclasses import dataclass, field
from typing import TYPE_CHECKING, Any, TypedDict

from databricks.bundles.apps._models.app_permission import (
AppPermission,
AppPermissionParam,
)
from databricks.bundles.apps._models.app_resource import AppResource, AppResourceParam
from databricks.bundles.apps._models.lifecycle import Lifecycle, LifecycleParam
from databricks.bundles.core._resource import Resource
from databricks.bundles.core._transform import _transform
from databricks.bundles.core._transform_to_json import _transform_to_json_value
from databricks.bundles.core._variable import (
VariableOr,
VariableOrDict,
VariableOrList,
VariableOrOptional,
)

if TYPE_CHECKING:
from typing_extensions import Self


@dataclass(kw_only=True)
class App(Resource):
"""Databricks App resource"""

name: VariableOr[str]
"""
The name of the app. The name must be unique within the workspace.
"""

source_code_path: VariableOrOptional[str] = None
"""
Path to the app source code on local disk. This is used by DABs to deploy the app.
"""

description: VariableOrOptional[str] = None
"""
The description of the app.
"""

resources: VariableOrList[AppResource] = field(default_factory=list)
"""
A list of workspace resources associated with the app.
Each resource can be a job, secret, serving endpoint, SQL warehouse, or Unity Catalog securable.
"""

permissions: VariableOrList[AppPermission] = field(default_factory=list)
"""
Access control list for the app. Multiple permissions can be defined for different principals.
"""

lifecycle: VariableOrOptional[Lifecycle] = None
"""
Lifecycle is a struct that contains the lifecycle settings for a resource. It controls the behavior of the resource when it is deployed or destroyed.
"""

config: VariableOrDict[Any] = field(default_factory=dict)
"""
Application-specific configuration.

This can include various settings such as:
- command: List of strings for the command to run the app
- env: List of environment variable configurations with 'name', 'value', or 'valueFrom'
- Any other custom app-specific settings

See AppConfigDict for common configuration structure.
"""

@classmethod
def from_dict(cls, value: "AppDict") -> "Self":
return _transform(cls, value)

def as_dict(self) -> "AppDict":
return _transform_to_json_value(self) # type:ignore


class AppDict(TypedDict, total=False):
"""Databricks App resource"""

name: VariableOr[str]
"""
The name of the app. The name must be unique within the workspace.
"""

source_code_path: VariableOrOptional[str]
"""
Path to the app source code on local disk. This is used by DABs to deploy the app.
"""

description: VariableOrOptional[str]
"""
The description of the app.
"""

resources: VariableOrList[AppResourceParam]
"""
A list of workspace resources associated with the app.
Each resource can be a job, secret, serving endpoint, SQL warehouse, or Unity Catalog securable.
"""

permissions: VariableOrList[AppPermissionParam]
"""
Access control list for the app. Multiple permissions can be defined for different principals.
"""

lifecycle: VariableOrOptional[LifecycleParam]
"""
Lifecycle is a struct that contains the lifecycle settings for a resource. It controls the behavior of the resource when it is deployed or destroyed.
"""

config: VariableOrDict[Any]
"""
Application-specific configuration.

This can include various settings such as:
- command: List of strings for the command to run the app
- env: List of environment variable configurations with 'name', 'value', or 'valueFrom'
- Any other custom app-specific settings

See AppConfigDict for common configuration structure.
"""


AppParam = AppDict | App
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from typing import Any, Dict, List, TypedDict, Union

from databricks.bundles.core._variable import VariableOr, VariableOrOptional


class AppEnvVarDict(TypedDict, total=False):
"""Environment variable configuration for an app"""

name: VariableOr[str]
"""The name of the environment variable"""

value: VariableOrOptional[str]
"""
The value of the environment variable.
Either value or valueFrom must be specified, but not both.
"""

valueFrom: VariableOrOptional[str]
"""
Reference to another environment variable to get the value from.
Either value or valueFrom must be specified, but not both.
"""


class AppConfigDict(TypedDict, total=False):
"""
Configuration for a Databricks app.

This is a flexible dictionary structure that can contain various app-specific
configuration settings. Common configuration options include:

- command: List of strings for the command to run the app
- env: List of environment variable configurations
- Any other app-specific settings
"""

command: Union[List[str], VariableOr[str]]
"""
The command to run the app. This is typically a list of strings
representing the executable and its arguments.
Example: ["python", "app.py"] or ["streamlit", "run", "main.py"]
"""

env: List[AppEnvVarDict]
"""
Environment variables to set for the app.
Each variable can have a direct value or reference another environment variable.
Example: [{"name": "PORT", "value": "8080"}, {"name": "DB_URL", "valueFrom": "DATABASE_URL"}]
"""


# AppConfigParam is a flexible type that accepts various config formats
AppConfigParam = Union[AppConfigDict, Dict[str, Any]]
Loading
Loading