me like nix
0

Configure Feed

Select the types of activity you want to include in your feed.

Sync SABnzbd API key to Arr clients

author
Sean Aye
date (Jun 14, 2026, 10:18 PM -0400) commit 1520f0cb parent d88ddcd4 change-id ozkqvnyk
+66
+66
modules/media-server.nix
··· 50 50 after = [ "transmission-media-dirs.service" ]; 51 51 }; 52 52 53 + # Keep manually-created Sonarr/Radarr SABnzbd download clients in sync with 54 + # SABnzbd's generated API key. This avoids storing the SABnzbd API key in Nix 55 + # while repairing clients after the settings-backed SABnzbd config rewrite. 56 + systemd.services.sync-sabnzbd-download-client-keys = { 57 + description = "Sync SABnzbd API key into Arr download clients"; 58 + after = [ "sabnzbd.service" "sonarr.service" "radarr.service" ]; 59 + wants = [ "sabnzbd.service" "sonarr.service" "radarr.service" ]; 60 + wantedBy = [ "multi-user.target" ]; 61 + serviceConfig = { 62 + Type = "oneshot"; 63 + User = "root"; 64 + }; 65 + path = [ pkgs.python3 ]; 66 + script = '' 67 + python3 ${pkgs.writeText "sync-sabnzbd-download-client-keys.py" '' 68 + import json 69 + import urllib.error 70 + import urllib.request 71 + from pathlib import Path 72 + 73 + def read_key(path): 74 + for line in Path(path).read_text().splitlines(): 75 + if line.strip().startswith("api_key"): 76 + return line.split("=", 1)[1].strip() 77 + raise RuntimeError(f"api_key not found in {path}") 78 + 79 + sab_key = read_key("/var/lib/sabnzbd/sabnzbd.ini") 80 + 81 + services = [ 82 + ("Sonarr", "http://127.0.0.1:8989", "/data/.state/nixarr/secrets/sonarr.api-key"), 83 + ("Radarr", "http://127.0.0.1:7878", "/data/.state/nixarr/secrets/radarr.api-key"), 84 + ] 85 + 86 + def request(base, api_key, method, path, data=None): 87 + body = None if data is None else json.dumps(data).encode() 88 + req = urllib.request.Request( 89 + base + path, 90 + data=body, 91 + method=method, 92 + headers={"X-Api-Key": api_key, "Content-Type": "application/json"}, 93 + ) 94 + with urllib.request.urlopen(req, timeout=10) as resp: 95 + raw = resp.read() 96 + return None if not raw else json.loads(raw) 97 + 98 + for name, base, key_file in services: 99 + try: 100 + api_key = Path(key_file).read_text().strip() 101 + clients = request(base, api_key, "GET", "/api/v3/downloadclient") 102 + changed = 0 103 + for client in clients: 104 + if (client.get("implementation") or "").lower() != "sabnzbd" and (client.get("name") or "").lower() != "sabnzbd": 105 + continue 106 + for field in client.get("fields", []): 107 + if field.get("name") == "apiKey" and field.get("value") != sab_key: 108 + field["value"] = sab_key 109 + changed += 1 110 + request(base, api_key, "PUT", f"/api/v3/downloadclient/{client['id']}", client) 111 + print(f"{name}: updated {changed} SABnzbd apiKey field(s)") 112 + except Exception as e: 113 + print(f"{name}: failed to sync SABnzbd API key: {e}") 114 + raise 115 + ''} 116 + ''; 117 + }; 118 + 53 119 # nixarr configures SABnzbd through services.sabnzbd.settings on newer nixpkgs, 54 120 # but NixOS keeps the legacy configFile default when system.stateVersion < 26.05, 55 121 # causing those settings to be ignored. Force the new settings-backed path.