Hallo zusammen!
Ich habe ein filelike object (zipfile.ZipFile), das ich aus einer Pyhton Funktion zurück bekomme und müsste diese nun in einer HTML Seite als downoadlink bereitstellen. Hat jemand eine Idee wie man das machen kann?
Das ganze sieht folgendermaßen aus: Ich habe ein HTML Seite mit einem Formular (action = python funktion), das ich mit JS submitte und nun möchte ich das File, das mir die Python Funktion zurück gibt als downloadlink in die HTML Datei einbinden.
Ich hoffe mir kann wer helfen, bitte danke
LG Nina
Python return filelike object download
@nho: Das würde ja bedeuten Du würdest einen Link ausliefern der erst bei der *nächsten* Anfrage das Dateiobkekt ausliefert welches Du in der aktuellen Anfrage im Speicher erstellt hast. So funktioniert das für gewöhnlich nicht. Man würde normalerweise einen Link ausliefern über den das Dateiobjekt bei der Anfrage über diesen Link erst erzeugt und der Inhalt dann auch gleich als Antwort ausgeliefert wird.
Ansonsten müsste man den Inhalt irgendwie persistent machen über die Anfragen hinweg, also letztendlich irgendwo zwischenspeichern. Zum Beispiel auf dem Dateisystem, in einer Datenbank, oder vielleicht auch in einem Cache und in dem Link dann einen Namen, ID, oder Token in den Link einbauen über den man die Datei dann bei der Anfrage wieder identifizieren kann.
Ansonsten müsste man den Inhalt irgendwie persistent machen über die Anfragen hinweg, also letztendlich irgendwo zwischenspeichern. Zum Beispiel auf dem Dateisystem, in einer Datenbank, oder vielleicht auch in einem Cache und in dem Link dann einen Namen, ID, oder Token in den Link einbauen über den man die Datei dann bei der Anfrage wieder identifizieren kann.
ok das klingt logisch, was ich bisher habe:
das funktioniert soweit auch, es wird ein link in der html seite angezeigt, jedoch nicht der link zum file.. Ich verwende Zope!
lg
Code: Alles auswählen
sf = tempfile.NamedTemporaryFile("w+b", suffix=".zip", dir = "/mypath")
zf = zipfile.ZipFile(sf, "w", zipfile.ZIP_DEFLATED)
zf.write(...)
downloadlink = '<a href="zf">your file</a>'
REQUEST.RESPONSE.appendBody(downloadlink)
lg
@nho: Naja Du musst in den Link halt irgendetwas einbauen um die Datei bei einem späteren Aufruf wieder identifizieren zu können, zum Beispiel den Dateinamen oder zumindest einen variablen Teil davon der ausreicht um den Namen zu rekonstruieren.
`NamedTemporaryFile` ist da keine so gute Idee. Ich würde den Dateinamen selber generieren, dann hat man auch selber in der Hand wie sicher das ist gegen Angreifer die Versuchen den Dateinamen von solchen Dateien zu raten. Zum Beispiel auf Basis einer UUID, die man dann auch als Token in den Link einbauen kann.
Auf jeden Fall muss man die Datei am Ende des schreibens schliessen damit auch ganz sicher alle Daten rausgegeschrieben werden, und wenn Du bei `NamedTemporaryFile` bleibst, musst Du dem beim erstellen sagen, dass die Datei beim schliessen *nicht* gelöscht werden soll.
`NamedTemporaryFile` ist da keine so gute Idee. Ich würde den Dateinamen selber generieren, dann hat man auch selber in der Hand wie sicher das ist gegen Angreifer die Versuchen den Dateinamen von solchen Dateien zu raten. Zum Beispiel auf Basis einer UUID, die man dann auch als Token in den Link einbauen kann.
Auf jeden Fall muss man die Datei am Ende des schreibens schliessen damit auch ganz sicher alle Daten rausgegeschrieben werden, und wenn Du bei `NamedTemporaryFile` bleibst, musst Du dem beim erstellen sagen, dass die Datei beim schliessen *nicht* gelöscht werden soll.
ok ich habe der Datei jetzt eine ID zugewiesen bzw. kann man mit zf.filename auch auf den namen des zipfile zugreifen..
das eigentliche Problem ist, dass ich nicht weiß wie ich zwischen Python und JS interagieren kann.. gibt es eine möglichkeit, an der stelle wo ich das Form submitte (und durch die Action die Python Funktion aufgerufen wird), an den Returnwert der Funktion zu gelangen?
LG
das eigentliche Problem ist, dass ich nicht weiß wie ich zwischen Python und JS interagieren kann.. gibt es eine möglichkeit, an der stelle wo ich das Form submitte (und durch die Action die Python Funktion aufgerufen wird), an den Returnwert der Funktion zu gelangen?
LG
@nho: wenn Du dir Form submittest schickt ja Python eine Antwort zurück. In dieser Antwort mußt Du halt den Link auf die Datei mitschicken.
Wenn Du Dein Skript konkreter beschreibst, kann man vielleicht auch genauer antworten.
Wenn Du Dein Skript konkreter beschreibst, kann man vielleicht auch genauer antworten.
das ganze sieht folgendermaßen aus:
Ich habe eine html datei mit einem Formular:
diese Formular wird mit JS submitted:
dadurch wird eine Python Funktion aufgerufen:
dadurch öffnet sich automatisch der filedownload. Ich würde es aber bevorzugen, wenn ein Downloadlink in meine html datei eingebunden wird. Zum Beispiel über einen placeholder im html?
Gibt es da überhaupt eine Möglichkeit?
Ich habe eine html datei mit einem Formular:
Code: Alles auswählen
<form id="initexport" action="path/startExport" method="post">
<input type="hidden" id="dataformat" value="xml" name="dataformat">
</form>
Code: Alles auswählen
exportwindow.document.getElementById('initexport').submit();
Code: Alles auswählen
filetype = REQUEST.get('dataformat')
#erstelle eine Datei, schreibe den Inhalt hinhein und zip
REQUEST.RESPONSE.setHeader('content-type', 'application/zip')
REQUEST.RESPONSE.setHeader('content-disposition', 'attachment;filename="%s.zip"' % 'xmldatei')
REQUEST.RESPONSE.setHeader('content-length', xmlfilelen)
return REQUEST.RESPONSE
Gibt es da überhaupt eine Möglichkeit?
weil die export Datei erst erstellt werden muss, das geschieht in der Python Funktion. Dort wird ein temporäres File erstellt, mit den Daten befüllt und anschließend soll sie downloadbar sein.
Gibt es eine direkte Methode auf diese Funktion über JS zuzugreifen?
Gibt es eine direkte Methode auf diese Funktion über JS zuzugreifen?
@nho: Das ist keine Antwort auf die Frage. Natürlich muss die Datei vor dem herunterladen erzeugt werden, aber warum wird die nach dem erzeugen dann nicht einfach ausgeliefert anstatt da noch einen Zwischenschritt einzufügen der hauptsächlich Umstände bereitet. Welchen Vorteil bringt das?
@nho: Nein, Du erzeugst keinen Link, sondern baust den Link schon in die Seite ein, also statt der Form mit JavaScript einfach das:
Code: Alles auswählen
<a href='path/doExport?dataformat=xml'>XML exportieren</a>