librelist archives

« back to archive

App Engine Blobstore

App Engine Blobstore

From:
Dan Ross
Date:
2011-01-08 @ 03:15
I noticed a few other posts in the archives asking for experience with the
App Engine blobstore but there were no responses.

Does anyone have any advice or tricks they'd like to share before I start 
figuring this out that pertain to Flask?

Thanks,

Dan

Re: [flask] App Engine Blobstore

From:
Adam Oakman
Date:
2011-01-08 @ 04:13
Hi Dan,
     I went through the process of uploading mainly as an exercise for  
my knowledge. I'll post my code here for information purposes, but its  
not thoroughly tested and probably is not the best handler for it  
however it works well for me. Oh and apart from the blobstore and cgi  
(used to parse the header only) modules its pure Flask which I like.


This is the code that returns the upload template, a simple form that  
posts to upload_url

@app.route('/upload/', methods=['GET','POST'])
@login_required
def uploads():
     upload_url =  
blobstore.create_upload_url(url_for('uploads_handler'))
     if request.is_xhr:
         return upload_url
     else:
         return render_template('upload.html', upload_url=upload_url)

Heres the form:

<form method="post" action="{{ upload_url }}" enctype="multipart/form- 
data">
   <dl>
     <input type="file" name="file" />
     <input type="hidden" name="item" value="{{ item.key() }}" />
     <input type="hidden" name="return"  
value="{{ request.base_url }}" />
   </dl>
   <input type="submit" name="button" class="btn" value="Upload" />
</form>

This is the handler that the blobstore redirects to after storing the  
blob. Essentially this code gets the blobkey from the header,  
retrieves the blob information from th blobstore, writes that to my  
table and then performs a redirect to the final page. There were a  
couple of traps for young players here. First getting the blob_key  
from the file uploads header took me some time, but with some help  
from this list I worked through it. Second was the blobstore requires  
the handler to return a redirect with no data, so I had to modify the  
standard redirect response as you will see.

@app.route('/upload/handler/', methods=['GET','POST'])
@login_required
def uploads_handler():
     #key is stored in the header for each file uploaded
     type, params =  
cgi.parse_header(request.files['file'].headers['Content-Type'])
     blob_key = blobstore.BlobKey(params['blob-key'])
     blob = blobstore.BlobInfo.get(blob_key)
     item = Page_Items.get(request.values['item'])
     upload = Uploads(owner = g.user.owner,
                     filename = blob.filename,
                     mime_type = blob.content_type,
                     blob = blob,
                     items = [item.key()])
     if blob.content_type in app.config['IMAGE_TYPES']:
         upload.download_url = images.get_serving_url(str(blob_key))
     upload.put()
     if item.images:
         item_imgs = json.loads(item.images)
     else:
         item_imgs = []
     item_imgs.append({'key': str(upload.key()), 'url' :  
upload.download_url, 'filename' : upload.filename })
     item.images = json.dumps(item_imgs)
     item.put()
     response = redirect(request.values['return'])
     response.data = ''
     return response

Hope it helps

Adam

On Jan 7, 2011, at 9:15 PM, Dan Ross wrote:

> I noticed a few other posts in the archives asking for experience  
> with the App Engine blobstore but there were no responses.
>
> Does anyone have any advice or tricks they'd like to share before I  
> start figuring this out that pertain to Flask?
>
> Thanks,
>
> Dan

Re: [flask] App Engine Blobstore

From:
Dan Ross
Date:
2011-01-08 @ 06:17
Spectacular. That gives me some reference to work with. Thanks Adam.

On Jan 7, 2011, at 10:13 PM, Adam Oakman wrote:

