def s3_download(source, destination,
                exists_strategy=ExistsStrategy.RAISE,
                profile_name=None):
    """
    Copy a file from an S3 source to a local destination.

    Parameters
    ----------
    source : str
        Path starting with s3://, e.g. 's3://bucket-name/key/foo.bar'
    destination : str
    exists_strategy : {'raise', 'replace', 'abort'}
        What is done when the destination already exists?
        * `ExistsStrategy.RAISE` means a RuntimeError is raised,
        * `ExistsStrategy.REPLACE` means the local file is replaced,
        * `ExistsStrategy.ABORT` means the download is not done.
    profile_name : str, optional
        AWS profile

    Raises
    ------
    botocore.exceptions.NoCredentialsError
        Botocore is not able to find your credentials. Either specify
        profile_name or add the environment variables AWS_ACCESS_KEY_ID,
        AWS_SECRET_ACCESS_KEY and AWS_SESSION_TOKEN.
        See https://boto3.readthedocs.io/en/latest/guide/configuration.html
    """
    if not isinstance(exists_strategy, ExistsStrategy):
        raise ValueError('exists_strategy \'{}\' is not in {}'
                         .format(exists_strategy, ExistsStrategy))
    session = boto3.Session(profile_name=profile_name)
    s3 = session.resource('s3')
    bucket_name, key = _s3_path_split(source)
    if os.path.isfile(destination):
        if exists_strategy is ExistsStrategy.RAISE:
            raise RuntimeError('File \'{}\' already exists.'
                               .format(destination))
        elif exists_strategy is ExistsStrategy.ABORT:
            return
    s3.Bucket(bucket_name).download_file(key, destination)