1{
2 lib,
3 stdenv,
4 python3,
5 fetchFromGitHub,
6
7 # tests
8 addBinToPathHook,
9 gitMinimal,
10 versionCheckHook,
11 writableTmpDirAsHomeHook,
12}:
13let
14 python = python3.override {
15 self = python;
16 packageOverrides = self: super: {
17 pydantic = super.pydantic_1;
18
19 # python-on-whales is the only aiohttp dependency that is incompatible with pydantic_1
20 # Override aiohttp to remove this dependency
21 aiohttp = super.aiohttp.overridePythonAttrs (old: {
22 # Remove python-on-whales from nativeCheckInputs
23 nativeCheckInputs = lib.filter (p: (p.pname or "") != "python-on-whales") old.nativeCheckInputs;
24
25 disabledTestPaths = [
26 # Requires python-on-whales
27 "tests/autobahn/test_autobahn.py"
28 ]
29 ++ (old.disabledTestPaths or [ ]);
30 });
31
32 databricks-sdk = super.databricks-sdk.overridePythonAttrs (old: {
33 # Tests require langchain-openai which is incompatible with pydantic_1
34 doCheck = false;
35 });
36 };
37 };
38in
39python.pkgs.buildPythonApplication rec {
40 pname = "dbx";
41 version = "0.8.19";
42 pyproject = true;
43
44 src = fetchFromGitHub {
45 owner = "databrickslabs";
46 repo = "dbx";
47 tag = "v${version}";
48 hash = "sha256-DNVJcCDHyWCorTxNN6RR6TWNF2MrysXT44UbwegROTU=";
49 };
50
51 postPatch = ''
52 # Probably a typo
53 substituteInPlace src/dbx/custom.py \
54 --replace-fail "_make_rich_rext" "_make_rich_text"
55
56 # dbx pins an old version of typer.
57 # In newer versions of typer, `callback` does not accept the 'name' argument anymore.
58 substituteInPlace src/dbx/cli.py \
59 --replace-fail 'name="dbx",' ""
60
61 # Fixes: TypeError: 'NoneType' object is not iterable
62 substituteInPlace src/dbx/utils/common.py \
63 --replace-fail \
64 '[t.split("=") for t in multiple_argument]' \
65 '[t.split("=") for t in multiple_argument] if multiple_argument else []'
66 '';
67
68 pythonRelaxDeps = [
69 "cryptography"
70 "databricks-cli"
71 "pydantic"
72 "rich"
73 "tenacity"
74 "typer"
75 ];
76
77 pythonRemoveDeps = [ "mlflow-skinny" ];
78
79 build-system = with python.pkgs; [
80 hatch-vcs
81 hatchling
82 ];
83
84 dependencies = with python.pkgs; [
85 aiohttp
86 click
87 cookiecutter
88 cryptography
89 databricks-cli
90 jinja2
91 mlflow
92 pathspec
93 pydantic
94 pyyaml
95 requests
96 retry
97 rich
98 setuptools
99 tenacity
100 typer
101 watchdog
102 ];
103
104 optional-dependencies = with python.pkgs; {
105 aws = [ boto3 ];
106 azure = [
107 azure-storage-blob
108 azure-identity
109 ];
110 gcp = [ google-cloud-storage ];
111 };
112
113 nativeCheckInputs = [
114 addBinToPathHook
115 gitMinimal
116 versionCheckHook
117 writableTmpDirAsHomeHook
118 ]
119 ++ (with python.pkgs; [
120 pytest-asyncio
121 pytest-mock
122 pytest-timeout
123 pytest-xdist
124 pytestCheckHook
125 ]);
126 versionCheckProgramArg = "--version";
127
128 disabledTests = [
129 # Fails because of dbfs CLI wrong call
130 "test_dbfs_unknown_user"
131 "test_dbfs_no_root"
132 # Requires pylint, prospector, pydocstyle
133 "test_python_basic_sanity_check"
134 ];
135
136 disabledTestPaths = lib.optionals stdenv.hostPlatform.isDarwin [
137 # ERROR fsevents:fsevents.py:310 Unhandled exception in FSEventsEmitter
138 # SystemError: Cannot start fsevents stream. Use a kqueue or polling observer instead.
139 "tests/unit/sync/test_event_handler.py"
140 ];
141
142 pythonImportsCheck = [ "dbx" ];
143
144 meta = {
145 description = "CLI tool for advanced Databricks jobs management";
146 homepage = "https://github.com/databrickslabs/dbx";
147 changelog = "https://github.com/databrickslabs/dbx/blob/v${version}/CHANGELOG.md";
148 license = lib.licenses.databricks-dbx;
149 maintainers = with lib.maintainers; [ GuillaumeDesforges ];
150 };
151}