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.6.tar.gz (62.7 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.6-py3-none-any.whl (23.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: fega_schmitt_client-0.0.6.tar.gz
  • Upload date:
  • Size: 62.7 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.6.tar.gz
Algorithm Hash digest
SHA256 004c7c4c930743b8f099cd7af08d49aec40d63a30355c1c8560a645e042c2cff
MD5 ff1a0ccf048333dae40f9c50d74f0490
BLAKE2b-256 91cb2b3c2e508231dc824635a2f67c12bc5df3f08373eaaee8382c104d343da1

See more details on using hashes here.

Provenance

The following attestation bundles were made for fega_schmitt_client-0.0.6.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.6-py3-none-any.whl.

File metadata

File hashes

Hashes for fega_schmitt_client-0.0.6-py3-none-any.whl
Algorithm Hash digest
SHA256 39b593fe38a762fe25a18bc1dbc4d3418b594da508dcbbd39e7ac0c66e5e859c
MD5 e921bc45ca441c2dc949c5f01397aec2
BLAKE2b-256 920dc428622cde23f732d243abc371568cb2a1994235f8ece34942a639fef0bb

See more details on using hashes here.

Provenance

The following attestation bundles were made for fega_schmitt_client-0.0.6-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