Skip to main content

fega-schmitt-client

Tests Release License: MIT Renovate uv Ruff

Status: v1 implementiert (SOAP-Preis-/Verfügbarkeitsservice) + erste IDS-Erweiterung (Warenkorb senden/empfangen), noch nicht auf PyPI veröffentlicht. UGL4 sowie IDS-Artikeldeeplink/-suche/Heatinglabel sind bewusst noch nicht umgesetzt, siehe Architektur. Der SOAP-Preis-/Verfügbarkeitsservice ist sowohl gegen die Spezifikation/einen Mock-Server (automatisierte Tests) als auch live gegen den echten FEGA & Schmitt-Server verifiziert (siehe "Offene Punkte" für Details zum manuellen Testaufruf).

Eine reine Python-Library für den Zugriff auf die B2B-Schnittstellen von FEGA & Schmitt Elektrogroßhandel — allen voran den Preis-/Verfügbarkeitsservice. Kein MCP-, kein KI-spezifischer Code: diese Library ist eigenständig nutzbar (Skripte, andere Services, Warenwirtschaftssysteme) und wird zusätzlich vom Schwester-Projekt fega-schmitt-mcp (separates Repository unter GIT/MCP/) als MCP-Interface verpackt.

Suchst du das MCP-Interface für KI-Assistenten? Siehe das Repository fega-schmitt-mcp — der dünne MCP-Wrapper um diese Library.

Über FEGA & Schmitt

FEGA & Schmitt ist ein deutscher Elektrogroßhändler. Kunden erhalten Zugriff auf mehrere, technisch sehr unterschiedliche B2B-Schnittstellen zum Datenaustausch mit ihrer Warenwirtschaft/Handwerkersoftware. Details siehe docs/architecture.md.

Schnittstellen im Überblick

Schnittstelle Typ Zweck Eignung für Library v1
SOAP Preis-/Verfügbarkeitsservice Synchrones SOAP/XML über HTTPS Preis & Verfügbarkeit für bis zu 1000 Artikel je Anfrage ✅ Basis für v1 — einzige echte Request/Response-API
IDS-Schnittstelle (BVBS/ITEK-Branchenstandard, v2.5) Browser-Redirect + Hook-URL, halbautomatisch Warenkorb-Austausch, Artikelsuche, Artikel-Deeplinks, Heizungslabel (ErP) ⚠️ Später — passt nicht zu einer reinen Funktionsaufruf-API, siehe Architektur
UGL Version 4 (SHK-Branchenstandard) Datei-basiert (FTP/Portal), ASCII Fixed-Length Anfragen, Abrufaufträge, Auftragsbestätigungen als Batch-Dateien ⚠️ Später — Batch/Polling statt Live-Antwort

Die vollständigen Original-Spezifikationen liegen als PDF in docs/specs/:

  • Schnittstellenbeschreibung_SOAP.pdf — Preis-/Verfügbarkeits-Webservice (FEGA & Schmitt, Stand März 2016)
  • IDS_Schnittstelle_2_5_final_NEU.pdf — IDS-Schnittstelle für Warenkorb/Artikelsuche/Heizlabel (BVBS/ITEK, Version 2.5, Stand 02.11.2020)
  • ugl4neutral.pdf — UGL Version 4, Datenaustausch Handwerk ↔ SHK-Großhandel (GC-Gruppe, Stand 16.06.2006)

Öffentliche API (v1)

from fega_schmitt_client import FegaSchmittClient, PriceAvailRequestItem

client = FegaSchmittClient(
    partner_purchaser="9920",       # Kundennummer bei FEGA & Schmitt
    legitimation_id="...",          # Shop-Kennwort
)

results = client.get_price_availability([
    PriceAvailRequestItem(material_number="0815", quantity=200, unit="MTR"),
    PriceAvailRequestItem(material_number="4711", quantity=1),
])

for r in results:
    print(r.material_number, r.availability_status, r.net_amount)

Details zu Datenmodell, Fehlerbehandlung und Architektur: siehe docs/architecture.md.

IDS-Erweiterung: Warenkorb senden/empfangen

fega_schmitt_client.ids implementiert den "Warenkorb senden"-Teil der IDS-Schnittstelle (BVBS/ITEK v2.5, halbautomatisch — Browserfenster + manuelle Nutzerinteraktion im FEGA-Shop, siehe docs/specs/IDS_Schnittstelle_2_5_final_NEU.pdf, Abschnitt 5.2). Die Library baut nur die Daten — kein Browser-Handling, kein Webhook-Server; das übernimmt der Aufrufer (z. B. fega-schmitt-mcp):

from decimal import Decimal
from fega_schmitt_client.ids import Cart, CartItem, build_cart_request, parse_cart_callback

cart = Cart(items=[
    CartItem(article_number="0815", quantity=Decimal(200), unit="MTR"),
])

request = build_cart_request(
    cart,
    shop_url="https://shop.fega.de/...",   # noch nicht bekannt, siehe "Offene Punkte"
    customer_number="9920",
    hook_url="https://mein-server.example/fega-hook",  # optional
)
# request.fields als multipart/form-data-POST an request.shop_url schicken
# (bzw. als auto-submitting HTML-Formular im Browser des Nutzers öffnen)

# Später, wenn der Shop das Ergebnis an die hook_url zurückschickt:
updated_cart = parse_cart_callback(received_xml)

Ohne hook_url funktioniert das Senden weiterhin — der Nutzer schließt den Vorgang dann manuell im Browser ab, es gibt nur keinen automatischen Rücklauf.

CLI

Als Kommandozeilen-Tool fega installierbar, ohne dass ein eigenes venv angelegt werden muss:

