Can't upload file in Google App Engine - python

I don't know why I can't upload my file? When I hit submit instead of redirecting to the default page (which is http://localhost:8082), it redirects to http://localhost:8082/sign. I didn't build no such path, so it return link broken. Here's my html:
<form action="/sign" enctype="multipart/form-data" method="post">
<div><label>Excel file submit:</label></div>
<div><input type="file" name="excel"/></div>
<div><input type="submit" value="Upload file"></div>
</form>
my app.yaml:
application: engineapp01
version: 1
runtime: python
api_version: 1
handlers:
- url: /js
static_dir: js
- url: /css
static_dir: css
- url: .*
script: main.py
main.py:
import os;
from google.appengine.ext import webapp
from google.appengine.ext.webapp import util
from google.appengine.ext.webapp import template
from google.appengine.ext import db
from mmap import mmap,ACCESS_READ
from xlrd import open_workbook
class Account(db.Model):
name = db.StringProperty()
type = db.StringProperty()
no = db.IntegerProperty()
co = db.IntegerProperty()
class MyFile(db.Model):
filedata = db.BlobProperty()
class MainHandler(webapp.RequestHandler):
def get(self):
#delete all old temporary entries
query = Account.all()
results = query.fetch(limit=40)
db.delete(results)
#temporary entry
acc = Account(name='temporaryAccountName',
type='temporaryType',
no=0,
co=500)
acc.put()
temp = os.path.join(os.path.dirname(__file__),'templates/index.htm')
tableData = ''
query = Account.all()
query.order('name')
results = query.fetch(limit=20)
for account in results:
tempStr= """
<tr>
<td align='left' valign='top'>%s</td>
<td align='left' valign='top'>%s</td>
<td align='left' valign='top'>%d</td>
<td align='left' valign='top'>%d</td>
</tr>""" % (account.name,account.type,account.no,account.co)
tableData = tableData + tempStr
outstr = template.render(
temp,
{'tabledata':tableData})
self.response.out.write(outstr)
def post(self):
myFile = MyFile()
excel = self.request.get("excel")
myFile.fileData = db.Blob(excel)
myFile.put()
self.redirect('/')
def main():
application = webapp.WSGIApplication([('/', MainHandler)],
debug=True)
util.run_wsgi_app(application)
if __name__ == '__main__':
main()

Why are you sending the form data to a page that doesn't exist?
Try changing the HTML to:
<form action="/" enctype="multipart/form-data" method="post">
...
...since "/" is where your form-handling code resides.

Related

Beginner Pythonanywhere Query

Edit 3:
I am trying to display info from a csv file on pythonanywhere, prompted from a user input into a form.
I have loaded the client_db.csv onto my files on pythonanywhere here:'/home/myusername/mydirectory/client_db.csv'.
Essentially, the user would 'Enter an address: (form)', and values for 'name', 'shack', 'status' and 'payments' would display.
Here is my attempt so far (v3), but I am not getting it to work. I suspect there is something wrong with the html input?
from flask import Flask
import os
import sys
import csv
import numpy as np
app = Flask(__name__)
app.config["DEBUG"] = True
path = '/home/myusername/ishack'
if path not in sys.path:
sys.path.append(path)
client_db = np.genfromtxt('/home/myusername/ishack/client_db.csv', delimiter=',',dtype=None, names=True)
#app.route('/')
def form()
return """
<html>
<body>
<h1>Enter a Shack Number</h1>
<form action="/address" method="POST">
<textarea class="form-control" name="address" placeholder="Enter a Shack Number"></textarea>
<input type="submit" />
</form>
</body>
</html>
"""
#app.route('/address', methods=["POST"])
def display_info(address):
ind = np.where(client_db['Shack']==address)[0]
return {'Name': client_db['Name'][ind],
'Shack': client_db['Shack'][ind],
'Status': client_db['Status'][ind],
'Payments': client_db['Payments'][ind]}
display_info(address)
You are having minor problems in the code just posted:
There are minor errors like missing colons and so
Additionally, note you are indexing wrongly the matrix, putting first the column and later the row, when it is exactly the opposite. The correct sentence is (note ind is before Name for example):
return {'Name': client_db[ind]['Name'][0],
'Shack': client_db[ind]['Shack'][0],
'Status': client_db[ind]['Status'][0],
'Payments': client_db[ind]['Payments'][0]}
The last problem is related to the POST of the form. To grab the address data you must use: address = request.form["address"]
For finishing your code, this example returns a JSON data with the fields found in the CSV file:
from flask import Flask, request, Response
from flask import request
import json
import os
import sys
import csv
import numpy as np
app = Flask(__name__)
app.config["DEBUG"] = True
path = '/home/myusername/ishack'
if path not in sys.path:
sys.path.append(path)
client_db = np.genfromtxt('/home/myusername/ishack/client_db.csv', delimiter=',', dtype=None, names=True)
#app.route('/')
def form():
return """
<html>
<body>
<h1>Enter a Shack Number</h1>
<form action="/address" method="POST">
<textarea class="form-control" name="address" placeholder="Enter a Shack Number"></textarea>
<input type="submit" />
</form>
</body>
</html>
"""
#app.route('/address', methods=["POST"])
def display_info():
address = request.form["address"]
ind = np.where(client_db['Shack'] == address)[0]
res = {'Name': client_db[ind]['Name'][0],
'Shack': client_db[ind]['Shack'][0],
'Status': client_db[ind]['Status'][0],
'Payments': client_db[ind]['Payments'][0]}
return Response(json.dumps(res), mimetype='application/json')
app.run(host="0.0.0.0", port=5000)

GCS upload is realy slow from GAE

I have setup a simple python project on GAE, the user picks a file and it uploads into Google Cloud Storage. This all works fine, but I am getting an upload time of 10-11 seconds when I am uploading a 100kb file. How can I reduce this?
Extra info:
I have a 100Mbis upload speed and the result is the same with a 4kb image, the latency of the first post id about 6 seconds
import os
import urllib
import webapp2
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
class MainHandler(webapp2.RequestHandler):
def get(self):
upload_url = blobstore.create_upload_url('/upload', gs_bucket_name='bucket_name')
self.response.out.write('<html><body>')
self.response.out.write('<form action="%s" method="POST" enctype="multipart/form-data">' % upload_url)
self.response.out.write("""Upload File: <input type="file" name="file"><br> <input type="submit"
name="submit" value="Submit"> </form></body></html>""")
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
upload_files = self.get_uploads('file') # 'file' is file upload field in the form
blob_info = upload_files[0]
self.redirect('/serve/%s' % blob_info.key())
class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, resource):
resource = str(urllib.unquote(resource))
blob_info = blobstore.BlobInfo.get(resource)
self.send_blob(blob_info)
app = webapp2.WSGIApplication([('/', MainHandler),
('/upload', UploadHandler),
('/serve/([^/]+)?', ServeHandler)],
debug=True)

