Curl - Daten Senden

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
TommiB
User
Beiträge: 41
Registriert: Montag 9. Februar 2015, 18:15

Hallo,
ich möchte mittels Python 2.7 auf dem Raspi folgendes "senden"

curl -H "Content-Type: application/json" -X POST -u USER:PASSWORD -d '{ "text": "TEXT", "Names": ["NAME"], "Group": ["GRUPPENNAME"] }' URL/calls


Folgendes habe ich versucht:

Code: Alles auswählen

import os
os.system ("curl -1 -X POST H Content-Type: application/json -d -u \"TommiB:TestPW\"  "Text=testtest&Names=TommiB&GroupNames=Freunde&\"  \"http://irgenteineadesse.com:8080/"")
Habe gestern auch schon andere Sachen probiert..

Kann mir jemand einen Tipp geben?

Gruß Tommi
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

'curl' macht im Prinzip nichts besonderes, sondern führt nur HTTP Requests aus. Das kann Python auch schon von selbst, sodass es nicht notwendig ist, dafür einen externen Prozess zu starten. Stattdessen solltest du dir entweder mal das 'requests'-Modul ansehen, oder notfalls urllib/urllib2 aus der Standard Library.

Nebenbei: In Python gibt es, anders als z.B. in Bash, zwischen einfachen und doppelten Anführungszeichen für Strings keinen semantischen Unterschied. Aber man kann sie benutzen, um das jeweils andere im String selbst zu verwenden. Daher kannst du in deinem 'os.system' Aufruf (hier übrigens mal das 'subprocess'-Modul ansehen), einfach 'curl…' schreiben und auf das Escaping verzichten.
Benutzeravatar
snafu
User
Beiträge: 6738
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Und bei der Verwendung von subprocess kann man die Anführungszeichen hier sowieso weglassen, gerade weil man sich dann ja nicht mehr darum kümmern muss, wie eine Shell ein Sonderzeichen wohl behandeln könnte. Es ist schlichtweg keine Shell mehr zwischengeschaltet, d.h. es wird die ursprüngliche Eingabe ohne jegliche Interpretation direkt an das Programm übergeben.

EDIT:
Wenn ich deinen Code ausführen will, bekommen ich übrigens einen SyntaxError. Das ist in der Form also überhaupt nicht lauffähig. Kein Wunder bei den ganzen Anführungszeichen. Wie gesagt, schau dir mal subprocess an. Da brauchst du meistens überhaupt keine Anführungszeichen, da wie gesagt die einzelnen Argumente (bei der Variante mit der Liste) isoliert behandelt werden und in ihrer Ursprungsform übermittelt werden. Das macht vieles einfacher.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

macht das Python Skript noch mehr? Einen einzelnen Shell-Befehl in ein Python-Skript packen macht ja wenig Sinn...

BTW: wenn du in der Shell Request mit JSON senden möchtest / musst, ist das IMHO mit HTTPie deutlich einfacher & angenehmer.

Innerhalb eines Pytho-Skripts möchtest du aber immer das genannte `requests` Modul verwenden.

Und zu `os.system`: das gilt als veraltet und auch in der Python-Doku steht explizit, dass die Nutzung von `subprocess` empfohlen wird.

Gruß, noisefloor
TommiB
User
Beiträge: 41
Registriert: Montag 9. Februar 2015, 18:15

Hallo,
danke für die Antworten...

Das Script soll "nur'" die Daten an die Seite schicken. Das wird da dann verarbeitet.
Das ganze soll in eine Ablaufsteuerung und bei bestimmten Zuständen eine Nachricht verschicken...

Irgendwie checke ich das mit requests und subprocess nicht....
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Irgendwie checke ich das mit requests und subprocess nicht....
Was denn genau nicht...?

Das `subprocess` Modul macht das, was du mit `os.system` auch machst - curl aufrufen. Nur besser, schöner, einfacher, flexibler, moderner.

Das `request` Modul macht das, was du aktuell mit curl machst - nur direkt aus Python heraus, was diverse Vorteile hat / haben kann.
Das ganze soll in eine Ablaufsteuerung und bei bestimmten Zuständen eine Nachricht verschicken...
Dann solltest du IMHO das requests-Modul nehmen, weil du dann alles aus deinem Python-Skript heraus machen kannst, ohne externe Programmaufrufe.
Doku zu requests: http://docs.python-requests.org/en/master/

Gruß, noisefloor
TommiB
User
Beiträge: 41
Registriert: Montag 9. Februar 2015, 18:15

Habe jetzt folgendes probiert:

Code: Alles auswählen

import requests
import json

payload = {'Text':'testtest', 'Names':Tommi',GroupNames':'Friends'}

r = requests.post("http://defaultsite.com",auth=('Tommi:TestPW'), data=json.dumps(payload))
print(r.text)
Bekomme ich folgende Fehler:
Traceback (most recent call last):
File "/home/pi/test request.py", line 6, in <module>
r = requests.post("http://defaultsite.com",auth=('Tommi:TestPW'), data=json.dumps(payload))
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 110, in post
return request('post', url, data=data, json=json, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 474, in request
prep = self.prepare_request(req)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 407, in prepare_request
hooks=merge_hooks(request.hooks, self.hooks),
File "/usr/lib/python2.7/dist-packages/requests/models.py", line 306, in prepare
self.prepare_auth(auth, url)
File "/usr/lib/python2.7/dist-packages/requests/models.py", line 527, in prepare_auth
r = auth(self)
TypeError: 'str' object is not callable
nezzcarth
User
Beiträge: 1633
Registriert: Samstag 16. April 2011, 12:47

Wo hast du denn den "auth=…" Teil her? Das ist so nicht richtig. Schau mal hier: http://docs.python-requests.org/en/late ... ntication/
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

Code: Alles auswählen

auth=('Tommi:TestPW')
ist auch falsch, der Wert für `auth` muss ein Tuple sein - siehe Beispiel auf der Startseite der Doku von requests:

Code: Alles auswählen

auth=('Tommi', 'TestPW')
Und anstelle von `json.dumps` ist das einfacher:

Code: Alles auswählen

r = requests.post("http://defaultsite.com", auth=('Tommi', 'TestPW'), json=payload)
Gruß, noisefloor
TommiB
User
Beiträge: 41
Registriert: Montag 9. Februar 2015, 18:15

Hallo noisefloor,
danke für die Hilfe.

Code: Alles auswählen

import requests, json
payload = {'Text':'testtest', Names':Tommi','GroupNames':'Friends'}
r = requests.post("http://testsite.com:8080/calls", auth=(Tommi','TestPW'), json=payload)
print(r.text)
Ich bekomme immer noch folgende Fehler...

Traceback (most recent call last):
File "/home/pi/test request.py", line 6, in <module>
r = requests.post("http://testsite.com", auth=(Tommi',TestPW'), json=payload)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 110, in post
return request('post', url, data=data, json=json, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/api.py", line 56, in request
return session.request(method=method, url=url, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 488, in request
resp = self.send(prep, **send_kwargs)
File "/usr/lib/python2.7/dist-packages/requests/sessions.py", line 609, in send
r = adapter.send(request, **kwargs)
File "/usr/lib/python2.7/dist-packages/requests/adapters.py", line 487, in send
raise ConnectionError(e, request=request)
ConnectionError: HTTPConnectionPool(host=testsite.com): Max retries exceeded with url: /calls (Caused by NewConnectionError('<requests.packages.urllib3.connection.HTTPConnection object at 0x74f22030>: Failed to establish a new connection: [Errno 111] Connection refused',))

Die letzte Meldung sagt wohl aus, daß ich zu viele Versuche hatte und erstmal gesperrt bin...
Ich habe den Betreiber schon angeschrieben...

Aber was das davor ist, weiss ich nicht.

Gruß Tommi
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Aber was das davor ist, weiss ich nicht.
Das davor ist der Stacktrace, also der "interne Weg" zum Fehler. Das kann beim Degugging hilfreich sein - hier aber nicht :-) Kannst du also ignorieren.

Gruß, noisefloor
Antworten