JSON-Daten hübsch machen – mit Python oder jq
Viele APIs liefern Daten im JSON-Format - als unüberschaubaren Einzeiler ...
Strukturierte Daten werden gerne als JSON ausgegeben, vor allem, wenn man APIs direkt per curl anspricht. In der Regel handelt es sich dabei um einen hässlichen Einzeiler, der nicht gut lesbar ist. Und sich auch nicht gut durchsuchen lässt, weil Suchwerkzeuge meist auf Zeilenbasis arbeiten. Also muss JSON aufgehübscht werden.
Ein simples Beispiel wäre die Abfrage der API der Monitoring-Lösung Checkmk, die per curl zum Beispiel alle überwachten Hosts ausgeben kann. Leider sieht die Rückgabe dann auszugsweise etwa so aus:
{"links": [{"domainType": "link", "rel": "self", "href": "http://localhost/mysite/check_mk/api/1.0/domain-types/host_config/collections/all", "method": "GET", "type": "application/json"}], "id": "host", "domainType": "host_config", "value": [{"links": [], "domainType": "host_config", "id": "CiscoSG250", "title": "CiscoSG250", "members": {}, "extensions": {"folder": "/", "attributes": {"ipaddress": "192.168.178.61", "snmp_community": {"type": "v1_v2_community", "community": "mycommunity"}, "meta_data": {"created_at": "2024-07-15T16:00:14+00:00", "updated_at": "2024-08-15T15:06:16.816484+00:00", "created_by": "cmkadmin"}, "tag_agent": "no-agent", "tag_snmp_ds": "snmp-v2"}, "effective_attributes": null, "is_cluster": false, "is_offline": false, "cluster_nodes": null}}, {"links": [], "domainType": "host_config", "id": "hueding", "title": "hueding", "members": {}, "extensions": {"folder": "/", "attributes": {"ipaddress": "hue001788b1cff5", "meta_data": {"created_at": "2024-01-17T22:56:48.253 ....
Nun gibt es zwei Standard-Optionen, dieses Chaos zu formatieren: Das explizit dafür gedachte Tool jq und das Python-Modul json.tool.
Meist dürfte jq die bessere Variante sein, allerdings ist jq im Gegensatz zu Python nicht standardmäßig auf fast allen Systemen vorhanden. Falls Ihr Euch also die Installation sparen wollt oder eh mit Python arbeitet:
python3 -m json.tool --json-lines <<< $(./myhosts.sh)
oder
./myhosts.sh | python3 -m json.tool --json-lines
Im Skript myhosts.sh steckt nur die curl-Abfrage für die Checkmk-API. Hier seht Ihr auch direkt einen der Nachteile gegenüber jq: Ohne die Format-Angabe --json-lines spuckt das Modul eine Fehlermeldung aus, mit der Angabe fehlt das Syntax-Highlighting. Das Ergebnis, auszugsweise:
{
"links": [
{
"domainType": "link",
"rel": "self",
"href": "http://localhost/mysite/check_mk/api/1.0/domain-types/host_config/collections/all",
"method": "GET",
"type": "application/json"
}
],
"id": "host",
"domainType": "host_config",
"value": [
{
"links": [],
"domainType": "host_config",
"id": "CiscoSG250",
"title": "CiscoSG250",
"members": {},
"extensions": {
"folder": "/",
"attributes": {
"ipaddress": "192.168.178.61",
...
Mit jq funktioniert es genauso:
jq <<< $(./myhosts.sh)
oder
./myhosts.sh | jq
Der Befehl ist definitiv besser zu merken, kümmert sich selbst um Format-Kleinkram und spendiert Euch hübsches Syntax-Highlighting. Zumindest im Terminal, hier sieht es wieder so aus:
{
"links": [
{
"domainType": "link",
"rel": "self",
"href": "http://localhost/mysite/check_mk/api/1.0/domain-types/host_config/collections/all",
"method": "GET",
"type": "application/json"
}
],
"id": "host",
"domainType": "host_config",
"value": [
{
"links": [],
"domainType": "host_config",
"id": "CiscoSG250",
"title": "CiscoSG250",
"members": {},
"extensions": {
"folder": "/",
"attributes": {
"ipaddress": "192.168.178.61",
...
Die Einrückungen sind anders, der Rest ist bei Python und jq identisch.
Das Schöne: Mit diesen Daten lässt sich dann auch auf der Kommandozeile einfach weiter arbeiten. Wenn Ihr zum Beispiel nur die Namen/Titel aller Hosts haben wollt:
jq <<< $(./myhosts.sh) | sed -n 's/.*title\": \"\([[:alnum:]]*\)\".*/\1/gp'
Und das ergibt eine schlichte Liste mit Host-Namen:
CiscoSG250
hueding
localhost
tauer
ubu22virt
weg1
weg2local
win11virt
justtestingnuller
Pretty-Print für JSON ist immer wieder mal eine nützliche Angelegenheit. Und wenn Ihr es nur selten benötigt, nutzt halt einen Online-Dienst wie JSON Pretty Print.
Ein praktisches Beispiel zur API- und JSON-Nutzung ist meine Desktop-App für Hue-Geräte.