> Hi Dan,
>     I went through the process of uploading mainly as an exercise for  
> my knowledge. I'll post my code here for information purposes, but its  
> not thoroughly tested and probably is not the best handler for it  
> however it works well for me. Oh and apart from the blobstore and cgi  
> (used to parse the header only) modules its pure Flask which I like.
> 
> 
> This is the code that returns the upload template, a simple form that  
> posts to upload_url
> 
> @app.route('/upload/', methods=['GET','POST'])
> @login_required
> def uploads():
>     upload_url =  
> blobstore.create_upload_url(url_for('uploads_handler'))
>     if request.is_xhr:
>         return upload_url
>     else:
>         return render_template('upload.html', upload_url=upload_url)
> 
> Heres the form:
> 
> <form method="post" action="{{ upload_url }}" enctype="multipart/form- 
> data">
>   <dl>
>     <input type="file" name="file" />
>     <input type="hidden" name="item" value="{{ item.key() }}" />
>     <input type="hidden" name="return"  
> value="{{ request.base_url }}" />
>   </dl>
>   <input type="submit" name="button" class="btn" value="Upload" />
> </form>
> 
> This is the handler that the blobstore redirects to after storing the  
> blob. Essentially this code gets the blobkey from the header,  
> retrieves the blob information from th blobstore, writes that to my  
> table and then performs a redirect to the final page. There were a  
> couple of traps for young players here. First getting the blob_key  
> from the file uploads header took me some time, but with some help  
> from this list I worked through it. Second was the blobstore requires  
> the handler to return a redirect with no data, so I had to modify the  
> standard redirect response as you will see.
> 
> @app.route('/upload/handler/', methods=['GET','POST'])
> @login_required
> def uploads_handler():
>     #key is stored in the header for each file uploaded
>     type, params =  
> cgi.parse_header(request.files['file'].headers['Content-Type'])
>     blob_key = blobstore.BlobKey(params['blob-key'])
>     blob = blobstore.BlobInfo.get(blob_key)
>     item = Page_Items.get(request.values['item'])
>     upload = Uploads(owner = g.user.owner,
>                     filename = blob.filename,
>                     mime_type = blob.content_type,
>                     blob = blob,
>                     items = [item.key()])
>     if blob.content_type in app.config['IMAGE_TYPES']:
>         upload.download_url = images.get_serving_url(str(blob_key))
>     upload.put()
>     if item.images:
>         item_imgs = json.loads(item.images)
>     else:
>         item_imgs = []
>     item_imgs.append({'key': str(upload.key()), 'url' :  
> upload.download_url, 'filename' : upload.filename })
>     item.images = json.dumps(item_imgs)
>     item.put()
>     response = redirect(request.values['return'])
>     response.data = ''
>     return response
> 
> Hope it helps
> 
> Adam
> 
> On Jan 7, 2011, at 9:15 PM, Dan Ross wrote:
> 
>> I noticed a few other posts in the archives asking for experience  
>> with the App Engine blobstore but there were no responses.
>> 
>> Does anyone have any advice or tricks they'd like to share before I  
>> start figuring this out that pertain to Flask?
>> 
>> Thanks,
>> 
>> Dan
> 

Re: [flask] App Engine Blobstore

From:
Paul Burt
Date:
2011-01-08 @ 09:56
You can also use werkzeug's own parse_options_header to parse out the blob key:

Something like this:

from flask import request
from werkzeug import parse_options_header

def get_blob_key(field_name, blob_key=None):
    """Parse out and return the blob key from a file uploaded via the App Engine
    Blobstore API.

    """
    try:
        upload_file = request.files[field_name]
        header = upload_file.headers['Content-Type']
        parsed_header = parse_options_header(header)
        blob_key = parsed_header[1]['blob-key']
    except:
        # something went wrong
    return blob_key

This obviously only deals with one uploaded file in one form field,
but it illustrates the usage reasonably.

Once you've got the elusive blob key parsed out of the Content-Type
header, you're good to go.

Paul


