Transferring from Blob to Cloud Storage - python

I've transferred my App-Engine from BlobStorage to Cloud-Storage. This works finde with these Upload-Code:
Upload.py:
...
upload_url = blobstore.create_upload_url('/upload', gs_bucket_name="my-default-bucket")
...
my_upload_template.html:
...
<form action="{{ upload_url }}" method="POST" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit" name="submit" value="Submit">
</form>
...
Upload.py:
class UploadBlobHandler(blobstore_handlers.BlobstoreUploadHandler):
def post(self):
file_info = self.get_file_infos()[0]
self.response.out.write(file_info.gs_object_name)
self.redirect("/download/serve" + file_info.gs_object_name)
it worked great. But it's upload not only in the Google Cloud Storage-Bucket. It's uploaded in den Blob Storage too. (Can check when you go to https://appengine.google.com and click Blob Viewer.)
Is that the right way? Is it right? Or do I something wrong?

If I understood you correctly... you're using the Blobstore API to save to your Google Cloud Storage?
If that is what you're doing, then yes you're doing correctly, and yes it will save a copy of your document in the Blobstore.

Related

GAE Python webapp2 image upload error

I am working on a project in which i am trying to upload a image on blob store. But i am getting this error
File "C:\Users\shaizi\PycharmProjects\simpletestapp\Update.py", line
51, in post
blob_info = upload_files[0]
IndexError: list index out of range
My html form code is
<form id="signup" method="post" action="/update" enctype="multipart/form-data">
<label>Change image:</label>
<input type="file" name="pict" ><br>
</form>
Python Code for uploading image to Blob store:
def post(self):
blobstore.create_upload_url('/post/signup')
upload_files = self.get_uploads('pict')
blob_info = upload_files[0]
Actually i have to set the action to Upload url.
<form id="signup" method="post" action="/post/signup" enctype="multipart/form-data">
<label>Change image:</label>
<input type="file" name="pict" ><br>
</form>
I think you have to use a form_url variable:
` <form method="post" action="{{ form_url }}" accept-charset="UTF-8"
enctype="multipart/form-data">`
You get this variable from the appengine with your backend code:
class UploadPage(BaseRequestHandler):
def get(self):
form = UploadForm()
self.render('upload.html', {
'form': form,
'form_url': blobstore.create_upload_url('/upload_form'),
})
In my case, with multi-part forms, I am getting file data as follows:
self.request.get('<name_in_form>')
For your case, it should be:
self.request.get('pict')
In any case, if possible, try to avoid using blobstore, as Google recommends using Cloud Storage, as blobstore looks like will be deprecated in the future, couple of references:
https://cloud.google.com/appengine/docs/python/blobstore/
Google Blobstore versus Google cloud storage
Regards.

Uploading a file Google App - Python

Hoping someone can help cure my stupidity. I am creating a webapp where I need to upload csv files and process them. I am struggling to get my code to work in its simplest form. I can get the page to load up but as soon as I press the submit button to post the file I get a 403 Forbidden Error: Access was denied to this resource.
When I run it in the google app interactive console it does not give me any errors. Can some one point me in the right direction please.
HTML:
{% extends base_layout %}
{% block header_title %}
{% trans %}Upload Documents{% endtrans %}
{% endblock %}
{% block content %}
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="myfile">
<br>
<input type="submit" name="submit" value="Submit">
{% endblock %}
Handler class:
class Upload(BaseHandler):
def get(self):
return self.render_template('upload.html')
def post(self):
file = self.request.POST.getall('myfile')
#file will be process with data going into models here.
self.response.out.write("success")
You cannot simply upload a file to app engine since the file system is read only. You have to upload to either cloud storage or blob storage. When using either you have to use the facilities for each.
The easiest and fastest way to upload files via a form is with the blobstore api.

upload file to google storage using Python Google App engine API

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>

How do I get information from a form using webapp2?

I have the following scenario:
<form class=*** method="post" action=("main.py" ???)>
<input class=*** type="email" name="email">
<input class=*** type="submit" value=***>
</form>
This form is in a .html file, evidently in a different file from the python code. I wish know which ways do I have to get the information from the form and send to the python file to finally work on it (I guess is something about the action field but not sure).
OBS: I must use the webapp2 (I'm using the google server so django and other stuff do not work on it)
You can see Handling Forms with webapp2 from the Google App Engine wepapp2 tutorial.
import cgi
from google.appengine.api import users
import webapp2
MAIN_PAGE_HTML = """\
<html>
<body>
<form action="/sign" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
</body>
</html>
"""
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.write(MAIN_PAGE_HTML)
class Guestbook(webapp2.RequestHandler):
def post(self):
self.response.write('<html><body>You wrote:<pre>')
self.response.write(cgi.escape(self.request.get('content')))
self.response.write('</pre></body></html>')
application = webapp2.WSGIApplication([
('/', MainPage),
('/sign', Guestbook),
], debug=True)
And read through the entire tutorial for more information about Datastore and template
Using template allow you to put code html code in another file.

How to upload a file with django (python) and s3?

I'm looking for a way to upload a file to s3. I am using django. I am currently using amazon's python library for uploading along with the following code:
View:
def submitpicture(request):
fuser = request.session["login"]
copied_data = request.POST.copy()
copied_data.update(request.FILES)
content_type = copied_data['file'].get('content-type')
ffile = copied_data['file']['content']
key = '%s-%s' % (fuser, ''.join(copied_data['file']['filename'].split(' ')))
site_s3.save_s3_data(key, ffile, content_type)
Template:
<form action="/submitpicture/" method="POST">
<input type="file" id="file" name="file" />
<input type="submit" value="submit" />
</form>
However, when I actually try to run it i get the following error:
"Key 'file' not found in <QueryDict: {}>"
#MultiValueDictKeyError
I really don't see what I'm doing wrong. Can someone point me in the right direction?
Edit: Just in case someone wonders, I am planning on adding some validation after I get the actual upload working.
You will have to provide the enctype attribute to the FORM element (I've been bitten by this before). For example, your FORM tag should look like:
<form action="/submitpicture/" method="POST" enctype="multipart/form-data" >
Without the enctype, you will find yourself with an empty request.FILES.
Instead of doing this manually I would take a look at the storage backend David Larlet has written for Django, django-storages
Adding enctype="multipart/form-data" seems like something that's worth mentioning in the "File Uploads" section of the django docs (http://docs.djangoproject.com/en/dev/topics/http/file-uploads/). Thoughts?

Categories

Resources