From fad93e194f6be3dde237c89d88359ae5715658b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dieter=20Schl=C3=BCter?= Date: Thu, 25 Jun 2026 12:51:11 +0200 Subject: [PATCH] fix: seven.io-Statuscode als nacktes int/float robust parsen (0.1.1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Der SMS-Endpunkt liefert standardmäßig nur den nackten Statuscode (z. B. 100), der als JSON zu einem int decodiert — _parse rief darauf data.get() auf und crashte mit AttributeError. Jetzt wird ein Nicht-Objekt-JSON als Statuscode behandelt (ok = code == "100"). - client.py: _parse behandelt dict / int-Code / Text einheitlich - Tests: nackter int-Code 100 (ok) und 900 (Fehler) Co-Authored-By: Claude Opus 4.8 --- pyproject.toml | 2 +- src/seven_send/__init__.py | 2 +- src/seven_send/client.py | 17 ++++++++++++++--- tests/test_client.py | 15 +++++++++++++++ 4 files changed, 31 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index a2f623c..d134fad 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "seven-send" -version = "0.1.0" +version = "0.1.1" description = "Kleine Library + CLI zum Verschicken von SMS und TTS-Sprachanrufen über seven.io" readme = "README.md" requires-python = ">=3.10" diff --git a/src/seven_send/__init__.py b/src/seven_send/__init__.py index 52683b1..8728c3c 100644 --- a/src/seven_send/__init__.py +++ b/src/seven_send/__init__.py @@ -3,4 +3,4 @@ from seven_send.client import Result, SevenClient, SevenError __all__ = ["SevenClient", "Result", "SevenError"] -__version__ = "0.1.0" +__version__ = "0.1.1" diff --git a/src/seven_send/client.py b/src/seven_send/client.py index ff96762..79675a6 100644 --- a/src/seven_send/client.py +++ b/src/seven_send/client.py @@ -107,9 +107,20 @@ class SevenClient: ) try: data = resp.json() - except Exception: # Legacy: nackter Statuscode als Text - first = body.splitlines()[0] if body else "" - return Result(ok=(first == "100"), channel=channel, to=to, code=first or None, raw=body) + except Exception: + data = None + + # seven.io liefert je nach Endpunkt/Format entweder ein JSON-Objekt ODER nur + # den nackten Statuscode (z. B. "100") — der decodiert als JSON zu int/float. + # Beides hier robust behandeln. + if not isinstance(data, dict): + code = str(data).strip() if data is not None else (body.splitlines()[0] if body else "") + code = code or None + return Result( + ok=(code == "100"), channel=channel, to=to, code=code, raw=body, + error=None if code == "100" else f"seven status={code}", + ) + code = str(data.get("success", "")).strip() or None msgs = data.get("messages") or [] ok = code in (None, "100") and all(m.get("success", True) for m in msgs) diff --git a/tests/test_client.py b/tests/test_client.py index 5291777..cee4f10 100644 --- a/tests/test_client.py +++ b/tests/test_client.py @@ -61,6 +61,21 @@ def test_failure_code(monkeypatch): assert not r.ok and r.code == "401" +def test_sms_bare_int_code_ok(monkeypatch): + # SMS-Endpunkt liefert oft nur den nackten Code -> resp.json() == int 100 + cap = [] + _patch_post(monkeypatch, cap, FakeResp(payload=100, text="100")) + r = SevenClient("key").send_sms("+49", "x") + assert r.ok and r.code == "100" + + +def test_sms_bare_int_code_error(monkeypatch): + cap = [] + _patch_post(monkeypatch, cap, FakeResp(payload=900, text="900")) + r = SevenClient("key").send_sms("+49", "x") + assert not r.ok and r.code == "900" and "900" in r.error + + def test_http_error(monkeypatch): cap = [] _patch_post(monkeypatch, cap, FakeResp(status_code=500, text="boom"))