uv tool install fega-schmitt-client
fega --customer-number 9920 --shop-password "..." price-avail 0815:200:MTR 4711

Alternativ per Umgebungsvariablen (FEGA_CUSTOMER_NUMBER, FEGA_SHOP_PASSWORD) statt Optionen. -j/--json liefert JSON statt Tabellenausgabe. fega --help bzw. fega price-avail --help zeigen alle Optionen.

Installation

pip install fega-schmitt-client
# oder
uv add fega-schmitt-client

(Noch nicht auf PyPI veröffentlicht — bis dahin lokal installierbar via uv pip install . bzw. uv tool install . aus dem geklonten Repo.)

Entwicklung

uv sync --all-groups        # Dependencies + Dev-Tools installieren
uv run pytest                # Tests (gegen einen respx-Mock-Server, kein echter FEGA-Zugang nötig)
uv run pre-commit install    # Linting/Formatting-Hooks aktivieren
uv run pre-commit run --all-files

Offene Punkte

  • Test-/Produktivzugangsdaten für den SOAP-Serviceerledigt: get_price_availability wurde live gegen https://soap.fega.de/priceavail.php verifiziert (echte Kundennummer/Shop-Kennwort, Artikel 121350 → I720, korrekte Preis-, Verfügbarkeits- und Kupferzuschlag-Daten). Zugangsdaten liegen als Secret in OpenBao, nicht im Repo.
  • Wie FEGA & Schmitt eine komplett abgelehnte Anmeldung tatsächlich signalisiert (HTTP-Status, Fault oder ein bestimmter Returncode), bleibt weiterhin offen — der Live-Test lief mit gültigen Zugangsdaten, absichtlich falsche wurden nicht getestet. Beobachtet wurde allerdings: eine unbekannte Artikelnummer liefert E999/Fehler 216 mit dem missverständlichen Text "Bitte pruefen Sie Ihre Anmeldedaten" (HTTP 200) — nicht mit einem Auth-spezifischen HTTP-Status. FegaAuthError (aktuell nur bei HTTP 401/403) ist also weiterhin eine ungetestete Annahme, könnte in der Praxis aber nie greifen, wenn FEGA Ablehnungen generell per Item-Returncode statt HTTP-Status meldet
  • Die tatsächliche IDS-Shop-URL von FEGA & Schmitt (shop_url in build_cart_request) sowie die referenzierten XSD-Schemas (Warenkorb_senden.xsd, Warenkorb_empfangen_2-5.xsd — in der vorliegenden PDF nicht enthalten, nur die tabellarische Feldbeschreibung); die Implementierung von fega_schmitt_client.ids ist entsprechend nur gegen die Spezifikation getestet, nicht gegen den echten Shop
  • Das exakte Formularfeld, unter dem der Shop den Warenkorb an die Hook-URL zurückschickt — die Spec dokumentiert nur den Feldnamen warenkorb für die ausgehende Richtung, für den Rücklauf wird das per Analogieschluss angenommen
  • Artikeldeeplink, Artikelsuche, Login-Informationen, Schnittstellenversion und Heatinglabel (restliche IDS-Aktionen) sind noch nicht umgesetzt
  • DATANORM v5 + Offline-Zugang (FTP): bei FEGA & Schmitt beantragt, aber Zugangsdaten und Format-Spezifikation liegen noch nicht vor — siehe docs/architecture.md. DATANORM ist die von der SOAP-Spec selbst referenzierte Quelle der Artikelnummern für get_price_availability, daher relevanter als "nur" ein weiteres Zusatzformat
  • Ob UGL4 für dieses Projekt relevant ist, und falls ja: FTP-Zugangsdaten/Verzeichnis
  • Endgültiger PyPI-/Modulname (fega-schmitt-client ist ein Arbeitstitel)
  • PyPI Trusted Publishing muss einmalig manuell auf pypi.org eingerichtet werden (Workflow-Datei pypi-publish.yml, Environment pypi), bevor der Release-Workflow tatsächlich veröffentlichen kann

Lizenz

MIT, siehe LICENSE.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fega_schmitt_client-0.0.2.tar.gz (60.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fega_schmitt_client-0.0.2-py3-none-any.whl (21.7 kB view details)

Uploaded Python 3

File details

Details for the file fega_schmitt_client-0.0.2.tar.gz.

File metadata

  • Download URL: fega_schmitt_client-0.0.2.tar.gz
  • Upload date:
  • Size: 60.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for fega_schmitt_client-0.0.2.tar.gz
Algorithm Hash digest
SHA256 1065a7e380d3ff67cda442ba2ff2e29a207a841c35dee2cb738e1a1e7f54518d
MD5 404249371d995e92abeaa13af9ad7f63
BLAKE2b-256 271908a9425464dba77b3127dfc46e9d3525e879dadf55c1977d1016a4fb8889

See more details on using hashes here.

Provenance

The following attestation bundles were made for fega_schmitt_client-0.0.2.tar.gz:

Publisher: pypi-publish.yml on the78mole/fega-schmitt-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fega_schmitt_client-0.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for fega_schmitt_client-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 9349428d1c8596b6d6efb9d2052fbfe3c547904b91865478ea6264d60af3b433
MD5 952fd95352b01777c5539cf1a9ec8115
BLAKE2b-256 7abf2c471a13ab4c481a34c60fc0efdb9008193868421849d156efa0b0f89487

See more details on using hashes here.

Provenance

The following attestation bundles were made for fega_schmitt_client-0.0.2-py3-none-any.whl:

Publisher: pypi-publish.yml on the78mole/fega-schmitt-client

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page