in src/google/appengine/ext/blobstore/blobstore.py [0:0]
def send_blob(self,
environ,
blob_key_or_info,
content_type=None,
save_as=None,
start=None,
end=None,
**kwargs):
"""Send a blob-response based on a blob_key.
Returns the correct response headers for serving a blob. If BlobInfo
is provided and no content_type specified, will set request content type
to BlobInfo's content type.
Args:
environ: a WSGI dict describing the HTTP request (See PEP 333).
blob_key_or_info: BlobKey or BlobInfo record to serve.
content_type: Content-type header to override when known. If not set,
this header is not included in the returned headers.
Web frameworks might set the 'content-type' header to a default type,
which prevents GAE from setting a guessed 'content-type'.
This behavior can be bypassed by setting headers['content-type'] to None
or an empty string explicitly after this function call.
save_as: If True, and BlobInfo record is provided, use BlobInfos
filename to save-as. If string is provided, use string as filename.
If None or False, do not send as attachment.
start: Start index of content-range to send.
end: End index of content-range to send. End index is inclusive.
**kwargs:
The `use_range` keyworded argument provides content range from the
requests' Range header.
Raises:
ValueError on invalid save_as parameter.
Returns:
headers: a `dict` containing response headers
"""
if set(kwargs) - _SEND_BLOB_PARAMETERS:
invalid_keywords = []
for keyword in kwargs:
if keyword not in _SEND_BLOB_PARAMETERS:
invalid_keywords.append(keyword)
if len(invalid_keywords) == 1:
raise TypeError('send_blob got unexpected keyword argument %s.'
% invalid_keywords[0])
else:
raise TypeError('send_blob got unexpected keyword arguments: %s'
% sorted(invalid_keywords))
use_range = kwargs.get('use_range', self.__use_range_unset)
use_range_set = use_range is not self.__use_range_unset
headers = {}
range_header = _check_ranges(start, end, use_range_set, use_range,
environ.get('HTTP_RANGE'))
if range_header is not None:
headers[BLOB_RANGE_HEADER] = range_header
if isinstance(blob_key_or_info, BlobInfo):
blob_key = blob_key_or_info.key()
blob_info = blob_key_or_info
elif isinstance(blob_key_or_info, str) and blob_key_or_info.startswith(
'/gs/'):
blob_key = create_gs_key(blob_key_or_info)
blob_info = None
else:
blob_key = blob_key_or_info
blob_info = None
headers[BLOB_KEY_HEADER] = str(blob_key)
if content_type:
if isinstance(content_type, six.text_type):
content_type = content_type.encode('utf-8')
headers['Content-Type'] = content_type
def send_attachment(filename):
if isinstance(filename, six.text_type):
filename_utf8 = filename.encode('utf-8')
headers['Content-Disposition'] = (
_CONTENT_DISPOSITION_FORMAT_UTF8 %
(filename_utf8, urllib.parse.quote(filename_utf8).encode('utf-8')))
else:
headers['Content-Disposition'] = (
_CONTENT_DISPOSITION_FORMAT % filename)
if save_as:
if isinstance(save_as, (bytes, six.text_type)):
send_attachment(save_as)
elif blob_info and save_as is True:
send_attachment(blob_info.filename)
else:
if not blob_info:
raise ValueError('Expected BlobInfo value for blob_key_or_info.')
else:
raise ValueError('Unexpected value for save_as.')
return headers