CURL / API ... Health

Hallo zusammen,

ich versuche mich das erste mal an eine API ran und bin da sehr hilflos gerade. Ich nutze eine Token API und bekomme den Bearer Token zurück.

Mit dem Token stelle ich die nächste Anfrage und bekomme das hier als Ergebnis zurück.

Navigate to /health to see the health status.1

Ich kann damit leider nichts anfangen, kann vielleicht jemand was kurz dazu erklären
was diese Response bedeutet ?

Danke und Gruß

Das du an der URL /health anhängen sollst :slight_smile:
Michael

Hi,

öhhh wie meinst du jetzt ???

/api​/v1​/data​/Kapazitaetsreserve/

hier noch ein /health anhängen ?

Gruß

also ich habe vieles probiert. So wirklich komme ich nicht dahinter wie diese Anfragen funktioniert.

Was ist der root der API?
Das hier?
/api​/v1​/data​
Dann dahinter versucht /health anzuhängen?
Michael

Da ich mich leider in API Schnittstellen nicht auskenne kann ich das nicht genau sagen.
So wie du aber fragst, sehen alle Anfragen bis hier

​/api​/v1​/data​

gleich aus …

/api​/v1​/health --> das gibt es auch so als Abruf der API
​/api​/v1​/data​/prognose​/{product}
/api​/v1​/data​/prognose​/{product}​/{dateFrom}​/{dateTo}
/api​/v1​/data​/hochrechnung​/{product}
/api​/v1​/data​/hochrechnung​/{product}​/{dateFrom}​/{dateTo}
usw.
Hier werden die Daten abgerufen ...
https://ds.netztransparenz.de/api/v1/data/{data}/{product}/{dateFrom}/{dateTo}

In der Beschreibung steht aber auch in der Hinsicht nichts dazu, aber gut vielleicht liegt das aber auch an meinen nicht vorhandenen Kenntnissen in der Richtung das man sowas nicht erwähnen muss.

Deine Versuche habe ich gerade getestet, aber egal wo ich das „health“ einbaue, die Antwort bleibt die selbe.

https://ds.netztransparenz.de/health
Liefert einfach den Zustand als Text.
Und die Meldung aus deinem ersten Beitrag scheint immer zu kommen, wenn deine Anfrage auf keinen Endpunkt zutrifft.
Das hier scheint zu gehen:
https://ds.netztransparenz.de/api/v1/data/hochrechnung/solar

Irgendwas scheint mit deinem Slash / nicht zu passen.
Wenn ich die url aus deinen beitragen kopiere, zerhaut es die url.
Michael

mhhh, ich kann es nicht genau sagen. Wenn man die Swagger UI anschaut, dann sieht es eigentlich so aus wie bei mir.

Oder mache ich da noch was falsch ?

Was meinst du mit URL-zerhauen ?

https://ds.netztransparenz.de​/api​/v1​/data​/hochrechnung​/solar

so sieht die URL nach der Printausgabe bei mir aus.

Das geht.
Bei deinen links von oben wurde daraus immer so etwas:
https://ds.netztransparenz.de/api%E2%80%8B/v1%E2%80%8B/data%E2%80%8B/hochrechnung%E2%80%8B/solar
Als wenn da ein falsches Zeichen eingeschlichen hat.
Michael

Ja ok, aber was wäre jetzt mein Fehler ?
Den Link hatte ich gezeigt, der sollte ja passen. Da ist kein Sonderzeichen drin.

Die erste Tokenanfrage für meinen Bearer Token zu bekommen ist ja auch funktionsfähig.

Jetzt bin ich total verwirrt :slight_smile:

Vielleicht liegt es an der Authentifizierung.
Den Bearer Token als Paramter angeben oder als Authentifizierung verwenden.

Moin,

ich bin da leider sehr frisch was das angeht solche API Schnittstellen einzubinden.
Was meinst du mit Parameter mit angeben ?

Gruß

Magst du uns mal deinen Code zeigen?

So wie ich es verstanden habe muss zuerst der Access Token abgerufen werde, dies kannst du ja vermutlich schon und m it diesem Token machst du den Aufruf auf den Endpoint.

Dies ist zwar hier in Python:

# Provide URL to request health info on API
myURL = "https://ds.netztransparenz.de/api/v1/health"
response = requests.get(myURL, headers = {'Authorization': 'Bearer {}'.format(TOKEN)})
print(response.text, file = sys.stdout)

Die interessante Stelle ist diese:

headers = {'Authorization': 'Bearer {}'.format(TOKEN)})