On 8 January 2011 06:17, Dan Ross <dan@rosspixelworks.com> wrote:
> Spectacular. That gives me some reference to work with. Thanks Adam.
>
> On Jan 7, 2011, at 10:13 PM, Adam Oakman wrote:
>
>> Hi Dan,
>>     I went through the process of uploading mainly as an exercise for
>> my knowledge. I'll post my code here for information purposes, but its
>> not thoroughly tested and probably is not the best handler for it
>> however it works well for me. Oh and apart from the blobstore and cgi
>> (used to parse the header only) modules its pure Flask which I like.
>>
>>
>> This is the code that returns the upload template, a simple form that
>> posts to upload_url
>>
>> @app.route('/upload/', methods=['GET','POST'])
>> @login_required
>> def uploads():
>>     upload_url =
>> blobstore.create_upload_url(url_for('uploads_handler'))
>>     if request.is_xhr:
>>         return upload_url
>>     else:
>>         return render_template('upload.html', upload_url=upload_url)
>>
>> Heres the form:
>>
>> <form method="post" action="{{ upload_url }}" enctype="multipart/form-
>> data">
>>   <dl>
>>     <input type="file" name="file" />
>>     <input type="hidden" name="item" value="{{ item.key() }}" />
>>     <input type="hidden" name="return"
>> value="{{ request.base_url }}" />
>>   </dl>
>>   <input type="submit" name="button" class="btn" value="Upload" />
>> </form>
>>
>> This is the handler that the blobstore redirects to after storing the
>> blob. Essentially this code gets the blobkey from the header,
>> retrieves the blob information from th blobstore, writes that to my
>> table and then performs a redirect to the final page. There were a
>> couple of traps for young players here. First getting the blob_key
>> from the file uploads header took me some time, but with some help
>> from this list I worked through it. Second was the blobstore requires
>> the handler to return a redirect with no data, so I had to modify the
>> standard redirect response as you will see.
>>
>> @app.route('/upload/handler/', methods=['GET','POST'])
>> @login_required
>> def uploads_handler():
>>     #key is stored in the header for each file uploaded
>>     type, params =
>> cgi.parse_header(request.files['file'].headers['Content-Type'])
>>     blob_key = blobstore.BlobKey(params['blob-key'])
>>     blob = blobstore.BlobInfo.get(blob_key)
>>     item = Page_Items.get(request.values['item'])
>>     upload = Uploads(owner = g.user.owner,
>>                     filename = blob.filename,
>>                     mime_type = blob.content_type,
>>                     blob = blob,
>>                     items = [item.key()])
>>     if blob.content_type in app.config['IMAGE_TYPES']:
>>         upload.download_url = images.get_serving_url(str(blob_key))
>>     upload.put()
>>     if item.images:
>>         item_imgs = json.loads(item.images)
>>     else:
>>         item_imgs = []
>>     item_imgs.append({'key': str(upload.key()), 'url' :
>> upload.download_url, 'filename' : upload.filename })
>>     item.images = json.dumps(item_imgs)
>>     item.put()
>>     response = redirect(request.values['return'])
>>     response.data = ''
>>     return response
>>
>> Hope it helps
>>
>> Adam
>>
>> On Jan 7, 2011, at 9:15 PM, Dan Ross wrote:
>>
>>> I noticed a few other posts in the archives asking for experience
>>> with the App Engine blobstore but there were no responses.
>>>
>>> Does anyone have any advice or tricks they'd like to share before I
>>> start figuring this out that pertain to Flask?
>>>
>>> Thanks,
>>>
>>> Dan
>>
>
>

Re: [flask] App Engine Blobstore

From:
Paul Burt
Date:
2011-01-08 @ 10:16
Dan, it also bears repeating here that you *must* enable Billing in
your application before trying to use the Blobstore API in the
production environment.

Just mentioning that because it burned me!

Paul


