def copy_dir(bucket_name, src_path, dest_path,<EOL>aws_access_key_id=None, aws_secret_access_key=None,<EOL>aws_profile=None,<EOL>surrogate_key=None, cache_control=None,<EOL>surrogate_control=None,<EOL>create_directory_redirect_object=True):
if not src_path.endswith('<STR_LIT:/>'):<EOL><INDENT>src_path += '<STR_LIT:/>'<EOL><DEDENT>if not dest_path.endswith('<STR_LIT:/>'):<EOL><INDENT>dest_path += '<STR_LIT:/>'<EOL><DEDENT>common_prefix = os.path.commonprefix([src_path, dest_path])<EOL>if common_prefix == src_path:<EOL><INDENT>msg = '<STR_LIT>'.format(<EOL>common_prefix, src_path)<EOL>raise RuntimeError(msg)<EOL><DEDENT>if common_prefix == dest_path:<EOL><INDENT>msg = '<STR_LIT>'.format(<EOL>common_prefix, dest_path)<EOL>raise RuntimeError(msg)<EOL><DEDENT>delete_dir(bucket_name, dest_path,<EOL>aws_access_key_id, aws_secret_access_key)<EOL>session = boto3.session.Session(<EOL>aws_access_key_id=aws_access_key_id,<EOL>aws_secret_access_key=aws_secret_access_key,<EOL>profile_name=aws_profile)<EOL>s3 = session.resource('<STR_LIT>')<EOL>bucket = s3.Bucket(bucket_name)<EOL>for src_obj in bucket.objects.filter(Prefix=src_path):<EOL><INDENT>src_rel_path = os.path.relpath(src_obj.key, start=src_path)<EOL>dest_key_path = os.path.join(dest_path, src_rel_path)<EOL>head = s3.meta.client.head_object(Bucket=bucket_name,<EOL>Key=src_obj.key)<EOL>metadata = head['<STR_LIT>']<EOL>content_type = head['<STR_LIT>']<EOL>if cache_control is None and '<STR_LIT>' in head:<EOL><INDENT>cache_control = head['<STR_LIT>']<EOL><DEDENT>if surrogate_control is not None:<EOL><INDENT>metadata['<STR_LIT>'] = surrogate_control<EOL><DEDENT>if surrogate_key is not None:<EOL><INDENT>metadata['<STR_LIT>'] = surrogate_key<EOL><DEDENT>s3.meta.client.copy_object(<EOL>Bucket=bucket_name,<EOL>Key=dest_key_path,<EOL>CopySource={'<STR_LIT>': bucket_name, '<STR_LIT>': src_obj.key},<EOL>MetadataDirective='<STR_LIT>',<EOL>Metadata=metadata,<EOL>ACL='<STR_LIT>',<EOL>CacheControl=cache_control,<EOL>ContentType=content_type)<EOL><DEDENT>if create_directory_redirect_object:<EOL><INDENT>dest_dirname = dest_path.rstrip('<STR_LIT:/>')<EOL>obj = bucket.Object(dest_dirname)<EOL>metadata = {'<STR_LIT>': '<STR_LIT:true>'}<EOL>obj.put(Body='<STR_LIT>',<EOL>ACL='<STR_LIT>',<EOL>Metadata=metadata,<EOL>CacheControl=cache_control)<EOL><DEDENT>
Copy objects from one directory in a bucket to another directory in
    the same bucket.

    Object metadata is preserved while copying, with the following exceptions:

    - If a new surrogate key is provided it will replace the original one.
    - If ``cache_control`` and ``surrogate_control`` values are provided they
      will replace the old one.

    Parameters
    ----------
    bucket_name : `str`
        Name of an S3 bucket.
    src_path : `str`
        Source directory in the S3 bucket. The ``src_path`` should ideally end
        in a trailing `'/'`. E.g. `'dir/dir2/'`.
    dest_path : `str`
        Destination directory in the S3 bucket. The ``dest_path`` should
        ideally end in a trailing `'/'`. E.g. `'dir/dir2/'`. The destination
        path cannot contain the source path.
    aws_access_key_id : `str`
        The access key for your AWS account. Also set
        ``aws_secret_access_key``.
    aws_secret_access_key : `str`
        The secret key for your AWS account.
    aws_profile : `str`, optional
        Name of AWS profile in :file:`~/.aws/credentials`. Use this instead
        of ``aws_access_key_id`` and ``aws_secret_access_key`` for file-based
        credentials.
    surrogate_key : `str`, optional
        The surrogate key to insert in the header of all objects in the
        ``x-amz-meta-surrogate-key`` field. This key is used to purge
        builds from the Fastly CDN when Editions change.
        If `None` then no header will be set.
        If the object already has a ``x-amz-meta-surrogate-key`` header then
        it will be replaced.
    cache_control : `str`, optional
        This sets (and overrides) the ``Cache-Control`` header on the copied
        files. The ``Cache-Control`` header specifically dictates how content
        is cached by the browser (if ``surrogate_control`` is also set).
    surrogate_control : `str`, optional
        This sets (and overrides) the ``x-amz-meta-surrogate-control`` header
        on the copied files. The ``Surrogate-Control``
        or ``x-amz-meta-surrogate-control`` header is used in priority by
        Fastly to givern it's caching. This caching policy is *not* passed
        to the browser.
    create_directory_redirect_object : `bool`, optional
        Create a directory redirect object for the root directory. The
        directory redirect object is an empty S3 object named after the
        directory (without a trailing slash) that contains a
        ``x-amz-meta-dir-redirect=true`` HTTP header. LSST the Docs' Fastly
        VCL is configured to redirect requests for a directory path to the
        directory's ``index.html`` (known as *courtesy redirects*).

    Raises
    ------
    ltdconveyor.s3.S3Error
        Thrown by any unexpected faults from the S3 API.
    RuntimeError
        Thrown when the source and destination directories are the same.