Uploading images - Google App Engine + Python

I'm using this link as an example to uploading images:
https://gist.github.com/jdstanhope/5079277
My HTML code:
<form action="/upload_image" method="post" id="form1" runat="server">
<div class="fileButtons">
<input type='file' id="imgInp" name="imgInput" accept="image/*"/><br><br>
<input type='button' id='remove' value='Remove' />
</div></form>
main.py:
class SetImage(webapp2.RequestHandler):
def post(self):
logging.debug("test")
id = str(self.request.get('id'))
image = self.request.get('imgInput')
app = webapp2.WSGIApplication([('/upload_image', SetImage),
('/', MainPage)], debug=True)
But when I add an image, nothing is being done, and the log console doesn't print:
logging.debug("test")
The recommended way of uploading images to GAE is by using blobstore.
Here is a quick breakdown of the doc to help you achieve this fast:
Imports:
import os
import urllib
import webapp2
from google.appengine.ext import blobstore
from google.appengine.ext.webapp import blobstore_handlers
Serve the form HTML. this form performs the POST to GAE with the selected files data:
class MainHandler(webapp2.RequestHandler):
def get(self):
upload_url = blobstore.create_upload_url('/upload')
self.response.out.write('<html><body>')
self.response.out.write('<form action="%s" method="POST"
enctype="multipart/form-data">' % upload_url)
self.response.out.write("""Upload File:
<input type="file" name="file"><br> <input type="submit"
name="submit" value="Submit"> </form></body></html>""")
Add a handler for receiving the POST data (binary content of the file). the last line in this function is to redirect the response to the location from where the file could be downloaded:
class UploadHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
# 'file' is file upload field in the form
upload_files = self.get_uploads('file')
blob_info = upload_files[0]
self.redirect('/serve/%s' % blob_info.key())
Add handler to serve the image that you uploaded using the UploadHandler described above:
class ServeHandler(blobstore_handlers.BlobstoreDownloadHandler):
def get(self, resource):
resource = str(urllib.unquote(resource))
blob_info = blobstore.BlobInfo.get(resource)
self.send_blob(blob_info)
And finally, define the routes for the app:
app = webapp2.WSGIApplication([('/', MainHandler),
('/upload', UploadHandler),
('/serve/([^/]+)?', ServeHandler)],
debug=True)
Regarding the issue of your log statement not firing: The default log level for dev_appserver.py is info, which you can override with the --dev_appserver_log_level flag.
Reference the new dev_appserver documentation.
To access uploaded files from a multipart/form-data POST request, the webapp2 documentation states that they're available in request.POST.

HTML output problems

I am writing a website with python and jinja2 in google app engine. My html page is showing this on the page:
Status: 200
Content-Type: text/html;
charset=utf-8
Cache-Control: no-cache
Content-Length: 432
Any idea where this problem is coming from? Also, why is {{ initial_city }} not displaying the results?
My main.py script is:
from google.appengine.ext import db
from google.appengine.api import memcache
from models import Deal
import os
import webapp2
import jinja2
#databasestuff
deal = Deal(title='Hello',
description='Deal info here',
city='New York')
deal.put()
print deal
jinja_environment = jinja2.Environment(autoescape=True,
loader=jinja2.FileSystemLoader(os.path.join(os.path.dirname(__file__), 'templates')))
class MainPage(webapp2.RequestHandler):
def get(self):
template = jinja_environment.get_template('index.html')
self.response.out.write(template.render())
class DealHandler(webapp2.RequestHandler):
def get(self):
def get_deals(choose_city, update=False):
key = str(choose_city)
all_deals = memcache.get(key)
return all_deals
choose_city = self.request.get('c')
try:
initial_city = str(choose_city)
choose_city = initial_city
except ValueError:
initial_city = 0
choose_city = initial_city
template = jinja_environment.get_template('deal.html')
self.response.out.write(template.render())
class ContentHandler(webapp2.RequestHandler):
def get(self):
template = jinja_environment.get_template('content.html')
self.response.out.write(template.render())
app = webapp2.WSGIApplication([('/', MainPage),
('/deal', DealHandler),
('/content', ContentHandler)],
debug=True)
My html page:
<!DOCTYPE html>
<html>
<head>
<title>
Deallzz: Chosen City: {{ initial_city }}
</title>
</head>
...
To display initial_city, pass the variable to the template using the render method:
self.response.out.write(template.render(initial_city = initial_city))
Its the "print deal" that is causing the problem. Its being output before any response.write
This is just the headers of the HTML page. You should provide more informations/code of what you are trying now.

Displaying images form datastore

I am just testing out displaying images on GAE, I have this little .py
import cgi
import wsgiref.handlers
from google.appengine.api import users
from google.appengine.api import images
from google.appengine.ext import db
from google.appengine.ext import webapp
class ImgUpload(db.Model):
project_name = db.StringProperty()
project_description = db.StringProperty(multiline=True)
img_name = db.StringProperty()
img_img = db.BlobProperty()
date = db.DateTimeProperty(auto_now_add=True)
class UploadPage(webapp.RequestHandler):
def get(self):
self.response.out.write("""<html><body>
<form action="/upload" enctype="multipart/form-data" method="post">
<div><label>Project Name</label></div>
<div><textarea name="title" rows="2" columns "60"></textarea></div>
<div><label>Despcription:</label></div>
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><label>Image Name</label></div>
<div><textarea name="imgname" row="1" cols="60"></textarea></div>
<div><label>Image</label></div>
<div><input type="file" name="img"/></div>
<div><input type="submit" value="Upload" /></div>
</form>
</body>
</html>""")
def post(self):
images = ImgUpload()
project_name = self.request.get('title')
project_description = self.request.get('content')
img_img = self.request.get('img')
img_name = self.request.get('imgname')
images.img_img = db.Blob(img_img)
images.project_name = project_name
images.project_description = project_description
images.img_name = img_name
images.put()
self.redirect('/upload')
class DisplayPage(webapp.RequestHandler):
def get(self):
display = db.GqlQuery("SELECT * "
"FROM display "
"WHERE ANCESTOR IS :1 "
"ORDER BY date DESC LIMIT 5"
)
for record in display:
self.response.out.write('<b>%s</> is the Name' % record.project_name)
def main():
application = webapp.WSGIApplication(
[('/', UploadPage),
('/display', DisplayPage)
],
debug=True)
wsgiref.handlers.CGIHandler().run(application)
if __name__=="__main__":
main()
When I run this, I get a KindError: No implementation for kind 'display'. Is this an issue pertaining to lack of a DB key, I know they data is in the store, I can see it in the admin, and I can't see any naming issue (at least off the top of my head, there could be thousands for all that I know). What exactly is causing this error to pop? Thank you in advance for your advice.
In your GQL you are selecting from the "display" kind. You don't have a display kind defined, you have a "ImgUpload" kind defined. Using the object interface to query will help you avoid this type of problem.
I also don't see a parameter being passed to the query for it to filter on, so you're going to get another error there.

Categories