human
Complete this python program:
def get_serving_url_async(blob_key, size=None, crop=False, secure_url=None, filename=None, rpc=None):
assistant
#Here is the Python code you requested.

    """Obtain a url that will serve the underlying image - async version.
    This URL is served by a high-performance dynamic image serving infrastructure.
    This URL format also allows dynamic resizing and crop with certain
    restrictions. To get dynamic resizing and cropping, specify size and crop
    arguments, or simply append options to the end of the default url obtained via
    this call.  Here is an example:
    get_serving_url -> "http://lh3.ggpht.com/SomeCharactersGoesHere"
    To get a 32 pixel sized version (aspect-ratio preserved) simply append
    "=s32" to the url:
    "http://lh3.ggpht.com/SomeCharactersGoesHere=s32"
    To get a 32 pixel cropped version simply append "=s32-c":
    "http://lh3.ggpht.com/SomeCharactersGoesHere=s32-c"
    Available sizes are any integer in the range [0, 1600] and is available as
    IMG_SERVING_SIZES_LIMIT.
    Args:
    blob_key: BlobKey, BlobInfo, str, or unicode representation of BlobKey of
    blob to get URL of.
    size: int, size of resulting images
    crop: bool, True requests a cropped image, False a resized one.
    secure_url: bool, True requests a https url, False requests a http url.
    filename: The filename of a Google Storage object to get the URL of.
    rpc: Optional UserRPC object.
    Returns:
    A UserRPC whose result will be a string that is the serving url
    Raises:
    BlobKeyRequiredError: when no blobkey was specified in the ctor.
    UnsupportedSizeError: when size parameters uses unsupported sizes.
    BadRequestError: when crop/size are present in wrong combination, or a
    blob_key and a filename have been specified.
    TypeError: when secure_url is not a boolean type.
    AccessDeniedError: when the blobkey refers to a Google Storage object, and
    the application does not have permission to access the object.
    """
    if ((not blob_key) and (not filename)):
        raise BlobKeyRequiredError('A    Blobkey    or    a    filename    is    required    for    this    operation.')
    if (crop and (not size)):
        raise BadRequestError('Size    should    be    set    for    crop    operation')
    if ((size is not None) and ((size > IMG_SERVING_SIZES_LIMIT) or (size < 0))):
        raise UnsupportedSizeError('Unsupported    size')
    if (secure_url and (not isinstance(secure_url, bool))):
        raise TypeError('secure_url    must    be    boolean.')
    if (filename and blob_key):
        raise BadRequestError('Cannot    specify    a    blob_key    and    a    filename.')
    if filename:
        _blob_key = blobstore.create_gs_key(filename)
        readable_blob_key = filename
    else:
        _blob_key = _extract_blob_key(blob_key)
        readable_blob_key = blob_key
    request = images_service_pb.ImagesGetUrlBaseRequest()
    response = images_service_pb.ImagesGetUrlBaseResponse()
    request.set_blob_key(_blob_key)
    if secure_url:
        request.set_create_secure_url(secure_url)
    def get_serving_url_hook(rpc):
        'Check    success,    handle    exceptions,    and    return    converted    RPC    result.\n\n                Args:\n                        rpc:    A    UserRPC    object.\n\n                Returns:\n                        The    URL    for    serving    the    image.\n\n                Raises:\n                        See    docstring    for    get_serving_url    for    more    details.\n                '
        try:
            rpc.check_success()
        except apiproxy_errors.ApplicationError as e:
            raise _ToImagesError(e, readable_blob_key)
        url = rpc.response.url()
        if (size is not None):
            url += ('=s%s' % size)
        if crop:
            url += '-c'
        return url
    return _make_async_call(rpc, 'GetUrlBase', request, response, get_serving_url_hook, None)