D.h. Im header muss der Access Token angegeben werden.

Ohne Garantie, da nicht getestet:


 $timeout = round($this->ReadPropertyInteger('Timeout') / 1000);
        //Send data to endpoint
        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_CUSTOMREQUEST   => $CustomRequest,
            CURLOPT_URL             => $Endpoint,
            CURLOPT_HEADER          => true,
            CURLOPT_RETURNTRANSFER  => true,
            CURLOPT_FAILONERROR     => true,
            CURLOPT_CONNECTTIMEOUT  => $timeout,
            CURLOPT_TIMEOUT         => 60,
            CURLOPT_POSTFIELDS      => $Postfields,
            CURLOPT_HTTPHEADER      => [
                'Authorization: Bearer ' . $accessToken]]);
        $response = curl_exec($ch);
        if (!curl_errno($ch)) {
            switch ($http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE)) {
                case 200:  # OK
                    $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
                    $header = substr($response, 0, $header_size);
                    $body = substr($response, $header_size);
                    $this->SendDebug(__FUNCTION__, 'Header: ' . $header, 0);
                    $this->SendDebug(__FUNCTION__, 'Body: ' . $body, 0);
                    break;

                default:
                    $this->SendDebug(__FUNCTION__, 'HTTP Code: ' . $http_code, 0);
            }
        } else {
            $error_msg = curl_error($ch);
            $this->SendDebug(__FUNCTION__, 'An error has occurred: ' . json_encode($error_msg), 0);
        }
        curl_close($ch);
        return $body;

$accessToken Musst du deinen zuvor abgeholten Access Token einsetzen.

Wenn du den Access Token abrufst, muss vermutlich im header folgendes mitgegeben werden:

'grant_type': 'client_credentials',
'client_id': DEINE_CLIENT_ID,
'client_secret': DEIN_CLIENT_SECRET

War jetzt auf die schnelle, vielleicht ein Ansatz für dich.

Uli

Guten Morgen,

danke für den Code. Soweit wie ich das auf die schnelle erkennen kann, habe ich die Anfrage gleich aufgebaut. Im Header ist auch mein Token mit übergeben worden, den ich zuvor angefragt habe.

Ich werde nochmal testen und gebe dann Rückmeldung. Muss jetzt mal was arbeiten :slight_smile:

Gruß

function FN_GetNetTransparenz($BerearToken, $EndPoint, $xPrintLog)
{
    global $ScriptName;
    $Release        = false;
    $json_response  = false;

    // Funktionsparameter überprüfen ...
    if (($EndPoint == '') or (empty($EndPoint)) or (strlen($EndPoint) <= 0))
    {
        $message = 'Es wurd keine URL übergeben ...';
        FN_ThrowException($ScriptName, $message, $xPrintLog);
    }
    elseif (($BerearToken == '') or (empty($BerearToken)) or (strlen($BerearToken) <= 0))
    {
        $message = 'Es wurd kein Beareartoken übergeben';
        FN_ThrowException($ScriptName, $message, $xPrintLog);
    }
    else
        $Release = true;

        $Release = true;

    // FREIGABE ALLE PARAMETER PASSEN ...
    if ($Release)
    {
        //Beginn Datenabfrage
        $curl = curl_init($EndPoint);
        //curl_setopt($curl, CURLOPT_URL, $EndPoint);
        //curl_setopt($curl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);        
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, false);        
        //curl_setopt(CURLOPT_FAILONERROR, true);
        //curl_setopt($curl, CURLOPT_CUSTOMREQUEST, 'GET');
        //curl_setopt($curl, CURLOPT_POST, 1);
		//curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
		//curl_setopt($curl, CURLOPT_TIMEOUT, 10);
		//curl_setopt($curl, CURLOPT_NOBODY, true);
		//curl_setopt($curl, CURLOPT_HTTPGET, false);
        //curl_setopt($curl, CURLOPT_USERNAME, $UserName);
        //curl_setopt($curl, CURLOPT_PASSWORD, $Password);
        //curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
        //curl_setopt($curl, CURLOPT_POSTFIELDS, "{}");                    

        $headers = array
        (
            "Authorization: Bearer " . $BerearToken,
            //'Accept: */*',            
            //'Content-Type: application/json',
            //"Connection: keep-alive" ,
            //"Pragma: no-cache" ,
            //"Cache-Control: no-cache" ,
            //"Accept: application/json, text/plain, */*" ,
            //"DNT: 1" ,
            //'Content-Type: application/x-www-form-urlencoded',
        );

        //curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_HEADER, $headers);

        $json_response  = curl_exec($curl);
        $json_response  = json_decode($json_response, true);
        $status         = curl_getinfo($curl, CURLINFO_HTTP_CODE);
 
        curl_close($curl);      // URL CLOSE ...
        
        if ($status != 200)     // FEHLERABFRAGE ...
        {
            $json_response = $status;
            throw new Exception("Expection --> Error : call to URL $endpoint failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl) . "");
        }

        return $json_response;
    }
}

