J'essaie d'écrire une webapp vraiment simple avec PythonAnywhere et Flask qui a permis à l'utilisateur de télécharger un fichier texte, génère un fichier csv, puis permet à l'utilisateur de télécharger le fichier csv. Il ne fait pas '' t doivent être fantaisistes, cela ne peut que fonctionner. J'ai déjà écrit le programme pour générer le csv à partir d'un fichier txt sur le lecteur.
En ce moment, ma fonction ouvre le fichier sur le lecteur avec:
with open(INPUTFILE, "r") as fname:
et écrit le csv avec:
with open(OUTPUTFILE, 'w') as fname:
iNPUTFILE et OUTPUTFILE étant des chaînes de nom de fichier.
Serait-il préférable pour moi de gérer les fichiers comme des objets, retournés par le flacon/html d'une manière ou d'une autre?
Je ne sais pas comment faire ça. Comment dois-je structurer ce programme? De combien de modèles HTML ai-je besoin? Je préférerais travailler sur les fichiers sans les enregistrer n'importe où, mais si je dois les enregistrer dans le répertoire PythonAnywhere, je le pourrais. Comment puis je faire ça?
PythonAnywhere dev ici. C'est une bonne question sur Flask et le développement web en général plutôt que spécifique à notre système, donc je vais essayer de donner une réponse générique sans rien de spécifique pour nous :-)
Il y a quelques choses que je devrais savoir pour donner une réponse définitive à votre question, alors je commencerai par énumérer les hypothèses que je fais - laissez-moi un commentaire si je me trompe avec l'une d'entre elles et Je mettrai à jour la réponse en conséquence.
Si les deux sont le cas, alors la meilleure façon de structurer votre application Flask serait de tout gérer dans Flask. Un exemple de code vaut mille mots, alors voici un simple que j'ai mis ensemble, ce qui permet à l'utilisateur de télécharger un fichier texte, l'exécute via une fonction appelée transform
(qui est l'endroit où la fonction de votre programme de conversion serait inséré - le mien remplace simplement =
avec ,
tout au long du fichier) et renvoie les résultats au navigateur. Il existe une version live de cette application sur PythonAnywhere ici .
from flask import Flask, make_response, request
app = Flask(__name__)
def transform(text_file_contents):
return text_file_contents.replace("=", ",")
@app.route('/')
def form():
return """
<html>
<body>
<h1>Transform a file demo</h1>
<form action="/transform" method="post" enctype="multipart/form-data">
<input type="file" name="data_file" />
<input type="submit" />
</form>
</body>
</html>
"""
@app.route('/transform', methods=["POST"])
def transform_view():
request_file = request.files['data_file']
if not request_file:
return "No file"
file_contents = request_file.stream.read().decode("utf-8")
result = transform(file_contents)
response = make_response(result)
response.headers["Content-Disposition"] = "attachment; filename=result.csv"
return response
Concernant vos autres questions:
form
dans un modèle, mais c'est tout.save(
nom de fichier )
méthode sur l'objet file
dont j'utilise la propriété stream
. Mais si vos fichiers sont assez petits (selon mon hypothèse ci-dessus), il est probablement plus logique de les traiter en mémoire comme le fait le code ci-dessus.J'espère que tout aide, et si vous avez des questions, laissez simplement un commentaire.
Mieux vaut ajouter
response.headers["Cache-Control"] = "must-revalidate"
response.headers["Pragma"] = "must-revalidate"
response.headers["Content-type"] = "application/csv"
Si vous n'ajoutez pas le type de contenu, FF 48.0 l'a signalé en html et a ouvert la boîte de dialogue Enregistrer une fois pour HTML, puis pour CSV. Si vous n'ajoutez pas Cache-Control, votre résultat peut être mis en cache, et si vous diffusez du contenu actif, ce n'est pas ce que vous voulez. Si vous utilisez must-revalidate sans âge, il servira effectivement de no-cache - voir ici et ici pour une explication.