I am following Massimiliano Pippi's Python for Google App engine. In chapter 3, we are trying to upload a file that the user of my app select thanks to this html code:
<div class="form-group">
<label for="uploaded_file">Attached file:</label>
<input type="file" id="uploaded_file" name="uploaded_file">
</div>
And from the python part, in my MainHandler on webapp2, I get the request content using:
def post(self):
uploaded_file = self.request.POST.get("uploaded_file", None)
file_name = getattr(uploaded_file, 'filename')
file_content = getattr(uploaded_file, 'file', None)
content_t = mimetypes.guess_type(file_name)[0]
bucket_name = app_identity.get_default_gcs_bucket_name()
path = os.path.join('/', bucket_name, file_name)
with cloudstorage.open(path, 'w', content_type=content_t) as f:
f.write(file_content.read())
The problem is that the variable uploaded_file is handled as if it was a file by Massimiliano Pippi, but my Python tells me that this variable is a unicode containing the name of the file. Therefore, when I try file_name = getattr(uploaded_file, 'filename'), I get an error.
Obviously, the code in the book is false, how can I fix it?
Ok so after Tim's advice, I chcked the doc of WebOb and notice that in the html file, I should have put enctype="multipart/form-data" as follows:
<form action="" method="post" enctype="multipart/form-data">
<div class="form-group">
<label for="uploaded_file">Attached file:</label>
<input type="file" id="uploaded_file" name="uploaded_file">
</div>
</form>
Instead of:
<form action="" method="post">
<div class="form-group">
<label for="uploaded_file">Attached file:</label>
<input type="file" id="uploaded_file" name="uploaded_file">
</div>
</form>
Related
This is my basic flask route
#app.route('/home/form', methods=('GET','POST'))
def form():
if request.method == 'POST':
machine = request.form['machine']
df = pd.DataFrame([[machine]], columns=["Machine"])
with pd.ExcelWriter('P:\\Rohaan\\LATEST WEBSITE\\sample.xlsx') as writer:
df.to_excel(writer)
if not machine:
flash('Title is required!')
else:
return redirect(url_for('home'))
return render_template('form.html')
if __name__ == "__main__":
app.run(debug=True)
My form.html that I retrieve data frame
HTML Code
<form method="post">
<label for="Machine">Machine</label>
<br>
<input type="text" name="machine"
placeholder="Message machine"
value=''></input>
<br>
<label for="content">Message Content</label>
<br>
<textarea name="content"
placeholder="Message content"
rows="15"
cols="60"
></textarea>
<br>
<button type="submit">Submit</button>
</form>
Currently getting this result using this code
My question is:
Why the incoming data override my previous data?
Currently getting this result using this code
#app.route('/home/form', methods=('GET','POST'))
def form():
if request.method == 'POST':
machine = request.form['machine']
df = pd.DataFrame([[machine]], columns=["Machine"])
with pd.ExcelWriter('P:\\Rohaan\\LATEST WEBSITE\\sample.xlsx') as writer:
df.to_excel(writer)
if not machine:
flash('Title is required!')
else:
return redirect(url_for('home'))
return render_template('form.html')
if name == "main": app.run(debug=True)
According to documentation you should specify mode = "a" if you want to append and not override (default is mode = "w") inside ExcelWriter, but if it is actually supported is probably dependent on the chosen excel engine.
HTML Code
<form method="post">
<label for="Machine">Machine</label>
<br>
<input type="text" name="machine"
placeholder="Message machine"
value=''></input>
<br>
<label for="content">Message Content</label>
<br>
<textarea name="content"
placeholder="Message content"
rows="15"
cols="60"
></textarea>
<br>
<button type="submit">Submit</button>
</form>
This question already has answers here:
Create and download a CSV file from a Flask view
(3 answers)
Closed 2 years ago.
My goal is to run my data de-identifying script and download my de-identified data from Flask. Right now, I have created a page to upload my file onto my web and I want to execute my de-identifying script using the execute button on my HTML and download the file.
My HTML:
{% block title %}Upload{% endblock %}
{% block main %}
<div class="container">
<div class="row">
<div class="col">
<h1>Upload the file</h1>
<hr>
<form action="/upload-file" method="POST" enctype="multipart/form-data">
<div class="form-group">
<label>Select file</label>
<div class="custom-file">
<input type="file" class="custom-file-input" name="Dataset" id="Dataset">
<label class="custom-file-label" for="Dataset">Select file...</label>
</div>
</div>
<button type="submit" class="btn btn-primary">De-indentify</button>
</form>
<form action="/upload-file" method="GET" enctype="multipart/form-data">
<button type="submit" class="btn btn-primary">Execute</button>
</form>
</div>
</div>
</div>
{% endblock %}
My App Flask route:
app.config["FILE_UPLOADS"] = "app/app/static/csv/uploads"
app.config["ALLOWED_FILE_EXTENSIONS"] = ["csv"]
def allowed_file(filename):
# We only want files with a . in the filename
if not "." in filename:
return False
# Split the extension from the filename
ext = filename.rsplit(".", 1)[1]
# Check if the extension is in ALLOWED_IMAGE_EXTENSIONS
if ext.upper() in app.config["ALLOWED_FILE_EXTENSIONS"]:
return True
else:
return False
#app.route("/upload-file", methods=["GET", "POST"])
def upload_file():
if request.method == "POST":
if request.files:
Dataset = request.files["Dataset"]
if Dataset.filename == "":
print("File must have a filename ")
return redirect(request.url)
if allowed_file(Dataset.filename):
print("That file extension is not allowed")
return redirect(request.url)
else:
filename = secure_filename(Dataset.filename)
Dataset.save(os.path.join(
app.config["FILE_UPLOADS"], filename))
print("Dataset saved")
return redirect(request.url)
return render_template("public/upload_file.html")
The file that I have uploaded:
Housing,Houseprice,Name,Neighbourhood,State
123556,100000,John,Bloomingdale,Washington
111777,250000,Ian,Bloomingdale,Washington
998273,250000,Tom,Spring Valley,California
My de-identifying script:
import pandas as pd
import uuid as u
# generate a pseudo-identifier sequesnce using python random number generator library uudi.
def uudi_generator(length):
uudi_list= list()
i=0
while i < length:
uudi_list.append(u.uuid4())
i+=1
return uudi_list
#import dataset
dataset = pd.read_csv('C:\\mylocation\\housing.csv', index_col=False)
# pseudo identifier
sLength = len(dataset['Housing'])
dataset.insert(0, 'uuid', pd.Series(uudi_generator(sLength), index=dataset.index))
#delete identifiabLe record from dataset
del dataset['Name']
del dataset['Neigbourhood']
Try this:
from flask import Response
csv_text = ""
for row in dataset.values:
csv_text += f"{row[0]},{row[1]},{row[2]},{row[3]}\n"
return Response(csv_text, mimetype='text/csv')
You don't even need to del the unwanted columns. Just don't add them in csv_text. You don't really even need pandas. You could read the csv as a text file, split('\n') and add the uuids when you compile the csv_text
I would like to upload a single file or files at a time using get method.
I have already done with the post method and working fine. But for some reason i would like to do the file upload using get method using command line.
The below code is which i have already tried to get the string from get method and i can able to get the varValue as string. But i would like to get the file using get method.
def home(request):
if request.method == 'GET':
varValue = request.GET.get('myfile', '')
print(varValue)`
HTML code:
<form method="GET" enctype="multipart/form-data">
<input type="file" name="myfile" accept="image/*" multiple>
<button type="submit">Upload files</button>
Try This Method
for filename, file in request.FILES.iteritems():
name = request.FILES[filename].name
A dictionary-like object containing all uploaded files. Each key in FILES is the name from the . Each value in FILES is an UploadedFile.
<form method="GET" enctype="multipart/form-data">
{% csrf_token %}
<input type="file" name="myfile">
<button type="submit">Upload File</button>
</form>
Found the solution using the post method itself. By skipping the csrf token we can do the command line script execution method.
Python views.py code below
from django.views.decorators.csrf import csrf_exempt
#csrf_exempt
def home(request):
if request.method == 'POST':
uploaded_file = request.FILES['myfile']
fs = FileSystemStorage()
name = fs.save(uploaded_file.name, uploaded_file)
print(name)
return render(request, "home.html")
HTML code:
<body>
<form method="POST" enctype="multipart/form-data">
<input type="file" name="myfile" accept="image/*" multiple>
<button type="submit">Upload files</button>
</body>
python code for file upload using post method:
import requests
files = {'myfile': open('d:\\20190819-140341-627485.png','rb')}
y = requests.post("http://127.0.0.1:8000",files=files)
I'm building a file storage system using the Google App Engine. Each user is able to login and create directories (Strings) for their accounts using a HTML form. I've been trying to not allow a user to add two directories with the same name but I cannot get it working.
Here is my form in HTML:
<form action="/" method="post">
Add a Directory: <input type="text" name="dir1"/><br/>
<input type="submit" name="button" value="Add Directory"/>
</form>
<br/>
{% for i in directories %}
Directory Name:{{ i.dir1 }}<br/>
<br/>
<form action="/" method="post">
<input type="hidden" name="index" value="{{ loop.index - 1 }}"/>
<input type="submit" value="Delete" name="button"/>
</form>
{% endfor %}
And here is my Python code in which I believe the check should be done:
def post(self):
self.response.headers['Content-Type'] = 'text/html'
action = self.request.get('button')
if action == 'Add Directory':
dir1 = self.request.get('dir1')
user = users.get_current_user()
myuser_key = ndb.Key('MyUser', user.user_id())
myuser = myuser_key.get()
new_directory = Directory(dir1=dir1)
myuser.directories.append(new_directory)
myuser.put()
self.redirect('/')
In your Python function, you could use ndb's get_or_insert method which retrieves an entity if the specified key already exists or creates it if it doesn't.
I have the following
<form action="classify_upload" method="post" id="upload-form">
<input type="file" name="imagefile" id="imagefile"/>
<input type="submit" />
</form>
And in my flask webapp I have the following rule:
#webapp.route('/upload', methods=['POST'])
def upload():
try:
imagefile = flask.request.files['imagefile']
...
except Exception as err:
...
But I am getting a error 400: bad request, which from my googling tells me Flask can not find the file under the key 'imagefile' which is the name of the input in the html. Any ideas why it is not finding it?
Turns out I need to include the enctype in the form, so the html should be
<form action="classify_upload" method="post" id="upload-form" enctype="multipart/form-data">
<input type="file" name="imagefile" id="imagefile"/>
<input type="submit" />
</form>