So…

Für den health check benötigst du keinen AccessToken:

<?php
//Get the health info from netztransparenz
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://ds.netztransparenz.de/api/v1/health');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
$headers = array();
$headers[] = 'Accept: */*';

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
echo $result;

Um den AccessToken zu holen:

<?php
//Get the access token from netztransparenz
$ch = curl_init();

$clientId = 'cm_app_1234567890';
$clientSecret = 'ntp_987654321';

curl_setopt_array($ch, array(
  CURLOPT_URL => "https://identity.netztransparenz.de/users/connect/token",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_SSL_VERIFYHOST =>false,
  CURLOPT_SSL_VERIFYPEER => false,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "grant_type=client_credentials&client_id=" . $clientId . "&client_secret=" . $clientSecret,
  CURLOPT_HTTPHEADER => array(
    "content-type: application/x-www-form-urlencoded"
  ),
));

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
echo $result;

Um dann z.B. die Jahresmarktprämie abzufragen:

<?php
//Get the anual bonus from netztransparenz
$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, 'https://ds.netztransparenz.de/api/v1/data/Jahresmarktpraemie');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');

$accessToken = 'eyJhbGciOiJSUz......AxjUA';
$headers = array();
$headers[] = 'Accept: */*';
$headers[] = 'Authorization: Bearer ' .$accessToken;
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);
echo $result;

Das sind jetzt nur einfache Skripte. Musst du dann für das Modul umbauen.
Der AccessToken hat nur eine bestimmte zeitliche Gültigkeit:

{"access_token":"eyJh........n1jAQ","expires_in":3600,"token_type":"Bearer","scope":"ntpStatistic.read_all_public"}

Im Modul würde ich den AccessToken in den Buffer schreiben mit Zeitstempel. Den werde ich dann abfragen und nur wenn der Zeitstempel abgelaufen ist, dann neu anfordern.

Viel Spaß!

Uli

@ubittner
Moin, ich weis nicht ob du eventuell mal über meinen Code geschaut hast, bin aber der Meinung das ich eigentlich so habe wie du erwähnt hast. Werde mich aber am Wochenende nochmal damit befassen.

Danke erstmal
Gruß

Moin,

also ich habe mir das nochmal angeschaut. Entweder sehe ich meinen Fehler in dem Script nicht oder es ist wer weis was falsch. Ich kann es leider nicht eingrenzen.

Ich bin der Meinung das ich das richtig anwende. Aber vielleicht hat jemand nochmal eine Idee.
Ich finde das aktuell keine Ansatz um das Problem lösen zu können.

Gruß

Hallo,

@pitti
@Nall-chan
@ubittner
@SGU
@dvzo

ich habe heute mit @pitti gesprochen und wir haben uns gemeinsam das Problem angeschaut.
So wie @Nall-chan schon erwähnt hatte scheint was mit der URL nicht zu stimmen.

Ich war immer im Editor soweit eigentlich der Meinung alles was ich dort lesbar vor Augen habe das die URL stimmt.
Dem war leider nicht so. Wie bin ich zu dem Problem gekommen. Ich habe mir den API URL Aufbau von der Swagger Seite heraus kopiert und in Symcon in ein Script kopiert, damit ich ja nicht das alles abtippen muss. Das ist ja erstmal alle voll legitim.

Ich hatte mir mit einem anderen Kollegen @dvzo die Swagger HTML Seite im Aufbau angeschaut. Da ist dann aufgefallen das an der Stelle wo die URL auf der Swagger Seite steht, das dort ein „&ZeroWidthSpace“ steht. Das vor jedem „/“ in der API

Das hat dann zu den falschen Anfragen geführt.

Ich habe dann alle API URLs aus dem Script in NotePad++ kopiert, dann die die Codierung auf ANSI umgestellt, dann alle Sonderzeichen ersetzt und wieder zurück in das Symcon Script kopiert.

Damit war das Thema erledigt. Aber darauf wäre ich niemals gekommen.

Danke nochmal vielmals an @pitti und @dvzo und allen anderen, da wäre ich niemals darauf gekommen.

Gruß

1 „Gefällt mir“