Module aus dem Internet importieren

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
Spontifixus
User
Beiträge: 9
Registriert: Donnerstag 3. August 2006, 12:33

Moin zusammen,

Die Situation ist die Folgende. Ich erstelle im Rahmen meiner Diplomarbeit eine Datenbank, auf die über zwei verschiedene Wege zugegriffen werden soll. Weg Nummer Eins: Ein Webinterface, Weg Nummer Zwei eine auf dem Rechner des Benutzers laufende lokale Python-Anwendung.
Zur Verarbeitung der Daten möchte ich bestimmte Klassen definieren, die anschließend von den jeweiligen Anwendungen (Webinterface und lokale Anwendung) instanziiert werden sollen (Stichwort MVC).

Problem dabei: Ist es möglich aus der lokalen Anwendung heraus ein Pythonmodul zu laden, dass auf einem Webserver liegt?

Eine Idee wäre es, das Modul herunterzuladen und es dann zu importieren, allerdings hat der Benutzer nicht gezwungenermaßen Schreibrechte auf das Verzeichnis wo die Anwendung später liegt.

Gibt es noch andere Möglichkeiten um ein Modul aus dem Internet zu laden?

Viele Grüße,
Markus :)
Y0Gi
User
Beiträge: 1454
Registriert: Freitag 22. September 2006, 23:05
Wohnort: ja

Meines Wissens geht das nicht, und das ist auch gut so *an Code-Injection bei PHP denk*. Du könntest natürlich den Server den Quelltext des Moduls als Plaintext ausliefern lassen, den vom lokalen Client in eine Datei speichern und dann laden lassen - da rate ich aber energisch von ab.

Solltest du nicht besser einen Webservice verwenden?
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Spontifixus hat geschrieben:Ich erstelle im Rahmen meiner Diplomarbeit eine Datenbank, auf die über zwei verschiedene Wege zugegriffen werden soll. Weg Nummer Eins: Ein Webinterface, Weg Nummer Zwei eine auf dem Rechner des Benutzers laufende lokale Python-Anwendung.
[...]
Zur Verarbeitung der Daten möchte ich bestimmte Klassen definieren, die anschließend von den jeweiligen Anwendungen (Webinterface und lokale Anwendung) instanziiert werden sollen (Stichwort MVC).
Hallo Markus!

Code: Alles auswählen

            Datenbank
                |
            Middleware
                |
       -------------------
      |                   |
 Webinterface   Lokales Python-Programm
Was will ich damit sagen? Mach einzelne Programme daraus und nicht ein ganzes Programm.
Die Datenbank kümmert sich um die Datenhaltung.
Die Middleware greift direkt auf die Datenbank zu und kümmert sich darum, dass die Clients eine vereinfachte Schnittstelle zur Datenbank haben.
Die Clients richten ihre Anfragen an die Middleware, die die Daten aus der Db holt und weiter gibt.
Einfachste Kommunikation zwischen den Clients und der Middleware --> XMLRPC, das in Python sehr gut implementiert wurde.

Für das Webinterface eignet sich jedes Web-Framework oder sogar CGI. Ich schlage dir CherryPy vor. Und für das GUI-Programm wxPython.

EDIT:

Eine Middleware hat allerdings auch seine Nachteile. Eine Middleware kann ziemlich schnell aus allen Nähten platzen. Mir persönlich ist schon passiert, dass die Middleware so umfangreich wurde, dass es inzwischen einfacher ist, direkt auf die Datenbank zuzugreifen, als für jede Kleinigkeit über die Middleware zu gehen. Man muss sich als Programmierer stark zurück halten, um doch über die Middleware zu gehen. Außerdem hat jedes gute Datenbanksystem eine Benutzer- und Rechteverwaltung eingebaut. Wenn du über eine Middleware gehst, dann musst du dich selber darum kümmern. Auch um die Lastverteilung. Connectionpooling usw.

Als Alternative kann man die Funktionen der Middleware direkt in die Datenbank verlegen. Das hat fast nur Vorteile. Eine gute Datenbank, wie z.B. PostgreSQL kann sogar direkt mit Python programmiert werden. Die Rechte können granular auf einzelne Objekte verteilt werden. Usw.

mfg
Gerold
:-)

PS: http://www.postgresql.org/docs/8.2/static/plpython.html
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Spontifixus
User
Beiträge: 9
Registriert: Donnerstag 3. August 2006, 12:33

Moin!

Vielen Dank für die Antworten!
gerold hat geschrieben:

Code: Alles auswählen

            Datenbank
                |
            Middleware
                |
       -------------------
      |                   |
 Webinterface   Lokales Python-Programm
