pipeloom-databricks 0.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,18 @@
1
+ """Databricks renderer for pipeloom: a compiled plan as Jobs settings JSON and bundle YAML.
2
+
3
+ Rendering is pure. Nothing here imports `databricks.sdk`; only the modules that talk to a
4
+ workspace will, and they load it lazily.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+
10
+ def pipeloom_databricks_task() -> None:
11
+ """The entry point of a rendered task, found by `package_name` and `entry_point`.
12
+
13
+ A function of the package covers a Databricks lookup that does not read entry points. The
14
+ task module loads only when a task runs.
15
+ """
16
+ from pipeloom_databricks.task import main
17
+
18
+ main()
@@ -0,0 +1,45 @@
1
+ """The stable surface other pipeloom distributions (such as an Airflow renderer) may call.
2
+
3
+ Importing it loads no SDK: `connect` imports `databricks.sdk` only when it runs.
4
+ """
5
+
6
+ from __future__ import annotations
7
+
8
+ from pipeloom_databricks.client import (
9
+ ApiError,
10
+ ConnectionNotConfigured,
11
+ DatabricksClient,
12
+ JobSummary,
13
+ RunInfo,
14
+ TaskRunInfo,
15
+ connect,
16
+ )
17
+ from pipeloom_databricks.deploy import DeployResult, DuplicateJobs, deploy, find_job
18
+ from pipeloom_databricks.finalize_states import task_states
19
+ from pipeloom_databricks.grouping import task_key_map
20
+ from pipeloom_databricks.render import deploy_options, render_job
21
+ from pipeloom_databricks.repair import repair
22
+ from pipeloom_databricks.run import RunStarted, SelectionError, find_run, run_job
23
+
24
+ __all__ = [
25
+ "ApiError",
26
+ "ConnectionNotConfigured",
27
+ "DatabricksClient",
28
+ "DeployResult",
29
+ "DuplicateJobs",
30
+ "JobSummary",
31
+ "RunInfo",
32
+ "RunStarted",
33
+ "SelectionError",
34
+ "TaskRunInfo",
35
+ "connect",
36
+ "deploy",
37
+ "deploy_options",
38
+ "find_job",
39
+ "find_run",
40
+ "render_job",
41
+ "repair",
42
+ "run_job",
43
+ "task_key_map",
44
+ "task_states",
45
+ ]
@@ -0,0 +1,113 @@
1
+ """The files of a Declarative Automation Bundle: one job file and one stable manifest per pipeline.
2
+
3
+ Pure: it returns bytes and never writes. `${workspace.file_path}` is the bundle variable that
4
+ resolves to the synced files at deploy time, so the job finds the project and the manifest
5
+ wherever the bundle lands.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from collections.abc import Sequence
11
+ from dataclasses import dataclass
12
+ from pathlib import Path
13
+ from typing import Final
14
+
15
+ from pipeloom.diagnostics import Report
16
+ from pipeloom.plan.manifest import manifest_bytes
17
+ from pipeloom.plan.model import Plan
18
+ from pipeloom_databricks.jobs_model import to_json
19
+ from pipeloom_databricks.render import (
20
+ Locations,
21
+ _own_version,
22
+ deploy_options,
23
+ job_name,
24
+ render_job,
25
+ )
26
+ from pipeloom_databricks.serialize import to_bundle_yaml
27
+
28
+ BUNDLE_FILE: Final = "databricks.yml"
29
+ WORKSPACE_FILES: Final = "${workspace.file_path}"
30
+
31
+
32
+ @dataclass(frozen=True)
33
+ class BundleFile:
34
+ path: Path
35
+ """Where the file goes: `<out>/<name>`."""
36
+ content: bytes
37
+
38
+
39
+ @dataclass(frozen=True)
40
+ class Runtime:
41
+ """What the target says that the job needs to know."""
42
+
43
+ artifacts_root: str | None
44
+ state_shared: bool
45
+ cancel_grace: int = 30
46
+
47
+
48
+ def find_bundle_root(out: Path, explicit: Path | None) -> Path | None:
49
+ """`explicit`, else the nearest ancestor of `out` (itself included) that holds databricks.yml."""
50
+ if explicit is not None:
51
+ return explicit.resolve()
52
+ here = out.resolve()
53
+ for folder in (here, *here.parents):
54
+ if (folder / BUNDLE_FILE).is_file():
55
+ return folder
56
+ return None
57
+
58
+
59
+ def relative_to_root(path: Path, root: Path) -> str | None:
60
+ """`path` below `root` as POSIX text (empty for the root itself), or None when outside."""
61
+ try:
62
+ rel = path.resolve().relative_to(root).as_posix()
63
+ except ValueError:
64
+ return None
65
+ return "" if rel == "." else rel
66
+
67
+
68
+ def _workspace(rel: str) -> str:
69
+ return f"{WORKSPACE_FILES}/{rel}" if rel else WORKSPACE_FILES
70
+
71
+
72
+ def render_bundle(
73
+ plan: Plan,
74
+ runtime: Runtime,
75
+ pipelines: Sequence[str],
76
+ *,
77
+ out: Path,
78
+ project_rel: str,
79
+ out_rel: str,
80
+ report: Report,
81
+ ) -> list[BundleFile] | None:
82
+ """The files of the given pipelines (all of them when empty), or None with the problems in
83
+ `report`. `project_rel` and `out_rel` are the project folder and the output folder relative
84
+ to the bundle root."""
85
+ opts = deploy_options(plan, report)
86
+ if opts is None:
87
+ return None
88
+ manifest = manifest_bytes(plan, stable=True)
89
+ files: list[BundleFile] = []
90
+ before = report.error_count
91
+ for pipeline in pipelines or sorted(opts.pipelines):
92
+ name = job_name(plan, pipeline)
93
+ locs = Locations(
94
+ project_root=_workspace(project_rel),
95
+ manifest_path=_workspace(f"{out_rel}/{name}.manifest.json".lstrip("/")),
96
+ artifacts_root=runtime.artifacts_root,
97
+ state_shared=runtime.state_shared,
98
+ cancel_grace=runtime.cancel_grace,
99
+ )
100
+ job = render_job(plan, pipeline, locs, report)
101
+ if job is None:
102
+ continue
103
+ header = (
104
+ f"Generated by pipeloom-databricks {_own_version(plan)}.\n"
105
+ f"Project: {plan.metadata.project}. Pipeline: {pipeline}. "
106
+ f"Target: {plan.metadata.target}.\n"
107
+ "Do not edit: run `pipeloom databricks bundle` again."
108
+ )
109
+ files.append(
110
+ BundleFile(out / f"{name}.job.yml", to_bundle_yaml(name, to_json(job.settings), header))
111
+ )
112
+ files.append(BundleFile(out / f"{name}.manifest.json", manifest))
113
+ return None if report.error_count > before else files