def _quote_source_header(value):
    result = VERSION_ID_SUFFIX.search(value)
    if result is None:
        return percent_encode(value, safe=SAFE_CHARS + '/')
    else:
        first, version_id = value[:result.start()], value[result.start():]
        return percent_encode(first, safe=SAFE_CHARS + '/') + version_id
 def _render_uri_template(self, uri_template, params):
     # We need to handle two cases::
     #
     # /{Bucket}/foo
     # /{Key+}/bar
     # A label ending with '+' is greedy.  There can only
     # be one greedy key.
     encoded_params = {}
     for template_param in re.findall(r'{(.*?)}', uri_template):
         if template_param.endswith('+'):
             encoded_params[template_param] = percent_encode(
                 params[template_param[:-1]], safe='/~')
         else:
             encoded_params[template_param] = percent_encode(
                 params[template_param])
     return uri_template.format(**encoded_params)
def _quote_source_header_from_dict(source_dict):
    try:
        bucket = source_dict['Bucket']
        key = percent_encode(source_dict['Key'], safe=SAFE_CHARS + '/')
        version_id = source_dict.get('VersionId')
    except KeyError as e:
        raise ParamValidationError(report='Missing required parameter: %s' %
                                   str(e))
    final = '%s/%s' % (bucket, key)
    if version_id is not None:
        final += '?versionId=%s' % version_id
    return final