proxy-fix

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
2026-05-06 11:43:44 +02:00
co-authored by Copilot
parent a829716810
commit 28cfc75121
3 changed files with 89 additions and 57 deletions
+66 -54
View File
@@ -146,6 +146,9 @@ def _wfs_get_gml(url: str, typename: str, extra_params: dict) -> Optional[bytes]
GET-Requests mit ``BBOX=``-KVP-Parameter oder ResourceId-``FILTER`` (nur
``xmlns:fes``, kein GML) werden dagegen akzeptiert.
**Proxy-Unterstützung:** Verwendet ``QgsBlockingNetworkRequest``, das automatisch
die in QGIS konfigurierten Proxy-Einstellungen berücksichtigt.
Parameters
----------
url :
@@ -161,10 +164,10 @@ def _wfs_get_gml(url: str, typename: str, extra_params: dict) -> Optional[bytes]
bytes | None
Rohe GML-Antwort oder ``None`` bei Fehler.
"""
import urllib.request
import urllib.parse
import urllib.error
from qgis.core import QgsMessageLog, Qgis
from qgis.core import QgsMessageLog, Qgis, QgsBlockingNetworkRequest
from qgis.PyQt.QtNetwork import QNetworkRequest
from qgis.PyQt.QtCore import QUrl
params = {
'SERVICE': 'WFS',
@@ -177,26 +180,34 @@ def _wfs_get_gml(url: str, typename: str, extra_params: dict) -> Optional[bytes]
full_url = url + '?' + urllib.parse.urlencode(params)
try:
with urllib.request.urlopen(full_url, timeout=120) as resp:
gml_bytes = resp.read()
except urllib.error.HTTPError as exc:
body_preview = exc.read(200).decode('utf-8', errors='replace')
req = QNetworkRequest(QUrl(full_url))
req.setTransferTimeout(120_000)
blocker = QgsBlockingNetworkRequest()
err = blocker.get(req)
if err != QgsBlockingNetworkRequest.ErrorCode.NoError:
msg = blocker.errorMessage()
QgsMessageLog.logMessage(
f"WFS GET HTTP {exc.code} ({typename}): {exc.reason}\n"
f"WFS GET fehlgeschlagen ({typename}): {msg}\nURL: {full_url[:300]}",
"sn_verfahrensgebiet",
Qgis.MessageLevel.Critical,
)
warning("WFS GET", f"Netzwerk-/Proxy-Fehler: {msg}", duration=10)
return None
reply = blocker.reply()
http_status = reply.attribute(QNetworkRequest.Attribute.HttpStatusCodeAttribute)
gml_bytes = bytes(reply.content())
if http_status is not None and http_status >= 400:
body_preview = gml_bytes[:200].decode('utf-8', errors='replace')
QgsMessageLog.logMessage(
f"WFS GET HTTP {http_status} ({typename})\n"
f"URL: {full_url[:300]}\nAntwort: {body_preview}",
"sn_verfahrensgebiet",
Qgis.MessageLevel.Critical,
)
warning("WFS GET", f"HTTP {exc.code}: {exc.reason}", duration=10)
return None
except Exception as exc:
QgsMessageLog.logMessage(
f"WFS GET fehlgeschlagen ({typename}): {exc}\nURL: {full_url[:300]}",
"sn_verfahrensgebiet",
Qgis.MessageLevel.Critical,
)
warning("WFS GET", f"Netzwerkfehler: {exc}", duration=10)
warning("WFS GET", f"HTTP {http_status}", duration=10)
return None
if not gml_bytes:
@@ -477,11 +488,7 @@ def _lade_grenzpunkte_als_dict(
)
_gml_bytes = _wfs_get_gml(ALKIS_SF_URL, GRENZPUNKT_TYPENAME, {'FILTER': filter_xml})
if not _gml_bytes:
warning(
"Grenzpunkte (Diagnose)",
f"Batch {i + 1}/{anzahl_batches}: GET-Anfrage fehlgeschlagen – Batch wird übersprungen.",
duration=4,
)
return {}, []
else:
tmp = _parse_alkis_gml_memory_layer(_gml_bytes, "AX_Grenzpunkt", "_TmpGP", geom_prop=None)
if not tmp:
@@ -704,9 +711,12 @@ def _lade_gemarkung_extents_mit_puffer(
return extents
def _wfs_hits_count(url: str, typename: str, extra_params: dict) -> int:
def _wfs_hits_count(url: str, typename: str, extra_params: dict) -> Optional[int]:
"""Fragt die Anzahl der Features per ``resultType=hits`` ab.
**Proxy-Unterstützung:** Verwendet ``QgsBlockingNetworkRequest``, das automatisch
die in QGIS konfigurierten Proxy-Einstellungen berücksichtigt.
Parameters
----------
url :
@@ -714,17 +724,21 @@ def _wfs_hits_count(url: str, typename: str, extra_params: dict) -> int:
typename :
Vollqualifizierter Feature-Typ.
extra_params :
Zus\u00e4tzliche KVP-Parameter (z.B. ``{'BBOX': '...'}``).
Zusätzliche KVP-Parameter (z.B. ``{'BBOX': '...'}``).
Returns
-------
int
Anzahl der Features oder ``-1`` wenn nicht ermittelbar.
Optional[int]
Anzahl der Features,
``-1`` wenn der Server antwortete aber ``numberMatched='unknown'`` lieferte
(gültiger WFS-Fallback, kein Fehler), oder
``None`` bei Netzwerk-/Proxy-Fehler (Aufrufer soll abbrechen).
"""
import urllib.request
import urllib.parse
import urllib.error
import xml.etree.ElementTree as ET
from qgis.core import QgsMessageLog, Qgis, QgsBlockingNetworkRequest
from qgis.PyQt.QtNetwork import QNetworkRequest
from qgis.PyQt.QtCore import QUrl
params = {
'SERVICE': 'WFS',
@@ -736,11 +750,22 @@ def _wfs_hits_count(url: str, typename: str, extra_params: dict) -> int:
params.update(extra_params)
full_url = url + '?' + urllib.parse.urlencode(params)
try:
with urllib.request.urlopen(full_url, timeout=30) as resp:
gml_bytes = resp.read()
except Exception:
return -1
req = QNetworkRequest(QUrl(full_url))
req.setTransferTimeout(30_000)
blocker = QgsBlockingNetworkRequest()
err = blocker.get(req)
if err != QgsBlockingNetworkRequest.ErrorCode.NoError:
msg = blocker.errorMessage()
QgsMessageLog.logMessage(
f"WFS Hits-Abfrage fehlgeschlagen ({typename}): {msg}\nURL: {full_url[:300]}",
"sn_verfahrensgebiet",
Qgis.MessageLevel.Critical,
)
return None
gml_bytes = bytes(blocker.reply().content())
try:
root = ET.fromstring(gml_bytes)
@@ -796,12 +821,7 @@ def _lade_punktort_ta_batches_per_gemarkung(
)
_gml_bytes = _wfs_get_gml(ALKIS_SF_URL, PUNKTORT_TA_TYPENAME, {'BBOX': _punktort_ta_bbox_param(bbox)})
if not _gml_bytes:
warning(
"Grenzpunkte (Diagnose)",
f"Gemarkung {_gemarkungsnummer}: GET-Anfrage fehlgeschlagen – wird übersprungen.",
duration=4,
)
continue
return None
tmp = _parse_alkis_gml_memory_layer(_gml_bytes, "AX_PunktortTA", "_TmpPTA", geom_prop="position", extract_qualitaet=True)
if not tmp:
warning(
@@ -997,6 +1017,8 @@ def lade_punktort_ta(
bbox_param = _punktort_ta_bbox_param(bbox)
n_hits = _wfs_hits_count(ALKIS_SF_URL, PUNKTORT_TA_TYPENAME, {'BBOX': bbox_param})
if n_hits is None:
return None
n_batches = max(1, math.ceil(n_hits / _BBOX_BATCH)) if n_hits > 0 else 1
info(
@@ -1022,13 +1044,7 @@ def lade_punktort_ta(
_gml_bytes = _wfs_get_gml(ALKIS_SF_URL, PUNKTORT_TA_TYPENAME, extra)
if not _gml_bytes:
warning(
"Grenzpunkte (Diagnose)",
f"Gemarkung {gemarkungsnummer} Batch {b_idx + 1}: "
f"GET-Anfrage fehlgeschlagen – übersprungen.",
duration=4,
)
continue
return None
tmp = _parse_alkis_gml_memory_layer(
_gml_bytes, "AX_PunktortTA", "_TmpPTA", geom_prop="position", extract_qualitaet=True
@@ -1343,6 +1359,8 @@ def grenzpunkte_gemarkungsweise(
for gemarkungsnummer, bbox in extents.items():
bbox_param = _punktort_ta_bbox_param(bbox)
n_hits = _wfs_hits_count(ALKIS_SF_URL, PUNKTORT_TA_TYPENAME, {'BBOX': bbox_param})
if n_hits is None:
return None
hits_pro_gemarkung[gemarkungsnummer] = n_hits
batches = max(1, math.ceil(n_hits / _BBOX_BATCH)) if n_hits > 0 else 1
n_pta_batches_gesamt += batches
@@ -1413,13 +1431,7 @@ def grenzpunkte_gemarkungsweise(
_gml_bytes = _wfs_get_gml(ALKIS_SF_URL, PUNKTORT_TA_TYPENAME, extra)
if not _gml_bytes:
warning(
"Grenzpunkte (Diagnose)",
f"Gemarkung {gemarkungsnummer} Batch {b_idx + 1}: "
f"GET-Anfrage fehlgeschlagen – Batch wird übersprungen.",
duration=6,
)
continue
return None
tmp = _parse_alkis_gml_memory_layer(
_gml_bytes, "AX_PunktortTA", "_TmpPTA", geom_prop="position", extract_qualitaet=True