Was will ich damit sagen? Mach einzelne Programme daraus und nicht ein ganzes Programm.
Die Datenbank kümmert sich um die Datenhaltung.
Die Middleware greift direkt auf die Datenbank zu und kümmert sich darum, dass die Clients eine vereinfachte Schnittstelle zur Datenbank haben.
Die Clients richten ihre Anfragen an die Middleware, die die Daten aus der Db holt und weiter gibt.
Genau das meinte ich mit MVC (Model View Control) - nur auf XMLRPC war ich bislang nicht gekommen.

Mir ist allerdings inzwischen aufgefallen, dass ein solcher Klimmzug wohl gar nicht nötig sein wird. Die Lokale Anwendung wird per SVN verteilt, da kann ich die entsprechenden Module auch gleich mit ausliefern...

Gruß,
Markus :)
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

Prinzipiell kann man natürlich schon einen Import-Hook schreiben, der Module bei Bedarf aus dem lädt und importiert... (löst zwar das OP-Problem nicht, ist aber ein schönes Beispiel für Import-Hooks)

Das ganze würde dann so ungefähr funktionieren:

Code: Alles auswählen

import sys, new, urllib, posixpath

class UrlHook:
    def __init__(self, path):
        if not path.startswith('http://'):
            # der Hook ist nicht zustaendig
            raise ImportError
        self.path = path

    def find_module(self, fullname):
        if "." in fullname:
            # Vorerst keine Packages...
            return None
        return self

    def load_module(self, fullname):
        url = posixpath.join(self.path, fullname+'.py')
        f = urllib.urlopen(url)
        try:
            code = f.read()
            # Neues Modulobjekt erstellen und den Code
            # darin ausfuehren
            mod = new.module(fullname)
            sys.modules.setdefault(fullname, mod)
            mod.__file__ = url
            mod.__loader__ = self
            exec code in mod.__dict__
            return mod
        finally:
            f.close()


# den Hook fuer jeden Eintrag in sys.path aufrufen
sys.path_hooks.append(UrlHook)
# Beispielpfad
sys.path.append('http://pydoc.gbrandl.de/')
# Modul von dieser URL importieren
import webmod
Vorsicht: wer mir nicht traut, sollte den Code nicht bei sich ausführen, oder zumindest vorher http://pydoc.gbrandl.de/webmod.py herunterladen und sich vergewissern, dass nichts schädliches darinsteht ;)
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
Whitie
User
Beiträge: 216
Registriert: Sonntag 4. Juni 2006, 12:39
Wohnort: Schulzendorf

Hallo Spontifixius,
Du könntest die Kommunikation auch über Pyro (Python Remote Objects) abwickeln. Da gibt es eine Option (mobile code), die aktiviert werden kann und bei Bedarf benötigte Module zum Client überträgt.
Ich hab leider keine Beispiele zur Hand, war aber damals recht einfach als ich es benutzt habe.

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

birkenfeld hat geschrieben:Prinzipiell kann man natürlich schon einen Import-Hook schreiben, der Module bei Bedarf aus dem lädt und importiert... (löst zwar das OP-Problem nicht, ist aber ein schönes Beispiel für Import-Hooks)
Hallo birkenfeld!

Damit hast du mich völlig überrascht. :D Ich hatte noch nie vorher etwas von "path_hooks" gehört. Wieder etwas, was die Erweiterbarkeit von Python demonstriert.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

gerold hat geschrieben: Damit hast du mich völlig überrascht. :D Ich hatte noch nie vorher etwas von "path_hooks" gehört.
Evtl. hast du sie aber schon benutzt; der zipimporter ist nämlich genau so ein Hook :)
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Der ganze UrlHook erinnert von der Funktionalität etwas an den aus PLT Scheme bekannten PLaneT. Dort ist es auch Möglich zur Laufzeit Module runterzuladen und zu importieren. Allerdings werden dort die Module dann abgespeichert, aber das ist bei birkenfelds Code auch sehr einfach nachzurüsten.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Spontifixus
User
Beiträge: 9
Registriert: Donnerstag 3. August 2006, 12:33

Moin,

nochmals vielen Dank für die vielen Antworten.

Ich habe mich für die erstgenannte Methode (XML-RPC) entschieden. Ich hatte schon einen Teil des Control-Layers in PHP umgesetzt, so dass ich mir die erneute Implementierung desselben in Python sparen kann.

Folgende Komponenten verwende ich:

Auf seiten PHP (der XML-RPC-Server) verwende ich PHPXMLRPC, auf Seiten Python kommt die xmlrpclib zum Einsatz.

Viele Grüße,
Markus :)
Antworten