Welches Framework?

Sockets, TCP/IP, (XML-)RPC und ähnliche Themen gehören in dieses Forum
Antworten
Jan.O
User
Beiträge: 61
Registriert: Samstag 26. April 2008, 00:32

Dienstag 28. Oktober 2008, 16:10

Hi,

Ich brauche einen Server in Python, welcher simple antworten auf HTTP-Anfragen geben kann. Der Server soll vorrangig variablen, die per HTTP-Request gesetzt wurden, per HTTP-Request ausgeben. zB Sollte der aufruf von http://www.example.de/zutaten?rezept=kuchen
"milch|eier|mehl"
ausgeben können, wenn vorher
http://www.example.de/setZutaten?rezept ... |eier|mehl
aufgerufen wurde (quasi ne DB).

Ich brauche keine templatesystem etc! Der server sollte einfach nur schnell sein, session-variablen etc. speichern können und strings ausgeben können!


Vielen dank!

Jan
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Dienstag 28. Oktober 2008, 17:23

Hallo Jan.O!

Mit CherryPy http://cherrypy.org/ könnte das z.B. so aussehen:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import cherrypy

rezepte = {}

class Root(object):
    
    def set_zutaten(self, rezept, zutaten):
        rezepte[rezept] = zutaten
        cherrypy.response.headers['Content-Type'] = "text/plain" # Standard wäre HTML
        return "Rezept angenommen"
    set_zutaten.exposed = True
    
    def get_zutaten(self, rezept):
        cherrypy.response.headers['Content-Type'] = "text/plain"
        return rezepte.get(rezept, "Not Found")
    get_zutaten.exposed = True

def main():
    cherrypy.quickstart(Root())

if __name__ == "__main__":
    main()
Dieser Aufruf fügt das Rezept hinzu:

Code: Alles auswählen

http://localhost:8080/set_zutaten?rezept=bier&zutaten=hopfen|malz|wasser
Und dieser Aufruf ruft es wieder ab (als Text):

Code: Alles auswählen

http://localhost:8080/get_zutaten?rezept=bier
mfg
Gerold
:-)

PS: Das mit den "Sessionvariablen" kann CherryPy natürlich auch. Siehe: http://cherrypy.org/wiki/CherryPySessions

.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Jan.O
User
Beiträge: 61
Registriert: Samstag 26. April 2008, 00:32

Dienstag 28. Oktober 2008, 17:46

Super! Echt vielen dank, hat mir sehr geholfen.
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Dienstag 28. Oktober 2008, 17:49

Wenn's weniger full-blown sein soll: Werkzeug. Da den Request-Wrapper und das Contrib-Sessions-Modul ansehen.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Dienstag 28. Oktober 2008, 22:23

Hallo Jan.O!

Wenn, dann soll man es gleich g'scheid vorzeigen. :roll:
Beim Zugriff auf ein Dictionary ist das noch kein Problem. Aber wahrscheinlich bleibt es bei dir nicht dabei. Und dann sollte man wissen, dass CherryPy die Requests in mehreren Threads beantwortet. Der Zugriff auf die Daten sollte daher "threadsicher" sein.

Deshalb habe ich zur Demonstration einen Lock eingebaut:
http://paste.pocoo.org/show/89351/

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Jan.O
User
Beiträge: 61
Registriert: Samstag 26. April 2008, 00:32

Dienstag 28. Oktober 2008, 22:35

Danke noch mal gerold, bist echt ein super typ :D!
Hab mich schon gefragt, wie CherryPy mit threads umgeht, jetzt weiß ichs. Werde jetzt cherryPy benutzen.

thx
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Dienstag 28. Oktober 2008, 23:13

Jan.O hat geschrieben:Danke noch mal gerold, bist echt ein super typ :D! [...] Werde jetzt cherryPy benutzen.
Ahm, ja, äh :oops: :-) -- dann könnte dich vielleicht noch das hier http://halvar.at/python/cherrypy_cheetah/ interessieren. Die Kapitel über Cheetah kannst du ja überspringen.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Mittwoch 29. Oktober 2008, 09:29

gerold hat geschrieben:Deshalb habe ich zur Demonstration einen Lock eingebaut:
Was mir da auffiel: Ein "shared read lock" würde an dieser Stelle aber reichen, denn jetzt sperrt jeder Lesezugriff alle anderen lesenden Zugriffe aus. Kennt Python das auch oder müsste man sich das selbst bauen?

Wäre es nicht auch besser, Lock und "Datenspeicher" in die Klasse "Root" zu verlagern? Wozu sind das globale Variablen?

Stefan
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 29. Oktober 2008, 10:10

Hallo Stefan!
sma hat geschrieben:Ein "shared read lock" würde an dieser Stelle aber reichen
Würde reichen! Wie man so etwas mit Python umsetzen würde, weiß ich aber nicht. Normalerweise vertraue ich auf das Datenbanksystem, welches im Hintergrund werkelt.
sma hat geschrieben:Wäre es nicht auch besser, Lock und "Datenspeicher" in die Klasse "Root" zu verlagern?
Das war Absicht. In CherryPy stellt die Root-Klasse normalerweise die URL "http://localhost:8080/" dar. Man kann weitere Klassen erstellen, die für die "Unterordner" zuständig sind. Die Root-Klasse ist also eine (angedeutete) Kommunikationsschnittstelle. Die Datenhaltung sollte also, meiner Meinung nach, nicht dort stattfinden.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Mittwoch 29. Oktober 2008, 10:46

Ich finde interessant, wie konsequent CherryPy Objekte und deren Methoden mit URLs verknüpft. Statt aber Exemplare von Klassen, die "Unterordner" beschreiben zusammenhangslos als Klassenattribute zu definieren, fände ich so etwas besser:

Code: Alles auswählen

class A:
  def __init__(self, parent):
    self.parent = parent

  @expose
  def index(self): ...

class B:
  def __init__(self):
    self.subfolder = A(self)

  @expose
  def index(self): ...
Dann hängt alles zusammen und ich brauche keine globalen Variablen. Das hier konstruktive Zusammenstecken kann man denke ich auch in eine eigene Oberklasse auslagern. Ein bisschen komisch finde ich, dass man offenbar nichts "default" nennen darf, weil das das Äquivalent zu "__getattr__" ist. Da hätte ich mir eine "__"-Methode gewünscht.

Stefan
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 29. Oktober 2008, 10:54

sma hat geschrieben:keine globalen Variablen
Hallo Stefan!

Warum reitest du auf dieser Variable herum? Die war ja nur als "Platzhalter" für die Datenhaltung gedacht.

mfg
Gerold
:-)

PS: Zum Ausprobieren: http://paste.pocoo.org/show/89388/

.
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Mittwoch 29. Oktober 2008, 13:37

Beispiel mit Datenbankzugriff: http://paste.pocoo.org/show/89400/
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Jan.O
User
Beiträge: 61
Registriert: Samstag 26. April 2008, 00:32

Freitag 31. Oktober 2008, 00:12

Wow, ich kann mich nur wiederholen: Einfach klasse. Vielen Dank für die guten Beispiele, Gerold! Und danke auch an die Anderen!

@ sma: So wie du dir das bei CherryPy wünscht, funktioniert es auch tatsächlich ^^ (es ist einer der wege). Man muss aber nicht die parent-klasse übergeben.


Jan
Antworten