Skip to content

Commit f603547

Browse files
committed
add apps impl
1 parent 2837583 commit f603547

File tree

20 files changed

+714
-1
lines changed

20 files changed

+714
-1
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,6 @@
2222
"script": "shellscript",
2323
"script.prepare": "shellscript",
2424
"script.cleanup": "shellscript"
25-
}
25+
},
26+
"cursorpyright.analysis.stubPath": ".vscode"
2627
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
bundle:
2+
name: my_project
3+
4+
sync: {paths: []} # don't need to copy files
5+
6+
experimental:
7+
python:
8+
resources:
9+
- "resources:load_resources"
10+
mutators:
11+
- "mutators:update_app"
12+
13+
resources:
14+
apps:
15+
my_app_1:
16+
name: "My App"
17+
description: "My first app"
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from dataclasses import replace
2+
3+
from databricks.bundles.core import app_mutator
4+
from databricks.bundles.apps import App
5+
6+
7+
@app_mutator
8+
def update_app(app: App) -> App:
9+
assert isinstance(app.name, str)
10+
11+
return replace(app, name=f"{app.name} (updated)")
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
from databricks.bundles.core import Resources
2+
3+
4+
def load_resources() -> Resources:
5+
resources = Resources()
6+
7+
resources.add_app(
8+
"my_app_2",
9+
{
10+
"name": "My App (2)",
11+
"description": "My second app",
12+
},
13+
)
14+
15+
return resources
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
echo "$DATABRICKS_BUNDLES_WHEEL" > "requirements-latest.txt"
2+
3+
trace uv run $UV_ARGS -q $CLI bundle validate --output json | \
4+
jq "pick(.experimental.python, .resources)"
5+
6+
rm -fr .databricks __pycache__

experimental/python/codegen/codegen/packages.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
"resources.Pipeline": "pipelines",
88
"resources.Schema": "schemas",
99
"resources.Volume": "volumes",
10+
"resources.App": "apps",
1011
}
1112

