Seite 1 von 1

[gelöst?] Neuling mit Konzeptfrage

Verfasst: Mittwoch 20. Dezember 2006, 00:50
von Sanji
Hallo,

ich habe in den letzten Jahren einige Websites in PHP aufgebaut und möchte jetzt meine eigene Seite auf Python umstellen. Da ich eine Abscheu vor externen Template-Systemen oder solchen aufgeblähten Konstruktionen, möchte ich diese auch nicht einsetzen.

Mein großes Problem ist die Verteilung meiner Scripts auf mehrere Dateien. Bei meinem Hoster läuft mod_python mit Python 2.4.3. Soweit ich mich belesen habe, werden ja quasi alle .py-Anfragen zum PythonHandler weitergeleitet, der die Anfrage dann behandelt.

In dieser Datei (nennen wir sie mal handler.py) dachte ich mir jetzt, dass ich schaue, welche Datei eigentlich aufgerufen wurde (sagen wir mal index.py) und diese dann einbinde, um sie auszuführen. Leider hat keiner der hier geposteten Lösungen (__import__, eval("import...")) funktioniert. Dummerweise läuft der Python Interpreter im PythonRoot und findet daher nicht so einfach meine Scripts in meinem DocumentRoot.

Was kann ich denn tun, um in meiner handler.py die "index.py" aus dem gleichen Verzeichnis, in dem auch die handler.py liegt, einzubinden und auszuführen?

Grüße,
Christoph

Verfasst: Mittwoch 20. Dezember 2006, 03:39
von EnTeQuAk
Wenn deine Scripte mit mod_python ausgeführt werden und nicht im System-Pfad - also z.B. in den site-pakages liegen musst du die Option

Code: Alles auswählen

PythonPath "['pfad/zum/script'] + sys,path"
.

Ich habe deine Frage zwar nicht ganz verstanden aber eins kann ich dir sagen. Wenn du Scripte mit mod_python ausführen möchtest benötigst du einen mod_python handler oder ein mod_python GateWay - was was ist.... da suche ich noch --

Als Beispiel sei mal http://trac.pocoo.org/repos/modpywsgi/modpywsgi.py
erwähnt.
Dieses binde ich bei mir in folgender Apache-Config ( httpd.conf )ein:

Code: Alles auswählen

        <Location />
                AddHandler mod_python .py
                PythonHandler modpywsgi::handler
                PythonAutoReload On
                PythonPath "['/home/ente/entes-world'] + sys.path"
                PythonOption application index::app
                PythonDebug On
        </Location>
Solltest du keinen Zugriff auf die httpd.conf haben dann sollte es reichen die Einstellungen in eine .htaccess reinzuschreiben.

MfG EnTeQuAk

Verfasst: Mittwoch 20. Dezember 2006, 10:49
von Sanji
Mein Problem ist ja, dass alle Anfragen auf .py-Dateien zum Handler geleitet werden. Und der soll jetzt entscheiden, welche Datei denn eigentlich angefordert wurde (über req.filename) und diese dann einbinden, um sie auszuführen. Aber ich schaffe es nicht, Dateien in meinem docroot einbinden zu lassen. Ich habe folgenden Code:

Code: Alles auswählen

##############################
# handler.py - mein PythonHandler

from mod_python import apache
import os, sys

ROOT_DIR = "G:\\docroot\\example.com\\wwwpy"

def handler(req):
	req.content_type = "text/plain"
	req.send_http_header()
	req.write(os.path.basename(req.filename)+" wurde aufgerufen.\n\n")
	from bob import bobfunc
	
	bobfunc(req,5)
	
	return apache.OK

##############################
# bob.py im DocumentRoot (dort, wo auch die handler.py liegt)

# -*- coding: iso-8859-15 -*-

def bobfunc(req,n):
	req.write("foo "+n)
Und zusätzlich in der .htaccess im DocumentRoot:

Code: Alles auswählen

PythonPath "['G:\\docroot\\example.com\\wwwpy'] + sys.path"
Bei einem Aufruf von http://localpy/bob.py (localpy ist ein virtueller Host auf 127.0.0.1) erhalte ich dann im Browser die Ausgabe:
bob.py wurde aufgerufen.


<pre>
Mod_python error: "PythonHandler handler"

Traceback (most recent call last):

File "G:\Software\Python-2.4.4\Lib\site-packages\mod_python\apache.py", line 299, in HandlerDispatch
result = object(req)

File "G:\docroot\example.com\wwwpy\handler.py", line 10, in handler
from bob import bobfunc

ImportError: cannot import name bobfunc

</pre>

Re: Neuling mit Konzeptfrage

Verfasst: Mittwoch 20. Dezember 2006, 11:25
von jens
Sanji hat geschrieben:Da ich eine Abscheu vor externen Template-Systemen oder solchen aufgeblähten Konstruktionen, möchte ich diese auch nicht einsetzen.
Also ich kann dir nur jinja empfehlen. Ist eine wirklich einfache schlanke Template-Sprache: http://wsgiarea.pocoo.org/jinja/

Verfasst: Mittwoch 20. Dezember 2006, 11:27
von EnTeQuAk
Ach ja...

@ Sanji:

Sorry hier bin ich auch gerade am basteln... ich probiere zwar erstmal andere Handler aus... aber so richtig will das alles nicht.

Daher werde ich mir für PyLucid wohl oder übel auch einen basteln müssen,.,.. *grml*

Nun ja... solltest du da etwas schönes hinbekommen :) Bin ich immer erfreut :)

MfG EnTeQuAk

Verfasst: Mittwoch 20. Dezember 2006, 15:46
von Sanji
Also ich habe jetzt noch ein wenig rumprobiert und die einzige Lösung, die ich gefunden habe, ist, das gewünschte Script von der handler.py per execfile() ausführen zu lassen. Die Datei, die dann ausgeführt wird (bei mir bob.py) hat dann "global" das ApacheRequest-Objekt und dann damit ganz normal agieren.

Stellt sich mir nur die Frage, ob das Performance-Probleme geben könnte.

Verfasst: Mittwoch 20. Dezember 2006, 16:13
von Sanji
Also meine handler.py sieht jetzt so aus:

Code: Alles auswählen

# -*- coding: iso-8859-1 -*-

from mod_python import apache
import os, sys

ROOT_DIR = "G:\\docroot\\example.com\\wwwpy\\" #der DocRoot

def handler(req):
	req.content_type = "text/html"
	req.send_http_header()
	
	file = os.path.basename(req.filename)
	
	if not os.path.exists(ROOT_DIR+file) or file == "handler.py":
		req.status = apache.HTTP_NOT_FOUND
		req.write("Oh, das ging schief (404).")
		return apache.OK
	
	execfile(ROOT_DIR+os.path.basename(req.filename))
	
	return apache.OK
Der Handler rendert seine eigene 404-Seite, wenn eine nicht existente Datei oder der Handler selbst aufgerufen wurde. Ansonsten führt es die Datei aus, die aufgerufen wurde (req.filename). Läuft wunderbar. :) Dann kann ich mich jetzt daran machen, im Laufe der nächsten 12 Monate meine ganze Website langsam umzucoden.

Edit (Leonidas): Highlighting eingeschaltet.

Verfasst: Mittwoch 20. Dezember 2006, 16:16
von jens