nixpkgs mirror (for testing)
github.com/NixOS/nixpkgs
nix
1{
2 lib,
3 buildPythonPackage,
4 fetchFromGitHub,
5 pythonOlder,
6 stdenvNoCC,
7 replaceVars,
8 buildNpmPackage,
9 python,
10 home-assistant-chip-wheels,
11
12 # build
13 setuptools,
14
15 # dependencies
16 aiohttp,
17 aiorun,
18 atomicwrites,
19 coloredlogs,
20 orjson,
21 home-assistant-chip-clusters,
22
23 # optionals
24 cryptography,
25 home-assistant-chip-core,
26 zeroconf,
27
28 # tests
29 aioresponses,
30 pytest,
31 pytest-aiohttp,
32 pytest-cov-stub,
33 pytestCheckHook,
34
35 # build options
36 withDashboard ? true,
37}:
38
39let
40 version = "8.1.2";
41
42 src = fetchFromGitHub {
43 owner = "home-assistant-libs";
44 repo = "python-matter-server";
45 tag = version;
46 hash = "sha256-vnI57h/aesnaDYorq1PzcMCLmV0z0ZBJvMg4Nzh1Dtc=";
47 };
48
49 paaCerts = stdenvNoCC.mkDerivation {
50 pname = "matter-server-paa-certificates";
51 inherit (home-assistant-chip-wheels) version src;
52
53 dontConfigure = true;
54 dontBuild = true;
55
56 installPhase = ''
57 runHook preInstall
58
59 mkdir -p $out
60 cp connectedhomeip/credentials/development/paa-root-certs/* $out/
61
62 runHook postInstall
63 '';
64 };
65
66 # Maintainer note: building the dashboard requires a python environment with a
67 # built version of python-matter-server. To support bundling the dashboard
68 # with the python-matter-server, the build is parameterized to build without
69 # a dependency on the dashboard, breaking a cyclical dependency. First,
70 # python-matter-server is built without the dashboard, then the dashboard is
71 # built, then python-matter-server is built again with the dashboard.
72 matterServerDashboard =
73 let
74 pythonWithChip = python.withPackages (ps: [
75 ps.home-assistant-chip-clusters
76 (ps.python-matter-server.override { withDashboard = false; })
77 ]);
78 in
79 buildNpmPackage {
80 pname = "python-matter-server-dashboard";
81 inherit src version;
82
83 npmDepsHash = "sha256-IgI1H3VlTq66duplVQqL67SpgxPF2MOowDn+ICMXCik=";
84
85 prePatch = ''
86 ${pythonWithChip.interpreter} scripts/generate_descriptions.py
87
88 # cd before the patch phase sets up the npm install hook to find the
89 # package.json. The script would need to be patched in order to be used
90 # with sourceRoot.
91 cd "dashboard"
92 '';
93
94 # This package does not contain a normal `npm build` step.
95 buildPhase = ''
96 env NODE_ENV=production npm exec -- tsc
97 env NODE_ENV=production npm exec -- rollup -c
98 '';
99
100 installPhase = ''
101 runHook preInstall
102
103 install -Dt "$out/" public/*
104 # Copy recursive directory structure, which install does not do.
105 cp -r dist/web/* "$out/"
106
107 runHook postInstall
108 '';
109 };
110in
111buildPythonPackage rec {
112 pname = if withDashboard then "python-matter-server" else "python-matter-server-without-dashboard";
113 inherit
114 src
115 version
116 ;
117
118 pyproject = true;
119
120 disabled = pythonOlder "3.12";
121
122 patches = [
123 (replaceVars ./link-paa-root-certs.patch {
124 paacerts = paaCerts;
125 })
126 ];
127
128 postPatch = ''
129 substituteInPlace pyproject.toml \
130 --replace-fail 'version = "0.0.0"' 'version = "${version}"'
131 ''
132 + lib.optionalString withDashboard ''
133 substituteInPlace "matter_server/server/server.py" \
134 --replace-fail 'Path(__file__).parent.joinpath("../dashboard/")' 'Path("${matterServerDashboard}")'
135 '';
136
137 build-system = [
138 setuptools
139 ];
140
141 pythonRelaxDeps = [ "home-assistant-chip-clusters" ];
142
143 dependencies = [
144 aiohttp
145 aiorun
146 atomicwrites
147 coloredlogs
148 orjson
149 home-assistant-chip-clusters
150 ];
151
152 optional-dependencies = {
153 server = [
154 cryptography
155 home-assistant-chip-core
156 zeroconf
157 ];
158 };
159
160 nativeCheckInputs = [
161 aioresponses
162 pytest-aiohttp
163 pytest-cov-stub
164 pytestCheckHook
165 ]
166 ++ lib.concatAttrValues optional-dependencies;
167
168 preCheck =
169 let
170 pythonEnv = python.withPackages (_: dependencies ++ nativeCheckInputs ++ [ pytest ]);
171 in
172 ''
173 export PYTHONPATH=${pythonEnv}/${python.sitePackages}
174 '';
175
176 disabledTestPaths = [
177 # requires internet access
178 "tests/server/ota/test_dcl.py"
179 ];
180
181 meta = {
182 changelog = "https://github.com/home-assistant-libs/python-matter-server/releases/tag/${src.tag}";
183 description = "Python server to interact with Matter";
184 mainProgram = "matter-server";
185 homepage = "https://github.com/home-assistant-libs/python-matter-server";
186 license = lib.licenses.asl20;
187 teams = [ lib.teams.home-assistant ];
188 };
189}