Einen Live-Daten-Provider bauen

Experte

Der Vertrag, den ein Webdienst erfüllt, um Ist-Zahlen in einen Metapad-Twin zu liefern: was Metapad anfragt, wie Zeiträume berechnet werden und was zu antworten ist.

Dieser Artikel richtet sich an Entwickler, die ein anderes System (ein ERP, ein Data Warehouse, einen öffentlichen Datenfeed) mit Metapad verbinden. Modellautoren brauchen ihn nicht; für sie gibt es Live-Daten in einen Twin holen.

Ein Live-Daten-Provider ist ein HTTPS-Endpunkt. Wenn jemand Live-Daten für einen Twin abruft, ruft Metapad ihn einmal je Szenario auf und schreibt die Antwort in die Zeitreihen dieses Szenarios.

Der Ablauf

  • Metapad ruft Sie auf. Das geschieht, wenn jemand auf Jetzt abrufen klickt, wenn ein Dashboard eines Live-Daten-Szenarios geöffnet oder sein Zeitraum geändert wird, oder wenn ein KI-Werkzeug einen Abruf anstößt. Sie senden nie von sich aus Daten.
  • Eine Anfrage je Twin und Szenario, die alle Agents, Eigenschaften und Zeitschritte auf einmal umfasst.
  • Zuordnung und Rechnen übernehmen Sie. Metapad summiert, mittelt, interpoliert und rechnet keine Einheiten um. Jeder Wert, den Sie senden, ist der Wert für einen ganzen Zeitraum.

Verbindung herstellen

  • Ihr Endpunkt muss HTTPS verwenden.
  • Sein Host muss für Ihr Metapad freigeschaltet sein. Auf app.metapad.ai übernimmt das transentis — schicken Sie uns den Hostnamen.
  • Braucht Ihr Endpunkt ein Token, wird es zusammen mit dem Host eingerichtet und nicht im Modell gespeichert. Metapad sendet es als Authorization: Bearer <token>. Antworten Sie mit 401, wenn es fehlt oder falsch ist.
  • Metapad folgt keinen Weiterleitungen, wartet höchstens 60 Sekunden und liest höchstens 32 MB Antwort.

Die Anfrage

Metapad sendet ein GET an die URL, die als Provider-URL des Twins eingetragen ist, und hängt seine Parameter an den Query-String an. Parameter, die schon in der URL stehen (ein Mandant, ein Datensatz), bleiben erhalten, sodass Sie sie für Ihr eigenes Routing nutzen können. Ignorieren Sie Parameter, die Sie nicht kennen; es können neue hinzukommen.

GET https://provider.example/data?tenant=acme
    &twin_id=…&scenario_id=…
    &step_count=1&step_unit=month
    &epoch=2027-01-01T00:00:00%2B01:00&epoch_step_offset=12
    &start_date=2028-01-01T00:00:00%2B01:00
    &from_timestep=0&to_timestep=11
ParameterBedeutung
twin_id, scenario_idWelcher Twin und welches Szenario gefüllt werden. Ein Provider für mehrere Twins kann seine Daten danach auswählen.
step_count, step_unitLänge eines Zeitschritts, z. B. 1 month. Einheiten: second, minute, hour, day, week, month, quarter, year.
epochDer Kalenderanker des Twins, als Datum und Uhrzeit mit UTC-Offset.
epoch_step_offsetWie viele Schritte Zeitschritt 0 nach der Epoche liegt (kann negativ sein).
start_dateBeginn von Zeitschritt 0, zur Bequemlichkeit. Berechnen Sie Zeiträume nicht daraus (siehe unten).
from_timestep, to_timestepDie gewünschten Zeitschritte, beide einschließlich.

Alle Daten verwenden den UTC-Offset der Epoche; benannte Zeitzonen gibt es nicht.

Welcher Zeitraum ist Zeitschritt i

Mit k0 = epoch_step_offset und step = step_count × step_unit umfasst Zeitschritt i

von  epoch + (k0 + i) × step       (einschließlich)
bis  epoch + (k0 + i + 1) × step   (ausschließlich)
  • Sekunde bis Woche sind exakte Dauern.
  • Monat, Quartal (3 Monate) und Jahr (12 Monate) sind Kalendermonate: Berechnen Sie jede Grenze in einem Sprung von der Epoche aus, und nehmen Sie den letzten Tag des Monats, wenn der Zielmonat kürzer ist.
  • Zählen Sie nicht von start_date aus. Bei Monaten ergibt das andere Daten, sobald die Epoche auf den 29.–31. fällt. Bei einer Epoche am 31. Januar und k0 = 1 ist Zeitschritt 0 der 28. Feb. – 31. März und Zeitschritt 1 der 31. März – 30. April. Ab start_date gezählt begänne Zeitschritt 1 am 28. März, und jeder Wert landete ohne jede Fehlermeldung im falschen Zeitraum.

