Seite 1 von 1
py Project mit web.py
Verfasst: Mittwoch 29. Oktober 2014, 17:11
von gNeandr
Zwischenzeitlich läuft mein Projekt recht gut auch Danke der Hilfe in diesem Thread:
http://www.python-forum.de/viewtopic.php?t=33895
Die bisherige Version wird als Python Funktion per Konsole gestartet und gibt den jeweiligen Status der Daten auch auf der Konsole aus.
Das soll auch so bleiben. Allerdings möchte ich einen Zugang per Browser/Mobilem Gerät haben.
Mir scheint
http://webpy.org/ ist ein geeignetes Tool hierfür.
Mein Problem, zwar kann ich 'web' einbinden, aber eine entsprechende class hat keinen Zugriff auf die Parameter der eigentlichen Anwendung. (Es wird / und soll keine Datenbank verwendet werden).
Welche Beschreibung ist notwendig, damit ihr mir auf die Sprünge helfen könnt?
(... und bitte keine Häme von wegen globale Parameter)
Re: py Project mit web.py
Verfasst: Mittwoch 29. Oktober 2014, 17:27
von Sirius3
@gNeandr: diese Url- und Klassendefinitionen von webpy sehen mir etwas verworren aus. Ich würde Dir flask oder bottle empfehlen.
Dein Problem verstehe ich nicht ganz. Wenn ein Skript hast, das Deine Methoden per Konsole zugänglich macht, mußt Du doch einfach nur diese Aufrufe über Urls verfügbar machen. Also wenn das Konsolen-Skript Zugriff hat, warum dann das Web-Interface nicht?
Re: py Project mit web.py
Verfasst: Mittwoch 29. Oktober 2014, 17:44
von gNeandr
Sirius3 hat geschrieben:@gNeandr: diese Url- und Klassendefinitionen von webpy sehen mir etwas verworren aus. Ich würde Dir flask oder bottle empfehlen.
Dein Problem verstehe ich nicht ganz. Wenn ein Skript hast, das Deine Methoden per Konsole zugänglich macht, mußt Du doch einfach nur diese Aufrufe über Urls verfügbar machen. Also wenn das Konsolen-Skript Zugriff hat, warum dann das Web-Interface nicht?
Zu web.py etc .. web.py schien mir recht plausibel und einfach, wohl deshalb habe ich mir flask und bottle nicht angesehen .. werd's nachholen.
Mein Skript enthält einen Hauptthread und zwei weitere jobs, die
1\ die Daten erzeugen/auf der Konsole ausgeben (mittels Threads und event handling zur Beendigung)
2\ auf weitere Befehlsdaten (derzeit) über Konsoleeingaben mittels eines anderen Skripts warten (Listener)
Das Web-Interface soll auf die mittels 1\ erzeugten Daten zugreifen und anzeigen
Re: py Project mit web.py
Verfasst: Mittwoch 29. Oktober 2014, 19:04
von gNeandr
Hier die Struktur meines Skripts mit dem derzeitigen web.py Ansatz ... der leider insofern nicht funktioniert, als ich keinen Zugriff auf die Daten
jobs = [] # store scheduled tasks bekomme:
Code: Alles auswählen
#!/usr/bin/env python
# import part
# globals
__version__ = '0.1g'
sched = BackgroundScheduler()
jobs = [] # store scheduled tasks
def jobs_listing(exit_event, name, calling):
try:
while not exit_event.is_set(): # loop to keep scheduler alive
updateJobsListing() # updating 'jobs', ..
sleep(10) # this runs every 10 sec
finally:
print (' piScheduler - Exit >{0}<'.format(name))
def job_serve(exit_event, name):
try:
while True:
# doing stuff and
# waiting for condition to leave try using 'break'
break
except:
pass
finally:
# closing part
exit_event.set()
listener.close()
sched.shutdown()
sys.exit(0)
# for web.py
urls = (
'/', 'index'
)
# for web.py
class index:
def GET(self, globals()):
x = ("hello this is RPI on .16\n")
x1 = __version__ + " " + str(datetime.datetime.now())[:19]
# >>>>>> no access to changed values like 'jobs' <<<<<<
return x + x1
def main():
# initializing with parameter
sched.start() # start the scheduler
exit_event = Event() # define an event to allow keyboard interrupt and other
Thread(target=jobs_listing, args=(exit_event, 'pilight Jobs', calling)).start()
# use web.py to get the scheduler data on a web page
app = web.application(urls, globals())
app.run()
# a routine to read the schedule data, update 'jobs'
# and kick the RPI functions
job_serve(exit_event, 'piScheduler')
# close down after exit_event was set true
sched.shutdown()
exit()
#---------------------------------
if __name__ == "__main__":
main()
Mit der class index soll der aktuelle Stand von 'jobs' an die web-Seite übergeben werden. Siehe Zeile 45. Das klappt nicht.
Es werden nur Daten im Zustand vor dem Aufruf von app.run() angezeigt .. nicht was notwendig ist.
FMPOV ist es kein Problem von web.py mit app.run() sondern es liegt an der Gesamtstruktur. But here I'm struggeling

