requests.post sendet keine Datei

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
pystar
User
Beiträge: 6
Registriert: Dienstag 1. Mai 2018, 17:43

Hallo Zusammen!

Gerade sammle ich meine ersten Erfahrungen mit Python und hänge schon an einem Problem. Ich will eine Datei an einen Dienst senden. Der soll die Datei nehmen und mir den Inhalt in einer Response-Datei senden. Wenn ich den PostAufruf ohne Datei sende kommt ein Fehlertext in der Datei.
Soweit funktioniert der Testdienst (positiv und negativ-Test) über Konsole mit einem curl-Aufruf:

Code: Alles auswählen

curl -X POST -d @test.xml http://192.168.56.101/requestTest -o test2.txt
MIt Python hab ich es so versucht:

Code: Alles auswählen

import requests


def main():
    print("Start Request-Test")
    url = 'http://192.168.56.101/requestTest'
    #file = open('test.xml', 'rb')
    files = {'file': open('test.xml','rb')}
        
    r = requests.post(url, files=files, headers={'Content-Type': 'text/xml'})
    
    r.text
    r.content
    
    with open('test.txt', 'wb') as f:
        f.write(r.content)
    print("Fertig!")
    
if __name__ == "__main__":
    main()

Als Ergebnis kommt immer der Fehlertext das keine Datei gesendet wurde.
Jetzt hab ich einige Varianten ausprobiert, leider ohne Erfolg. Alle Anleitungen die ich gefunden habe sind so oder ähnlich aufgebaut.
Beim debuggen sehe ich, dass das File und die Url richtig gefunden wird.

Was mach ich falsch oder wo ist der Fallstrick?
P.S. ich verwende Python 3.5 und Eclipse
__deets__
User
Beiträge: 14537
Registriert: Mittwoch 14. Oktober 2015, 14:29

Sieht an sich ganz gut aus, aber es kann sein das requests das form encoded. Und dein Dienst einfach eine Datei im Body will. Früher habe ich so etwas mit einem Proxy getestet, heutzutage würde ich mal wireshark bemühen & damit den Verkehr und Unterschied zwischen curl und request anschauen.
pystar
User
Beiträge: 6
Registriert: Dienstag 1. Mai 2018, 17:43

Hallo __deets__,

danke für deine Antwort und für den Tipp mir wireshark.
Leider werde ich aus dem wireshark-Daten nicht ganz schlau. Es sieht so aus als ob der Dienst eher den Stream und nicht die Datei erwartet.

In dieser Version funktioniert es jetzt:

Code: Alles auswählen

import requests

def main():
    print("Start Request-Test")
    url = 'http://192.168.56.101/requestTest/index.php'
    anforderungsFile = 'anforderung.txt'
             
    with open(anforderungsFile) as xml:
        r = requests.post(url, data=xml)  
        print(anforderungsFile)
        print(r.content)
        print("text: " + r.text)  
    type(r)
    requests.models.Response
    type(r.content)
    
    ergebnisFile = open('ergebnis.txt', "w+")
    
    ergebnisFile.write(r.text)
    ergebnisFile.close()
    print("Fertig!")
    
if __name__ == "__main__":
    main()
Ich habe jetzt noch nicht verstanden wie das genau funktioniert. Leider kann ich mir das momentan aus der Anleitung noch nicht erschließen: http://docs.python-requests.org/en/master/
Vielleicht hat noch jemand einen Hinweis damit ich das besser verstehe?

besten Dank und viele Grüße
pystar
__deets__
User
Beiträge: 14537
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich bin verwirrt. Geht’s jetzt? Wenn ja: es gibt halt Unterschiede, ob man ein html Formular verschickt (dein erster Versuch) oder gleich eine ganze Datei. Letzteres ist einfacher, ersteres flexibler (mehrere Dateien, andere Formular Felder).
pystar
User
Beiträge: 6
Registriert: Dienstag 1. Mai 2018, 17:43

Hallo __deets__

Ich bin auch verwirrt ;)
Die zweite Variante funktioniert.
Wenn ich es im Wireshark richtig gesehen habe wird in der ersten Variante die Datei selber gesendet. In der zweiten nur der steam der Datei.
Leider werde ich aus der API an der Stelle nicht schlau.
Ich kann jetzt nicht genau sagen wie es funktioniert. Also wir ich bewusst eine Datei oder eben einen steam der Datei sende.

Beste Grüße
pystar
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@pystar: man muß halt das liefern, was die Gegenseite möchte. Warum heißt die Datei anforderung.txt, anscheinend ist es doch aber eine XML-Datei? Die Zeilen mit `type` sind sinnlos, da sie nichts tun. Der Dateimodus `w+` ist ungewöhnlich, wahrscheinlich möchtest Du `w` mit dem with-Statement benutzen.
Antworten