Die Antwort

  • 200 mit JSON-Body: die zu schreibenden Werte.
  • 204 ohne Body: nichts zu melden.
  • Jeder andere Status gilt als Fehler und wird dem Nutzer mit seinem Code angezeigt (z. B. 401, 404, 429, 500). Metapad wiederholt die Anfrage nicht.
{
  "matching_mode": "name",
  "entries": [
    { "agent": "Filiale Berlin", "property": "revenue", "timestep": 0, "value": "31000" },
    { "agent": "Filiale Berlin", "property": "revenue", "timestep": 1, "value": "28500" }
  ],
  "meta": { "provider": "ACME ERP" }
}
FeldRegel
matching_mode"name" oder "id". Muss der Einstellung Zuordnung über des Twins entsprechen, sonst wird die ganze Antwort abgelehnt.
entriesHöchstens 50.000 (sprechen Sie uns an, wenn Sie mehr brauchen). Eine längere Liste wird abgelehnt, nie abgeschnitten. Aggregieren Sie gröber oder verteilen Sie auf mehrere Szenarien.
agentNamensmodus: der Name des Agents, exakt. ID-Modus: die ID des Agents.
propertyNamensmodus: der Name der Eigenschaft. ID-Modus: die ID der Eigenschaft.
timestepZwischen from_timestep und to_timestep.
valueEin String. Einfache JSON-Zahlen und Wahrheitswerte werden ebenfalls akzeptiert.
metaOptional und von Metapad ignoriert; nützlich für Ihr eigenes Logging.

Eine Antwort, die kein JSON ist oder der matching_mode oder entries fehlt, wird als Ganzes abgelehnt.

Werte nach Eigenschaftstyp

EigenschaftstypAkzeptierter Wert
ZahlEine Dezimalzahl: "31000", "0.25", "-4e3"
Wahrheitswert"true" oder "false"
DatumYYYY-MM-DD oder Datum und Uhrzeit mit Offset
OptionGenau eine der Optionen der Eigenschaft
JSON, DictionaryGültiger JSON-Text
Text, Rich Text, AssetBeliebiger String

Was Metapad damit macht

Einträge, die sich nicht verwenden lassen, werden übersprungen und gezählt, und der Nutzer sieht die Zahlen: unbekannter oder mehrdeutiger Agent, unbekannte Eigenschaft, eine Eigenschaft mit Formel, falscher Werttyp, Zeitschritt außerhalb des Bereichs, ein doppelter Eintrag (der erste gilt), ein fehlerhafter Eintrag oder ein Wert, den jemand von Hand eingegeben hat (er bleibt, außer der Nutzer hat Abrufen und manuelle Werte ersetzen gewählt).

Alles andere wird in einem Schritt geschrieben, den ein Nutzer rückgängig machen kann. Weil ein fehlender Eintrag „keine Daten“ bedeutet und nie einen Wert löscht, ändert dieselbe Antwort zweimal gesendet nichts, und eine korrigierte Zahl ersetzt einfach die alte.

Checkliste

  1. GET über HTTPS bedienen und unbekannte Parameter ignorieren.
  2. Das Token prüfen; bei falschem Token mit 401 antworten.
  3. Die Daten nach twin_id / scenario_id (oder eigenen Parametern) auswählen.
  4. Für jeden Zeitschritt seinen Zeitraum wie oben von der Epoche aus berechnen.
  5. Die Rohdaten je Agent, Eigenschaft und Zeitraum aggregieren.
  6. Mit 200, dem matching_mode des Twins und den Werten als Strings antworten, oder mit 204.
  7. Unter 50.000 Einträgen und deutlich unter 60 Sekunden bleiben.

Ein minimaler Provider

# Flask. Monate werden in einem Sprung von der Epoche aus gezählt, begrenzt auf das Monatsende.
import calendar, datetime
from flask import Flask, request, jsonify, abort

app = Flask(__name__)
UNIT_MONTHS = {"month": 1, "quarter": 3, "year": 12}
UNIT_SECONDS = {"second": 1, "minute": 60, "hour": 3600, "day": 86400, "week": 604800}

def add_months(d, n):
    t = d.month - 1 + n
    y, m = d.year + t // 12, t % 12 + 1
    return d.replace(year=y, month=m, day=min(d.day, calendar.monthrange(y, m)[1]))

def period_start(epoch, count, unit, k):
    if unit in UNIT_SECONDS:
        return epoch + datetime.timedelta(seconds=k * count * UNIT_SECONDS[unit])
    return add_months(epoch, k * count * UNIT_MONTHS[unit])

@app.get("/data")
def data():
    if request.headers.get("Authorization") != "Bearer s3cr3t":
        abort(401)
    a = request.args
    epoch = datetime.datetime.fromisoformat(a["epoch"])
    k0, count, unit = int(a["epoch_step_offset"]), int(a["step_count"]), a["step_unit"]
    entries = []
    for i in range(int(a["from_timestep"]), int(a["to_timestep"]) + 1):
        lo = period_start(epoch, count, unit, k0 + i)
        hi = period_start(epoch, count, unit, k0 + i + 1)
        for agent, revenue in revenue_by_agent(lo, hi):   # Ihre Datenquelle
            entries.append({"agent": agent, "property": "revenue",
                            "timestep": i, "value": str(revenue)})
    if not entries:
        return "", 204
    return jsonify({"matching_mode": "name", "entries": entries})

Nächste Schritte

  • Live-Daten in einen Twin holen — was Modellautoren sehen
  • Einen Twin in den Kalender setzen — woher Epoche und Schritt kommen

Dieser Inhalt wurde kollaborativ mit KI erstellt.