def sync_dir(source, target, verbose=True, excludes=None):
    """
    Sync a directory from source to target (either local to s3, s3 to s3, s3 to local)

    Parameters
    ----------
    source: str
        Directory from which we want to sync files

    target: str
        Directory to which all files will be synced

    verbose: bool, default: True
        If True, log some helpful messages
    """
    assert source.startswith('s3://') or target.startswith('s3://')
    command_str = "aws s3 sync --quiet --acl bucket-owner-full-control {} {}".format(source, target)
    if excludes:
        for exclude in excludes:
            command_str += f" --exclude '{exclude}'"
    if verbose:
        LOG.info("Syncing with '{}'".format(command_str))
    try:
        subprocess.check_output(command_str, shell=True)
    except subprocess.CalledProcessError as e:
        LOG.error("{} failed with error code {}".format(command_str, e.returncode))
        LOG.error(e.output)
    if verbose:
        LOG.info("Done syncing")

    Sync a directory from source to target (either local to s3, s3 to s3, s3 to local)

    Parameters
    ----------
    source: str
        Directory from which we want to sync files

    target: str
        Directory to which all files will be synced

    verbose: bool, default: True
        If True, log some helpful messages
    
tridet/utils/s3.py