Tento skript ukazuje robustní dávkový odesílač dokumentů ISDOC: ověří se pomocí API přihlašovacích údajů, odešle každý soubor ze vstupní složky, zjišťuje stav doručení a úspěšně odeslané soubory přesune do archivní složky.
Co tato ukázka předvádí
send_isdoc_batch.py
Naformátovaný a zvýrazněný zdrojový kód Pythonu
#!/usr/bin/env python3
import json
import os
import shutil
import sys
import urllib.error
import urllib.request
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Optional
API_BASE_URL = os.getenv("PEPPOS_BASE_URL", "https://sandbox.pepposh.eu")
CLIENT_ID = os.getenv("PEPPOS_CLIENT_ID", "YOUR-API-KEY")
CLIENT_SECRET = os.getenv("PEPPOS_CLIENT_SECRET", "YOUR-API-SECRET")
INPUT_DIR = Path(os.getenv("ISDOC_INPUT_DIR", "isdoc"))
SENT_DIR = Path(os.getenv("ISDOC_SENT_DIR", "isdoc_sent"))
@dataclass
class SendResult:
filename: str
sent: bool
moved_to: Optional[str]
document_id: Optional[str]
final_status: Optional[str]
queue_status: Optional[str]
message: str
def http_json(
method: str,
url: str,
headers: Optional[dict[str, str]] = None,
payload: Optional[str] = None,
) -> tuple[int, Any]:
req_headers = {"Accept": "application/json"}
if headers:
req_headers.update(headers)
data: Optional[bytes] = None
if payload is not None:
if isinstance(payload, str):
data = payload.encode("utf-8")
req_headers["Content-Type"] = "application/xml"
else:
data = json.dumps(payload).encode("utf-8")
req_headers["Content-Type"] = "application/json"
req = urllib.request.Request(url, data=data, method=method, headers=req_headers)
try:
with urllib.request.urlopen(req, timeout=30) as resp:
raw = resp.read().decode("utf-8", errors="replace")
return resp.getcode(), (json.loads(raw) if raw else {})
except urllib.error.HTTPError as e:
body = e.read().decode("utf-8", errors="replace")
try:
parsed = json.loads(body) if body else {}
except json.JSONDecodeError:
parsed = {"raw": body}
return e.code, parsed
def get_token() -> str:
if not CLIENT_ID or not CLIENT_SECRET:
raise RuntimeError("Missing PEPPOS_CLIENT_ID or PEPPOS_CLIENT_SECRET environment variable.")
status, body = http_json(
"POST",
f"{API_BASE_URL}/api/auth/token",
payload={
"client_id": CLIENT_ID,
"client_secret": CLIENT_SECRET,
"grant_type": "client_credentials",
},
)
if status != 200 or "access_token" not in body:
raise RuntimeError(f"Token request failed ({status}): {json.dumps(body, ensure_ascii=False)}")
return body["access_token"]
def send_isdoc_document(token: str, isdoc_path: Path) -> tuple[Optional[str], dict[str, Any]]:
content = isdoc_path.read_text(encoding="utf-8")
status, body = http_json(
"POST",
f"{API_BASE_URL}/api/documents/send/as/isdoc?wait-for-result",
headers={
"Authorization": f"Bearer {token}",
},
payload=content,
)
if status not in (200, 201, 202):
return None, {"http_status": status, "response": body}
document_id = body.get("data", {}).get("documentId") if isinstance(body, dict) else None
return document_id, {"http_status": status, "response": body}
def main() -> int:
if not INPUT_DIR.exists():
print(f"Input directory not found: {INPUT_DIR}")
return 1
SENT_DIR.mkdir(parents=True, exist_ok=True)
try:
token = get_token()
except Exception as e:
print(f"Token error: {e}")
return 1
files = sorted(p for p in INPUT_DIR.glob("*.isdoc") if p.is_file())
if not files:
print(f"No .isdoc files found in {INPUT_DIR}")
return 0
results: list[SendResult] = []
for path in files:
try:
document_id, send_meta = send_isdoc_document(token, path)
if not document_id:
results.append(
SendResult(
filename=path.name,
sent=False,
moved_to=None,
document_id=None,
final_status=None,
queue_status=None,
message=f"Send failed: {json.dumps(send_meta, ensure_ascii=False)}",
)
)
continue
status_body = send_meta.get("response") if isinstance(send_meta, dict) else {}
final_status = status_body.get("status") if isinstance(status_body, dict) else None
queue_status = None
message_status = None
if isinstance(status_body, dict):
queue_status = (status_body.get("sendQueueStatus") or {}).get("status")
message_status = status_body.get("messageStatus")
is_sent = queue_status in {"sent", "delivered"} or message_status in {"sent", "delivered"}
if is_sent:
target = SENT_DIR / path.name
shutil.move(str(path), str(target))
results.append(
SendResult(
filename=path.name,
sent=True,
moved_to=str(target),
document_id=document_id,
final_status=final_status,
queue_status=queue_status,
message="Sent and moved.",
)
)
else:
results.append(
SendResult(
filename=path.name,
sent=False,
moved_to=None,
document_id=document_id,
final_status=final_status,
queue_status=queue_status,
message=f"Not sent or delivery failed: {json.dumps(status_body, ensure_ascii=False)}",
)
)
except Exception as e:
results.append(
SendResult(
filename=path.name,
sent=False,
moved_to=None,
document_id=None,
final_status=None,
queue_status=None,
message=f"Error: {e}",
)
)
print("\n=== Batch result ===")
for r in results:
print(
json.dumps(
{
"file": r.filename,
"sent": r.sent,
"moved_to": r.moved_to,
"document_id": r.document_id,
"final_status": r.final_status,
"queue_status": r.queue_status,
"message": r.message,
},
ensure_ascii=False,
)
)
sent_count = sum(1 for r in results if r.sent)
print(f"\nSent successfully: {sent_count}/{len(results)}")
return 0 if sent_count == len(results) else 2
if __name__ == "__main__":
sys.exit(main())