Seite 1 von 1

Verständnisfrage REST API

Verfasst: Mittwoch 1. Dezember 2021, 17:53
von mcnill
Hallo zusammen,

auch wenn ich mir nicht sicher bin ob das Thema hier richtig aufgehoben ist, habe ich mich doch entschlossen einen Versuch zu wagen...
Falls es nicht ins Forum passt, bitte löschen.

Ein Programm stellt via lokalem webserver eine REST API zur Verfügung gegen die ich Daten austausche.
Die meisten API Aufrufe sind selbsterklärend. An der Übertragung von Dateien an den Server scheitere ich jedoch bislang.
Der Server loggt bei jeder Anfrage das der String Parameter "Name" fehlt und wirft einen 400er aus. :(
Das bedeutet, dass ich die Anfrage falsch erstelle.
-> "name" ist der einzige Pflichtparameter.
-> wohin mit den Binärdaten?
Hier fehlt mir offensichtlich das nötige Hintergrundwissen/ Verständnis für die API Beschreibung.
Vielleicht kann mir hier freundlicherweise jemand auf die Sprünge helfen.

Besten Dank für eure Hilfe!

Mein Versuch den Aufruf zu formulieren:

Code: Alles auswählen

def send_ifc_model():
    ifcfilepath =  "C:\\temp\\Testmodell.ifc"
    with open(ifcfilepath, "rb") as f:
        content = f.read()
    headers = {'content-type': 'application/octet-stream'}
    data = {'name' : content}
    gpl_response  = requests.post(f'{smc_baseurl}/models', headers=headers, data=data)
    print(gpl_response.status_code)
Hier ein Auszug aus der API Doku:

Code: Alles auswählen

post:	
    tags:
        0:	                    "models-api-controller"
    summary:	                "Open IFC Model"
    operationId:	            "openIFCModel"
    consumes:	
        0:	                    "application/octet-stream"
    produces:
        0:	                    "application/json"

    parameters:	
        0:
            name:	            "method"
            in:                	 "query"
            required:   	    false
            type:	            "string"
            enum:
                0:	            "DELETE"
                1:	            "GET"
                2:          	"HEAD"
                3:           	"OPTIONS"
                4:	            "PATCH"
                5:	            "POST"
                6:  	        "PUT"
                7:	            "TRACE"
        1:
            name:       	    "name"
            in:	                "query"
            description:	    "Name of the model"
            required:	        true
            type:	            "string"
        2:
            name:	            "type"
            in:	                "query"
            required:	        false
            type:	            "string"
        3	
            name:	            "url"
            in:	                "query"
            required:	        false
            type:	            "string"
            format:	            "uri"
    responses:	
        200	{…}
        201	{…}
        401	{…}
        403	{…}
        404	{…}
        500	{…}

Re: Verständnisfrage REST API

Verfasst: Mittwoch 1. Dezember 2021, 18:55
von __blackjack__
@mcnill: Wenn andere Aufrufe nach dem Muster funktionieren, dann scheint die API Dir bestimmte Fehler zu verzeihen, denn das was Du `data` nennst und als `data` übergibst, soll laut Dokumentation in die „query“, also nicht in den „body“ der Anfrage sondern in die URL. Bei `requests` wäre das `params`. Womit dann der „body“ sinnvollerweise für die Binärdaten genutzt werden kann.

Bei "name" soll auch der *Name* übergeben werden, nicht der Inhalt der Datei.

Re: Verständnisfrage REST API

Verfasst: Mittwoch 1. Dezember 2021, 22:47
von mcnill
@__blackjack__
Vielen Dank für die Antwort! Die Erklärung hat es gebraucht.
Die anderen Aufrufe funktionieren nach einem anderen Muster...
Wiefolgt klappt der Aufruf nun.

Code: Alles auswählen

def send_ifc_model():
    ifcfilepath =  "C:\\temp\\Testmodell.ifc"
    with open(ifcfilepath, "rb") as f:
        content = f.read()
    headers = {'content-type':'application/octet-stream'}
    params = {'name':'IFCDatei'}
    data = (content)
    gpl_response  = requests.post(f'{smc_baseurl}/models', headers=headers, params=params, data=data)
    print(gpl_response.json())
Respekt! Als Endanwender von Software der ich bin, bekomme ich sonst bunte Bildchen mit Erklärungen. Da ist die API Doku hier schon was anderes.
Merci nochmals!

Re: Verständnisfrage REST API

Verfasst: Mittwoch 1. Dezember 2021, 23:15
von Sirius3
`headers` ist überflüssig, denn das ist der Default, und warum nennst Du `content` in `data` um?

Re: Verständnisfrage REST API

Verfasst: Mittwoch 1. Dezember 2021, 23:31
von __blackjack__
Ich würde noch prüfen ob die Antwort keine Fehlerantwort war. Auch wenn das `json()` dann zwar sehr wahrscheinlich zu einer Ausnahme führt, ist die Ausnahme die sich auf den HTTP-Status bezieht mit mehr Informationen versehen was die Ursache angeht. Ungetestet:

Code: Alles auswählen

import requests
from pathlib import Path


def send_ifc_model():
    response = requests.post(
        f"{smc_baseurl}/models",
        params={"name": "IFCDatei"},
        data=Path(R"C:\temp\Testmodell.ifc").read_bytes(),
    )
    response.raise_for_status()
    print(response.json())

Re: Verständnisfrage REST API

Verfasst: Donnerstag 2. Dezember 2021, 20:03
von mcnill
@sirius3:
Danke dir für die Hinweise.
headers -> war mir so nicht klar, steht aber eigentlich auch in der Doku von 'requests' wenn man nachliest...
content in data umzubenennen -> klarer Unsinn. :)

@ __blackjack__:
Abermals danke für die Hilfestellung!
rawstrings für Windowspfade,
das 'pathlib' Modul (kannte ich nicht),
die raise_for_status methode.
Wunderbar! :)
Bisher habe ich nur die API Aufrufe zusammengestellt, das Ganze muss noch in ein vollständiges Skript mit Prüfung ob der Server da ist und so weiter.