On 8 January 2011 09:56, Paul Burt <paul.burt@gmail.com> wrote:
> You can also use werkzeug's own parse_options_header to parse out the blob key:
>
> Something like this:
>
> from flask import request
> from werkzeug import parse_options_header
>
> def get_blob_key(field_name, blob_key=None):
>    """Parse out and return the blob key from a file uploaded via the App Engine
>    Blobstore API.
>
>    """
>    try:
>        upload_file = request.files[field_name]
>        header = upload_file.headers['Content-Type']
>        parsed_header = parse_options_header(header)
>        blob_key = parsed_header[1]['blob-key']
>    except:
>        # something went wrong
>    return blob_key
>
> This obviously only deals with one uploaded file in one form field,
> but it illustrates the usage reasonably.
>
> Once you've got the elusive blob key parsed out of the Content-Type
> header, you're good to go.
>
> Paul
>
>
> On 8 January 2011 06:17, Dan Ross <dan@rosspixelworks.com> wrote:
>> Spectacular. That gives me some reference to work with. Thanks Adam.
>>
>> On Jan 7, 2011, at 10:13 PM, Adam Oakman wrote:
>>
>>> Hi Dan,
>>>     I went through the process of uploading mainly as an exercise for
>>> my knowledge. I'll post my code here for information purposes, but its
>>> not thoroughly tested and probably is not the best handler for it
>>> however it works well for me. Oh and apart from the blobstore and cgi
>>> (used to parse the header only) modules its pure Flask which I like.
>>>
>>>
>>> This is the code that returns the upload template, a simple form that
>>> posts to upload_url
>>>
>>> @app.route('/upload/', methods=['GET','POST'])
>>> @login_required
>>> def uploads():
>>>     upload_url =
>>> blobstore.create_upload_url(url_for('uploads_handler'))
>>>     if request.is_xhr:
>>>         return upload_url
>>>     else:
>>>         return render_template('upload.html', upload_url=upload_url)
>>>
>>> Heres the form:
>>>
>>> <form method="post" action="{{ upload_url }}" enctype="multipart/form-
>>> data">
>>>   <dl>
>>>     <input type="file" name="file" />
>>>     <input type="hidden" name="item" value="{{ item.key() }}" />
>>>     <input type="hidden" name="return"
>>> value="{{ request.base_url }}" />
>>>   </dl>
>>>   <input type="submit" name="button" class="btn" value="Upload" />
>>> </form>
>>>
>>> This is the handler that the blobstore redirects to after storing the
>>> blob. Essentially this code gets the blobkey from the header,
>>> retrieves the blob information from th blobstore, writes that to my
>>> table and then performs a redirect to the final page. There were a
>>> couple of traps for young players here. First getting the blob_key
>>> from the file uploads header took me some time, but with some help
>>> from this list I worked through it. Second was the blobstore requires
>>> the handler to return a redirect with no data, so I had to modify the
>>> standard redirect response as you will see.
>>>
>>> @app.route('/upload/handler/', methods=['GET','POST'])
>>> @login_required
>>> def uploads_handler():
>>>     #key is stored in the header for each file uploaded
>>>     type, params =
>>> cgi.parse_header(request.files['file'].headers['Content-Type'])
>>>     blob_key = blobstore.BlobKey(params['blob-key'])
>>>     blob = blobstore.BlobInfo.get(blob_key)
>>>     item = Page_Items.get(request.values['item'])
>>>     upload = Uploads(owner = g.user.owner,
>>>                     filename = blob.filename,
>>>                     mime_type = blob.content_type,
>>>                     blob = blob,
>>>                     items = [item.key()])
>>>     if blob.content_type in app.config['IMAGE_TYPES']:
>>>         upload.download_url = images.get_serving_url(str(blob_key))
>>>     upload.put()
>>>     if item.images:
>>>         item_imgs = json.loads(item.images)
>>>     else:
>>>         item_imgs = []
>>>     item_imgs.append({'key': str(upload.key()), 'url' :
>>> upload.download_url, 'filename' : upload.filename })
>>>     item.images = json.dumps(item_imgs)
>>>     item.put()
>>>     response = redirect(request.values['return'])
>>>     response.data = ''
>>>     return response
>>>
>>> Hope it helps
>>>
>>> Adam
>>>
>>> On Jan 7, 2011, at 9:15 PM, Dan Ross wrote:
>>>
>>>> I noticed a few other posts in the archives asking for experience
>>>> with the App Engine blobstore but there were no responses.
>>>>
>>>> Does anyone have any advice or tricks they'd like to share before I
>>>> start figuring this out that pertain to Flask?
>>>>
>>>> Thanks,
>>>>
>>>> Dan
>>>
>>
>>
>

Re: [flask] App Engine Blobstore

From:
Dan Ross
Date:
2011-01-08 @ 14:36
I saw that as well. That's why I'm trying to gather as much info as 
possible so I don't accidentally cost myself a bunch of money.

Thanks Paul.


On Jan 8, 2011, at 4:16 AM, Paul Burt wrote:

> Dan, it also bears repeating here that you *must* enable Billing in
> your application before trying to use the Blobstore API in the
> production environment.
> 
> Just mentioning that because it burned me!
> 
> Paul
> 
> 
> On 8 January 2011 09:56, Paul Burt <paul.burt@gmail.com> wrote:
>> You can also use werkzeug's own parse_options_header to parse out the blob key:
>> 
>> Something like this:
>> 
>> from flask import request
>> from werkzeug import parse_options_header
>> 
>> def get_blob_key(field_name, blob_key=None):
>>    """Parse out and return the blob key from a file uploaded via the App Engine
>>    Blobstore API.
>> 
>>    """
>>    try:
>>        upload_file = request.files[field_name]
>>        header = upload_file.headers['Content-Type']
>>        parsed_header = parse_options_header(header)
>>        blob_key = parsed_header[1]['blob-key']
>>    except:
>>        # something went wrong
>>    return blob_key
>> 
>> This obviously only deals with one uploaded file in one form field,
>> but it illustrates the usage reasonably.
>> 
>> Once you've got the elusive blob key parsed out of the Content-Type
>> header, you're good to go.
>> 
>> Paul
>> 
>> 
>> On 8 January 2011 06:17, Dan Ross <dan@rosspixelworks.com> wrote:
>>> Spectacular. That gives me some reference to work with. Thanks Adam.
>>> 
>>> On Jan 7, 2011, at 10:13 PM, Adam Oakman wrote:
>>> 
>>>> Hi Dan,
>>>>     I went through the process of uploading mainly as an exercise for
>>>> my knowledge. I'll post my code here for information purposes, but its
>>>> not thoroughly tested and probably is not the best handler for it
>>>> however it works well for me. Oh and apart from the blobstore and cgi
>>>> (used to parse the header only) modules its pure Flask which I like.
>>>> 
>>>> 
>>>> This is the code that returns the upload template, a simple form that
>>>> posts to upload_url
>>>> 
>>>> @app.route('/upload/', methods=['GET','POST'])
>>>> @login_required
>>>> def uploads():
>>>>     upload_url =
>>>> blobstore.create_upload_url(url_for('uploads_handler'))
>>>>     if request.is_xhr:
>>>>         return upload_url
>>>>     else:
>>>>         return render_template('upload.html', upload_url=upload_url)
>>>> 
>>>> Heres the form:
>>>> 
>>>> <form method="post" action="{{ upload_url }}" enctype="multipart/form-
>>>> data">
>>>>   <dl>
>>>>     <input type="file" name="file" />
>>>>     <input type="hidden" name="item" value="{{ item.key() }}" />
>>>>     <input type="hidden" name="return"
>>>> value="{{ request.base_url }}" />
>>>>   </dl>
>>>>   <input type="submit" name="button" class="btn" value="Upload" />
>>>> </form>
>>>> 
>>>> This is the handler that the blobstore redirects to after storing the
>>>> blob. Essentially this code gets the blobkey from the header,
>>>> retrieves the blob information from th blobstore, writes that to my
>>>> table and then performs a redirect to the final page. There were a
>>>> couple of traps for young players here. First getting the blob_key
>>>> from the file uploads header took me some time, but with some help
>>>> from this list I worked through it. Second was the blobstore requires
>>>> the handler to return a redirect with no data, so I had to modify the
>>>> standard redirect response as you will see.
>>>> 
>>>> @app.route('/upload/handler/', methods=['GET','POST'])
>>>> @login_required
>>>> def uploads_handler():
>>>>     #key is stored in the header for each file uploaded
>>>>     type, params =
>>>> cgi.parse_header(request.files['file'].headers['Content-Type'])
>>>>     blob_key = blobstore.BlobKey(params['blob-key'])
>>>>     blob = blobstore.BlobInfo.get(blob_key)
>>>>     item = Page_Items.get(request.values['item'])
>>>>     upload = Uploads(owner = g.user.owner,
>>>>                     filename = blob.filename,
>>>>                     mime_type = blob.content_type,
>>>>                     blob = blob,
>>>>                     items = [item.key()])
>>>>     if blob.content_type in app.config['IMAGE_TYPES']:
>>>>         upload.download_url = images.get_serving_url(str(blob_key))
>>>>     upload.put()
>>>>     if item.images:
>>>>         item_imgs = json.loads(item.images)
>>>>     else:
>>>>         item_imgs = []
>>>>     item_imgs.append({'key': str(upload.key()), 'url' :
>>>> upload.download_url, 'filename' : upload.filename })
>>>>     item.images = json.dumps(item_imgs)
>>>>     item.put()
>>>>     response = redirect(request.values['return'])
>>>>     response.data = ''
>>>>     return response
>>>> 
>>>> Hope it helps
>>>> 
>>>> Adam
>>>> 
>>>> On Jan 7, 2011, at 9:15 PM, Dan Ross wrote:
>>>> 
>>>>> I noticed a few other posts in the archives asking for experience
>>>>> with the App Engine blobstore but there were no responses.
>>>>> 
>>>>> Does anyone have any advice or tricks they'd like to share before I
>>>>> start figuring this out that pertain to Flask?
>>>>> 
>>>>> Thanks,
>>>>> 
>>>>> Dan
>>>> 
>>> 
>>> 
>>