1213
RESOURCE_TYPES = list(RESOURCE_NAMESPACE.keys())
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
from databricks.bundles.apps._models.app import App, AppDict, AppParam
2+
from databricks.bundles.apps._models.app_config import (
3+
AppConfigDict,
4+
AppConfigParam,
5+
AppEnvVarDict,
6+
)
7+
from databricks.bundles.apps._models.app_permission import (
8+
AppPermission,
9+
AppPermissionDict,
10+
AppPermissionLevel,
11+
AppPermissionParam,
12+
)
13+
from databricks.bundles.apps._models.app_resource import (
14+
AppResource,
15+
AppResourceJob,
16+
AppResourceJobDict,
17+
AppResourceJobParam,
18+
AppResourceParam,
19+
AppResourceSecret,
20+
AppResourceSecretDict,
21+
AppResourceSecretParam,
22+
AppResourceServingEndpoint,
23+
AppResourceServingEndpointDict,
24+
AppResourceServingEndpointParam,
25+
AppResourceSqlWarehouse,
26+
AppResourceSqlWarehouseDict,
27+
AppResourceSqlWarehouseParam,
28+
AppResourceUcSecurable,
29+
AppResourceUcSecurableDict,
30+
AppResourceUcSecurableParam,
31+
JobPermission,
32+
SecretPermission,
33+
ServingEndpointPermission,
34+
SqlWarehousePermission,
35+
UcSecurablePermission,
36+
UcSecurableType,
37+
)
38+
from databricks.bundles.apps._models.lifecycle import (
39+
Lifecycle,
40+
LifecycleDict,
41+
LifecycleParam,
42+
)
43+
44+
__all__ = [
45+
"App",
46+
"AppConfigDict",
47+
"AppConfigParam",
48+
"AppDict",
49+
"AppEnvVarDict",
50+
"AppParam",
51+
"AppPermission",
52+
"AppPermissionDict",
53+
"AppPermissionLevel",
54+
"AppPermissionParam",
55+
"AppResource",
56+
"AppResourceJob",
57+
"AppResourceJobDict",
58+
"AppResourceJobParam",
59+
"AppResourceParam",
60+
"AppResourceSecret",
61+
"AppResourceSecretDict",
62+
"AppResourceSecretParam",
63+
"AppResourceServingEndpoint",
64+
"AppResourceServingEndpointDict",
65+
"AppResourceServingEndpointParam",
66+
"AppResourceSqlWarehouse",
67+
"AppResourceSqlWarehouseDict",
68+
"AppResourceSqlWarehouseParam",
69+
"AppResourceUcSecurable",
70+
"AppResourceUcSecurableDict",
71+
"AppResourceUcSecurableParam",
72+
"JobPermission",
73+
"Lifecycle",
74+
"LifecycleDict",
75+
"LifecycleParam",
76+
"SecretPermission",
77+
"ServingEndpointPermission",
78+
"SqlWarehousePermission",
79+
"UcSecurablePermission",
80+
"UcSecurableType",
81+
]
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
from dataclasses import dataclass, field
2+
from typing import TYPE_CHECKING, Any, TypedDict
3+
4+
from databricks.bundles.apps._models.app_permission import (
5+
AppPermission,
6+
AppPermissionParam,
7+
)
8+
from databricks.bundles.apps._models.app_resource import AppResource, AppResourceParam
9+
from databricks.bundles.apps._models.lifecycle import Lifecycle, LifecycleParam
10+
from databricks.bundles.core._resource import Resource
11+
from databricks.bundles.core._transform import _transform
12+
from databricks.bundles.core._transform_to_json import _transform_to_json_value
13+
from databricks.bundles.core._variable import (
14+
VariableOr,
15+
VariableOrDict,
16+
VariableOrList,
17+
VariableOrOptional,
18+
)
19+
20+
if TYPE_CHECKING:
21+
from typing_extensions import Self
22+
23+
24+
@dataclass(kw_only=True)
25+
class App(Resource):
26+
"""Databricks App resource"""
27+
28+
name: VariableOr[str]
29+
"""
30+
The name of the app. The name must be unique within the workspace.
31+
"""
32+
33+
source_code_path: VariableOrOptional[str] = None
34+
"""
35+
Path to the app source code on local disk. This is used by DABs to deploy the app.
36+
"""
37+
38+
description: VariableOrOptional[str] = None
39+
"""
40+
The description of the app.
41+
"""
42+
43+
resources: VariableOrList[AppResource] = field(default_factory=list)
44+
"""
45+
A list of workspace resources associated with the app.
46+
Each resource can be a job, secret, serving endpoint, SQL warehouse, or Unity Catalog securable.
47+
"""
48+
49+
permissions: VariableOrList[AppPermission] = field(default_factory=list)
50+
"""
51+
Access control list for the app. Multiple permissions can be defined for different principals.
52+
"""
53+
54+
lifecycle: VariableOrOptional[Lifecycle] = None
55+
"""
56+
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.
57+
"""
58+
59+
config: VariableOrDict[Any] = field(default_factory=dict)
60+
"""
61+
Application-specific configuration.
62+
63+
This can include various settings such as:
64+
- command: List of strings for the command to run the app
65+
- env: List of environment variable configurations with 'name', 'value', or 'valueFrom'
66+
- Any other custom app-specific settings
67+
68+
See AppConfigDict for common configuration structure.
69+
"""
70+
71+
@classmethod
72+
def from_dict(cls, value: "AppDict") -> "Self":
73+
return _transform(cls, value)
74+
75+
def as_dict(self) -> "AppDict":
76+
return _transform_to_json_value(self) # type:ignore
77+
78+
79+
class AppDict(TypedDict, total=False):
80+
"""Databricks App resource"""
81+
82+
name: VariableOr[str]
83+
"""
84+
The name of the app. The name must be unique within the workspace.
85+
"""
86+
87+
source_code_path: VariableOrOptional[str]
88+
"""
89+
Path to the app source code on local disk. This is used by DABs to deploy the app.
90+
"""
91+
92+
description: VariableOrOptional[str]
93+
"""
94+
The description of the app.
95+
"""
96+
97+
resources: VariableOrList[AppResourceParam]
98+
"""
99+
A list of workspace resources associated with the app.
100+
Each resource can be a job, secret, serving endpoint, SQL warehouse, or Unity Catalog securable.
101+
"""
102+
103+
permissions: VariableOrList[AppPermissionParam]
104+
"""
105+
Access control list for the app. Multiple permissions can be defined for different principals.
106+
"""
107+
108+
lifecycle: VariableOrOptional[LifecycleParam]
109+
"""
110+
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.
111+
"""
112+
113+
config: VariableOrDict[Any]
114+
"""
115+
Application-specific configuration.
116+
117+
This can include various settings such as:
118+
- command: List of strings for the command to run the app
119+
- env: List of environment variable configurations with 'name', 'value', or 'valueFrom'
120+
- Any other custom app-specific settings
121+
122+
See AppConfigDict for common configuration structure.
123+
"""
124+
125+
126+
AppParam = AppDict | App
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from typing import Any, Dict, List, TypedDict, Union
2+
3+
from databricks.bundles.core._variable import VariableOr, VariableOrOptional
4+
5+
6+
class AppEnvVarDict(TypedDict, total=False):
7+
"""Environment variable configuration for an app"""
8+
9+
name: VariableOr[str]
10+
"""The name of the environment variable"""
11+
12+
value: VariableOrOptional[str]
13+
"""
14+
The value of the environment variable.
15+
Either value or valueFrom must be specified, but not both.
16+
"""
17+
18+
valueFrom: VariableOrOptional[str]
19+
"""
20+
Reference to another environment variable to get the value from.
21+
Either value or valueFrom must be specified, but not both.
22+
"""
23+
24+
25+
class AppConfigDict(TypedDict, total=False):
26+
"""
27+
Configuration for a Databricks app.
28+
29+
This is a flexible dictionary structure that can contain various app-specific
30+
configuration settings. Common configuration options include:
31+
32+
- command: List of strings for the command to run the app
33+
- env: List of environment variable configurations
34+
- Any other app-specific settings
35+
"""
36+
37+
command: Union[List[str], VariableOr[str]]
38+
"""
39+
The command to run the app. This is typically a list of strings
40+
representing the executable and its arguments.
41+
Example: ["python", "app.py"] or ["streamlit", "run", "main.py"]
42+
"""
43+
44+
env: List[AppEnvVarDict]
45+
"""
46+
Environment variables to set for the app.
47+
Each variable can have a direct value or reference another environment variable.
48+
Example: [{"name": "PORT", "value": "8080"}, {"name": "DB_URL", "valueFrom": "DATABASE_URL"}]
49+
"""
50+
51+
52+
# AppConfigParam is a flexible type that accepts various config formats
53+
AppConfigParam = Union[AppConfigDict, Dict[str, Any]]
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from dataclasses import dataclass
2+
from enum import Enum
3+
from typing import TypedDict
4+
5+
from databricks.bundles.core._transform import _transform
6+
from databricks.bundles.core._transform_to_json import _transform_to_json_value
7+
from databricks.bundles.core._variable import VariableOr, VariableOrOptional
8+
9+
10+
class AppPermissionLevel(str, Enum):
11+
"""Permission level for an app"""
12+
13+
CAN_MANAGE = "CAN_MANAGE"
14+
CAN_USE = "CAN_USE"
15+
16+
17+
AppPermissionLevelParam = AppPermissionLevel | str
18+
19+
20+
@dataclass(kw_only=True)
21+
class AppPermission:
22+
"""AppPermission holds the permission level setting for a single principal."""
23+
24+
level: VariableOr[AppPermissionLevel]
25+
"""Permission level"""
26+
27+
user_name: VariableOrOptional[str] = None
28+
"""User name to grant permission to"""
29+
30+
service_principal_name: VariableOrOptional[str] = None
31+
"""Service principal name to grant permission to"""
32+
33+
group_name: VariableOrOptional[str] = None
34+
"""Group name to grant permission to"""
35+
36+
@classmethod
37+
def from_dict(cls, value: "AppPermissionDict") -> "AppPermission":
38+
return _transform(cls, value)
39+
40+
def as_dict(self) -> "AppPermissionDict":
41+
return _transform_to_json_value(self) # type:ignore
42+
43+
44+
class AppPermissionDict(TypedDict, total=False):
45+
"""AppPermission holds the permission level setting for a single principal."""
46+
47+
level: VariableOr[AppPermissionLevelParam]
48+
"""Permission level"""
49+
50+
user_name: VariableOrOptional[str]
51+
"""User name to grant permission to"""
52+
53+
service_principal_name: VariableOrOptional[str]
54+
"""Service principal name to grant permission to"""
55+
56+
group_name: VariableOrOptional[str]
57+
"""Group name to grant permission to"""
58+
59+
60+
AppPermissionParam = AppPermissionDict | AppPermission

0 commit comments

Comments
 (0)