Refactor Zasilkovna client, update imports and cleanup

Refactored the Zasilkovna SOAP client to use a singleton pattern with caching and lazy loading, improving reliability and startup performance. Updated invoice PDF generation to import WeasyPrint lazily, preventing startup failures on systems missing dependencies. Cleaned up unused imports and code in several frontend components, removed unused state and variables, and adjusted Docker frontend port mapping. Also updated Django migration files to reflect a new generation timestamp.
This commit is contained in:
2025-12-18 16:23:35 +01:00
parent 1751badb90
commit 72155d4560
21 changed files with 69 additions and 44 deletions

View File

@@ -1,28 +1,49 @@
from zeep import Client
from zeep.exceptions import Fault
from zeep.transports import Transport
from zeep.cache import SqliteCache
import tempfile
import base64
import logging
import os
from functools import lru_cache
logger = logging.getLogger(__name__)
WSDL_URL = os.getenv("PACKETA_WSDL_URL", "https://www.zasilkovna.cz/api/soap.wsdl")
PACKETA_API_PASSWORD = os.getenv("PACKETA_API_PASSWORD")
zeepZasClient = Client(wsdl=WSDL_URL)
# --- 1. Singleton pro klienta (aby se WSDL stáhlo jen jednou pro celý proces) ---
@lru_cache(maxsize=1)
def get_shared_client():
"""
Tato funkce vrátí instanci klienta a drží ji v tempfile na jednu hodinu.
"""
if not PACKETA_API_PASSWORD:
raise ValueError("Packeta API password is not set.")
tempFpath = os.path.join(tempfile.gettempdir(), 'zeep_packeta_cache.db')
transport = Transport(cache=SqliteCache(path=tempFpath, timeout=3600))
return Client(wsdl=WSDL_URL, transport=transport)
class PacketaAPI:
#TODO: zeptat se jestli nepřidat další checkovací parametry ohledně zásilkovny např: blokování podle configurace webu
# popřemýšlet, jestli api klíče nenastavit přes configurator webu
def __getattribute__(self):
if PACKETA_API_PASSWORD in [None, ""]:
raise Exception("Packeta API password is not set in environment variables.")
# --- 2. Property pro lazy loading ---
@property
def client(self):
"""
Při zavolání self.client se zavolá tento kód.
Vrátí již existujícího klienta z cache.
"""
return get_shared_client()
elif zeepZasClient is None:
raise Exception("Packeta SOAP client is not initialized.")
# ---------- CREATE PACKET METHODS ----------
@@ -68,7 +89,7 @@ class PacketaAPI:
try:
# Použijeme createPacketClaimWithPassword, protože umožňuje ukládat email a telefon
result = zeepZasClient.service.createPacketClaimWithPassword(PACKETA_API_PASSWORD, attributes)
result = self.client.service.createPacketClaimWithPassword(PACKETA_API_PASSWORD, attributes)
return result
except Fault as e:
@@ -83,7 +104,7 @@ class PacketaAPI:
packet_id = 1234567890
"""
try:
zeepZasClient.service.cancelPacket(PACKETA_API_PASSWORD, packet_id)
self.client.service.cancelPacket(PACKETA_API_PASSWORD, packet_id)
return {"status": "ok", "message": f"Zásilka {packet_id} byla zrušena."}
@@ -99,7 +120,7 @@ class PacketaAPI:
Vrací datum do kdy je uložená zásilka.
"""
try:
request = zeepZasClient.service.packetGetStoredUntil(PACKETA_API_PASSWORD, packet_id)
request = self.client.service.packetGetStoredUntil(PACKETA_API_PASSWORD, packet_id)
if request is None:
raise Exception(f"Zásilka {packet_id} nebyla ještě doručena.")
@@ -128,7 +149,7 @@ class PacketaAPI:
bytes: PDF soubor (base64 dekódovaný)
"""
try:
pdf_base64 = zeepZasClient.service.packetLabelPdf(
pdf_base64 = self.client.service.packetLabelPdf(
PACKETA_API_PASSWORD, packet_id, format, offset
)
@@ -163,7 +184,7 @@ class PacketaAPI:
packet_ids = ["1234567890", "1234567891", "1234567892"]
"""
try:
result = zeepZasClient.service.createShipment(PACKETA_API_PASSWORD, packet_ids)
result = self.client.service.createShipment(PACKETA_API_PASSWORD, packet_ids)
return result
@@ -176,7 +197,7 @@ class PacketaAPI:
Získá seznam balíků ve shipmentu podle jeho shipmentId.
"""
try:
result = zeepZasClient.service.shipmentPackets(PACKETA_API_PASSWORD, shipment_id)
result = self.client.service.shipmentPackets(PACKETA_API_PASSWORD, shipment_id)
return result
except Fault as e:
logger.error(f"Packeta shipmentPackets error: {e}")

View File

@@ -1,4 +1,4 @@
# Generated by Django 5.2.9 on 2025-12-14 02:23
# Generated by Django 5.2.7 on 2025-12-18 15:11
import django.core.validators
from django.db import migrations, models