Re: py Project mit web.py
Verfasst: Mittwoch 29. Oktober 2014, 19:24
von BlackJack
@gNeandr: Natürlich liegt das an `app.run()` das Du nur Zustände hast die davor gesetzt wurden, denn ein *danach* gibt's nicht. Der `run()`-Aufruf kehrt nicht zurück, der `job_server()`-Aufruf wird nie ausgeführt.
Re: py Project mit web.py
Verfasst: Mittwoch 29. Oktober 2014, 20:38
von gNeandr
@BlackJack
Ja, so ist es .. und ein Test print Befehl zeigt es ja auch ganz klar .. klar wie Kloßbrühe
D.h hier sollte ich wohl einen zusätzlichen Thread haben und dort app.run() laufen lassen,
oder gibt's 'n andere / bessere Möglichkeit?
(Wie gesagt die web.py Eigenschaften oder deren Alternativen mal außen vor gelassen)
Re: py Project mit web.py
Verfasst: Donnerstag 30. Oktober 2014, 00:34
von gNeandr
Sirius3 hat geschrieben:
Dein Problem verstehe ich nicht ganz. Wenn ein Skript hast, das Deine Methoden per Konsole zugänglich macht, mußt Du doch einfach nur diese Aufrufe über Urls verfügbar machen. Also wenn das Konsolen-Skript Zugriff hat, warum dann das Web-Interface nicht?
Zurück auf null .. bzw zu deiner/dieser Frage, wahrscheinlich ist das der richtigere Weg! Zumal ich die Kommunikation mit einem zweiten Skript genauso mache. In meinem Post des Codes habe ich die Details von 'job_serve' ausgelassen. Da steht
Code: Alles auswählen
def job_serve(exit_event, name):
address = (192.168.178.xxx, 6001)
# listener = Listener(address, authkey='secret password')
listener = Listener(address')
try:
while True:
connection = listener.accept()
print (name, str(connection))
message = connection.recv().strip() <<<<<< error line
#
# process the incoming message...
#
print (' .... incoming msg: ', message)
except:
pass
finally:
# abgesang
Ein Konsole Script und folgenden Aufruf benutze ich um Steuerungsparameter bzw Befehle (in 'message') zu übertragen:
Code: Alles auswählen
address = (server, port)
conn = Client(address)
conn.send(message)
Das funktioniert einwandfrei ...
Allerdings verstehe ich nicht, wie ich per URL entsprechende Befehle absetzen kann, zB. '192.168.178.xxx:6001' gibt NUR einen Memory Fehler:
Code: Alles auswählen
xSchedule <read-write Connection, handle 6>
Traceback (most recent call last):
File "xSchedule.py", line 572, in <module>
main()
File "xSchedule.py", line 564, in main
job_serve(exit_event, 'xSchedule')
File "xSchedule.py", line 446, in job_serve
message = connection.recv().strip()
MemoryError
Note: den authkey in der Listener Definition habe ich bewusst (erst mal) weggelassen, hat aber keinen Einfluss auf den Mem-Fehler.
Was ist zu tun, um per Web Befehl zu arbeiten?
Re: py Project mit web.py
Verfasst: Donnerstag 30. Oktober 2014, 01:03
von BlackJack
@gNeandr: Vielleicht liegt's ja nur an mir oder an der vorgerückten Stunde, aber ich habe irgendwie keinen Überblick was da so gemacht wird und es sieht sehr komplex aus. Ein `MemoryError` bei einem `recv()` auf einem Socket (?) sieht komisch aus. Wobei man das eigentlich gar nicht ohne Argument aufrufen können dürfte‽
Re: py Project mit web.py
Verfasst: Donnerstag 30. Oktober 2014, 07:41
von Sirius3
@gNeandr: was hat connection für einen Typ? Und was ist ein Listener? Ein nacktes except das jede Exception einfach so ignoriert, ist immer schlecht. Woher hast Du dann überhaupt die Fehlermeldung?
Um Befehle zu verarbeiten verwende ich immer einen ganz normalen Web-Server, der per json kodierte Nachrichten bekommt und sendet. Da Du sowieso schon einen laufen hast, kannst Du den gleich mitbenutzen.
Re: py Project mit web.py
Verfasst: Donnerstag 30. Oktober 2014, 11:17
von gNeandr
@Sirius und @BlackJack und @Leonidas
Meine "Lösung" geht zurück auf einen Beitrag, den wir im Frühjahr diskutiert haben, siehe hier:
http://www.python-forum.de/posting.php? ... 1&p=258055
und wie gesagt, das läuft zur Zufriedenheit.
Es geht jetzt darum nicht nur Befehle zu übergeben wie mit einem separaten Script ala:
Code: Alles auswählen
if len(sys.argv) == 2:
message = sys.argv[1]
else:
message = 'pyClient : ' + str(datetime.datetime.now())
address = (server, 6001)
conn = Client(address, authkey='secret password')
conn.send(message)
conn.close()
Im Codeteil des og. Posts ist ab Zeile 21 'def server(..)' die das skizzierte Clientscript bedient.
Ich sollte doch diesen Teil nutzen können, um auch Aufrufe über eine Web-Seite zu bedienen. Allerdings tue ich mich da schwer.
Die Memory Err Meldung würde entsprechen dem zitierten Code an Zeile 27 kommen.
Re: py Project mit web.py
Verfasst: Donnerstag 30. Oktober 2014, 11:34
von BlackJack
@gNeandr: Wenn das an der Stelle einen `MemoryError` gibt versuchst Du entweder deutlich zu viele Daten zu empfangen, was aber unwahrscheinlich ist wenn man sich den Kommandozeilenclient anschaut, oder Du hast anderweitig ein Speicherleck und an der Stelle ist dann die Message einfach zu viel.
Wenn Dein Hauptprogramm sowieso auf einem Port oder einer Pipe auf Nachrichten lauscht, sollte es doch eigentlich trivial sein dem mit einer *externen* Webanwendung Nachrichten zukommen zu lassen. Ich würde dann nicht versuchen den Webserver mit in das Hauptprogramm zu basteln. Du kannst dann natürlich nicht direkt auf irgendwelche Interna vom Hauptprogramm zugreifen, aber das wäre IMHO sowieso ein wenig unsauber. Dafür könnte man Nachrichten und Antworten programmieren um diese Informationen abzufragen. Das könnte man dann auch von dem Kommandozeilenclient aus benutzen.
Re: py Project mit web.py
Verfasst: Donnerstag 30. Oktober 2014, 11:48
von gNeandr
@BlackJack Ja, den bestehenden Client zu nutzen (oder einen weiteren mit gleichartigem Code), daran hatte ich auch schon gedacht. Allerdings bin ich mir immer noch unsicher (siehe Mai Beiträge) wie das aufzubauen ist. Auf der Web-Seite brauchst dann wohl sowas wie ein Javascript Teil?
Ggf. hast du hierzu Pointer zum Nachlesen .. oder Beispiele? (Immer noch Neuling

)
Bzgl. eines ev. MemeoryLeaks .. wie kann ich das finden/reparieren?
Re: py Project mit web.py
Verfasst: Donnerstag 30. Oktober 2014, 12:07
von BlackJack
@gNeandr: Das würde mit einer Webanwendung im Grunde genau so aussehen, nur dass die `message` dann nicht von der Kommandozeile kommt, sondern über den Browser eingegeben wird. Also so grob skizziert mittels `bottle`:
Code: Alles auswählen
@route('/send_message', method='POST')
def send_message():
message = request.params['message']
if not message:
message = 'pyClient : {0}'.format(datetime.datetime.now())
address = (server, 6001)
conn = Client(address, authkey='secret password')
conn.send(message)
conn.close()
return {}
Die URL muss man per POST-Anfrage aufrufen und dort ein Parameter `message` mitgeben — das kann zum Beispiel aus einem <form> kommen — und man bekommt als Antwort ein leeres JSON-Objekt geliefert. Das heisst das eignet sich eher für Anfragen via Javascript, statt diese URL direkt als `action`-Attribut im <form> zu hinterlegen. *Dafür* wäre es besser wenn die Funktion mit einer HTML-Seite antworten würde, denn die meisten Benutzer können mit JSON-Antworten nicht viel anfangen.
Speicherlecks kann man versuchen mit einem Profiler aufzuspüren.
Die Fehlermeldung an der Stelle kommt mir allerdings komisch vor. Die würde da zum Beispiel kommen können wenn man ein DVD-Image oder etwas vergleichbar grosses über das `Connection`-Objekt versendet.
Re: py Project mit web.py
Verfasst: Donnerstag 30. Oktober 2014, 12:46
von gNeandr
@BlackJack
Danke für den web-Vorschlag, werd das mir mal später zu Gemüte führen.
Bzgl. MemoryError: Habe den RPI neu gestartet zumal ich etliche unsaubere Abbrüche hatte. Aber das hat nix gebracht
(wahrscheinlich nicht überraschend
)
Profiler == valgrind
... oder was empfiehlst du?
Re: py Project mit web.py
Verfasst: Donnerstag 30. Oktober 2014, 13:09
von BlackJack
@gNeandr: Nein ich meinte eher einen der Python kennt. Also zum Beispiel das `memory_profiler`-Modul aus dem Package-Index.
Re: py Project mit web.py
Verfasst: Donnerstag 30. Oktober 2014, 13:11
von gNeandr
@BlackJack
Danke ... damit ist mein Abend gerettet .. ohne TV oder so

Re: py Project mit web.py
Verfasst: Montag 3. November 2014, 19:15
von gNeandr
@BlackJack: Danke für den obigen Vorschlag:
... skizziert mittels `bottle`:
Code: Alles auswählen
@route('/send_message', method='POST')
def send_message():
message = request.params['message']
if not message:
message = 'pyClient : {0}'.format(datetime.datetime.now())
address = (server, 6001)
conn = Client(address, authkey='secret password')
conn.send(message)
conn.close()
return {}
Das klappt keine Frage, habe es auch mit conn.recv() erweitert und bekomme auch "einfache" Strings zurück.
Allerdings scheitere ich im Moment daran ein JSON zu übertragen.
Als Rückmeldung wandle ich JSON Daten mittels str(..) um was dann kein Problem beim Senden macht. Aber auf der Empfangsseite sollte ich wieder aus dem String JSON Daten machen, um damit vernünftig zu arbeiten.
Kannst mir da Hinwesie geben .. vllt. ist ja der Ansatz aus JSON mittels str(..) die Übertragung zu machen schon "schief"

Re: py Project mit web.py
Verfasst: Montag 3. November 2014, 19:22
von EyDu
Python hat ein json-Modul, das nimmt dir die ganze Arbeit ab. In diesem Fall brauchst du die loads- und die dumps-Methoden. Letztere solltest du, statt deines str-Aufrufs, zur Umwandlung in einen json-String verwenden.
Re: py Project mit web.py
Verfasst: Montag 3. November 2014, 20:47
von BlackJack
Wobei ich vorher schauen würde was das Webrahmenwerk bietet. Bottle macht das zum Beispiel automatisch wenn der Rückgabewert ein `dict` ist. Dann muss man sich eventuell auch nicht um so etwas wie die HTTP-Header kümmern die sagen das es sich um JSON und nicht um HTML handelt.