7
votes

Streamez un fichier à la réponse HTTP dans les pylônes

J'ai une action de contrôleur de pylônes qui doit renvoyer un fichier au client. (Le fichier est en dehors de la racine Web, donc je ne peux donc pas simplement en lier directement.) Le moyen le plus simple est, bien sûr, ceci: xxx

qui fonctionne, mais il est évidemment inefficace pour grands fichiers. Quelle est la meilleure façon de faire cela? Je n'ai pas été en mesure de trouver des méthodes pratiques dans les pylônes pour diffuser le contenu du fichier. Dois-je vraiment écrire le code pour lire un morceau à un moment moi-même de zéro?


2 commentaires

Pour servir des fichiers, assurez-vous de les ouvrir dans le mode RB , de sorte que vous ne recevez pas de résultats mutilés en cours d'exécution sur un serveur Windows.


Bon point, Bobince - changé à 'RB'


3 Réponses :


8
votes

L'outil correct à utiliser est shuttil.copyfileobj, qui se copie d'un à l'autre un morceau à la fois.

Exemple d'utilisation: P>

import shutil
with open(filepath, 'r') as f:
    shutil.copyfileobj(f, response)


1 commentaires

Eh bien, cela semblait travailler, mais je l'ai essayé avec un fichier de 2 Go récemment et j'ai découvert qu'il a toujours pris très longtemps pour rentrer de quoi que ce soit et que l'utilisation de la mémoire du processus soit allée à 2,5 Go. Il semble donc que la réponse des pylônes tamponne toujours l'ensemble du fichier.



1
votes

La clé ici est que le WSGI et les pylônes par extension fonctionnent avec des réponses iTables. Vous devriez donc être capable d'écrire du code comme (avertissement, code non testé ci-dessous!): xxx

aussi, paste.fileApp.fileapp est conçu pour pouvoir être capable de Renvoie les données de fichier pour vous, vous pouvez également essayer: xxx

dans la méthode de votre contrôleur.


3 commentaires

Désolé, cela n'aide pas. La méthode file_streamer renvoie les données, mais tout est toujours tamponné. Lorsque j'essaie de retourner fileappath (fichier) i get "TypeError:" l'objet FileApp "n'est pas démonérable"


Ah, on dirait que cela a juste besoin d'un peu plus de code que cela, mais essentiellement FileApp ce que je veux. Je posterai la réponse complète séparément. Merci! +1


retour de l'avant (Fileappath))



4
votes

Je l'ai enfin obligé de travailler à l'aide de la classe FileApp , grâce à Chris Atlee et THC4K (de Cette réponse ). Cette méthode m'a également permis de définir l'en-tête de longueur de contenu, Quelque chose de pylônes a Beaucoup de problèmes avec , qui permet au navigateur de montrer une estimation du temps restant.

Voici le code complet: xxx


0 commentaires