Seite 1 von 1
wget ausgabe in Variable??
Verfasst: Samstag 2. Mai 2020, 12:09
von joerg-harrer
Hallo, um es kurz zu machen.. Meine ersten "Gehversuche" in Python.
Ich habe folgende Frage.
ich komme von der Linux seite, hab da schon Jahrelang mit bash herumgetan und hab mir vor kurzem QT5 und Python angeschaut.
Ist es möglci, die wget.download(url) so verwenden , das die Ausgabe gleich in eine Variable kommt und keine datei auf platte legt?
Ich hab das in bash so hingebracht :
<SNIP>
cmd="wget
http://apache:8080/api/getPlainValue/11131"
x=$(wget -q -O - $cmd)
if [ "$x" == "true" ] ; then
cmd="wget
http://apache:8080/api/set/11131/?value=0"
else
cmd="wget
http://apache:8080/api/set/11131/?value=1"
fi
x=$(wget -q -O - $cmd) 2&> /dev/null
</SNIP>
In Phyton3 hab ich jetzt um das Ding zum laufen zu bringen , ein paar sehr unschöne Dinge gemacht ...
<SNIP>
cmd = "
http://apache:8080/api/getPlainValue/11131"
filename = wget.download(cmd,out="Arb.txt")
fo = open("Arb.txt", "r+")
line = fo.read(10)
print ("Read Line: %s" % (line))
if line == "true":
cmd="
http://apache:8080/api/set/11131/?value=0"
filename = wget.download(cmd,out="switch.txt")
os.remove("switch.txt")
else:
cmd="
http://apache:8080/api/set/11131/?value=1"
filename = wget.download(cmd,out="switch.txt")
os.remove("switch.txt")
fo.close()
os.remove("Arb.txt")
</SNIP>
Kann ich in Python ( Aktuelle Version Python 3.8.2) wget nicht so "umbiegen", das ich keine datei schreibe?
Wie gesagt, das sind meine ersten Gehversuche, und ich will das sauber machen.. Datei auf platte schreiben-> Datei zum lesen Öffnen-> dann löschen ist nicht die feine Art meine ich.
Ich hoffe das Ihr alle Gesund seid, und bin für Alle Infos dankbar.
Jörg
Re: wget ausgabe in Variable??
Verfasst: Samstag 2. Mai 2020, 12:38
von __deets__
Das hat mit Python nichts zu tun, wget will Dinge ins Dateisystem legen. Das ist dem auch nur sehr schwer abzugewoehnen, und bisher habe ich das nur mit Umlenkung nach /dev/null gemacht. Da ist es aber natuerlich etwas nutzlos. Edit: ich sehe gerade, du machst das ja auch -O. Das geht theoretisch, wuerde ich aber nicht machen. Sondern:
Aber in Python wuerde man eh wget (oder curl) nicht benutzen. Sondern einfach das requests Modul benutzen. Musst du ggf. vorher installieren. Und als Konsequenz hast du uA auch deine Rueckgabe im Speicher, statt auf Platte.
Und fuer Arbeit mit Dateien benutzt man die "rohen" os-calls heutzutage nicht, sondern bemueht die "pathlib".
Re: wget ausgabe in Variable??
Verfasst: Samstag 2. Mai 2020, 13:09
von Sirius3
Benutze statt <snip> Code-Tags, dann ist der Code hier im Forum auch lesbar. r+ ist als Dateimodus nie sinnvoll. Lesezugriff hellt man mit "r". Der if- und else-Block unterscheiden sich nur in einem Zeichen. Da benutzt man also eine Variable. HTTP liest man entweder mir dem eingebauten urllib-Modul oder requests.
Re: wget ausgabe in Variable??
Verfasst: Samstag 2. Mai 2020, 13:20
von nezzcarth
Wenn es unbedingt wget sein soll, geht es neben '-O -' vielleicht mit Fifos/Named Pipes. Das ist aber auch ganz schönes Gebastel (habe es nicht ausprobiert); ich würde das nicht empfehlen. Oder nimm curl, das schreibt doch eh auf stdout, wenn ich mich nicht vertute. Der beste Weg wäre aber eine reine Python-Lösung, zum Beispiel mit Requests.
Re: wget ausgabe in Variable??
Verfasst: Samstag 2. Mai 2020, 16:07
von joerg-harrer
Danke für Eure Antowot. ja, noch viel zu lernen ....
Habe jetzt requests zum laufen gebracht
Code: Alles auswählen
def toggle_ARb():
cmd = "http://apache:8080/api/getPlainValue/11131"
r = requests.get(cmd)
if r.content.decode() == "true":
cmd="http://apache:8080/api/set/11131/?value=0"
r = requests.get(cmd)
else:
cmd="http://apache:8080/api/set/11131/?value=1"
r = requests.get(cmd)
gefäät mir schon besser.
Danke für Eure Hilfe.
Re: wget ausgabe in Variable??
Verfasst: Samstag 2. Mai 2020, 17:00
von nezzcarth
Mal als Proof-of-Concept:
Code: Alles auswählen
#!/usr/bin/env python3
import os
import tempfile
import subprocess
import pathlib
import shutil
WGET_PATH = shutil.which('wget')
def download_file(url, fifo_name='fifo', wget_path=WGET_PATH):
if wget_path is None:
raise RuntimeError('No wget path.')
result = None
with tempfile.TemporaryDirectory() as directory:
fifo = pathlib.Path(directory) / fifo_name
os.mkfifo(fifo)
with subprocess.Popen([wget_path, url, '-O', fifo]) as process:
with fifo.open('r') as fh:
result = fh.read()
return result
def main():
file = download_file('http://127.0.0.1/largefile')
print(len(file))
if __name__ == '__main__':
main()
Das müsste man natürlich noch deutlich robuster machen, wenn man das verwenden wollen würde (was man eh nicht wollen würde

). Ich wollte nur mal wissen, ob das prinzipiell wirklich klappen würde.
Re: wget ausgabe in Variable??
Verfasst: Samstag 2. Mai 2020, 17:24
von Sirius3
Eingerückt wird immer mit 4 Leerzeichen pro Ebene nicht 5.
HTTP-Antworten haben ihr eigenes Encoding, das response.text auch berücksichtigt. Mit dem Default-Encoding von Python den Text zu decodieren ist also falsch.
Wie ich schon geschrieben hatte, sind der if-Block und der else-Block fast identisch, sollten also gar nicht existieren.
Statt drei mal die fast selbe URL im Code stehen zu haben, sollte man diese auch einmal als Konstante definieren.
Benutze keine Abkürzungen. Was soll den ARb sein? r ist ein response. Womöglich gar json-codiert?
Code: Alles auswählen
API_URL = "http://apache:8080/api"
def toggle_ARb(value_id=11131):
cmd = "getPlainValue/11131"
response = requests.get(f"{API_URL}/getPlainValue/{value_id}")
new_value = 0 if response.json() else 1
# oder doch response.text == "true"?
response = requests.get(f"{API_URL}/set/{value_id}", params={"value": new_value})
response.raise_for_status()
Re: wget ausgabe in Variable??
Verfasst: Freitag 12. Juni 2020, 22:40
von __blackjack__
@joerg-harrer: Der Bash-Quelltext sieht ziemlich wüst aus was die Einrückung angeht.
Das sieht auch falsch aus denn im Skript steht bereits ``wget`` in `$cmd` steht es dann aber *noch mal*. Und damit ist es auch nicht mehr wirklich ein `$cmd` sondern eher eine `$url`.
Für das ``if``/``else`` gilt das gleiche was Sirius3 für das erste Python-Programm gesagt hat: Die unterscheiden sich nur durch ein einzelnes Zeichen.
Sähe dann eher so aus:
Code: Alles auswählen
readonly API_URL='http://apache:8080/api'
readonly SOME_MAGIC_NUMBER='11131'
if [[ "$(wget -q -O - "$API_URL/getPlainValue/$SOME_MAGIC_NUMBER")" == 'true' ]]; then
value=0
else
value=1
fi
x=$(wget -q -O - "$API_URL/set/$SOME_MAGIC_NUMBER/?value=$value") 2&> /dev/null