# Buggy code
def get_docs_sites_urls(self, resource_identifier=None):
    """
    Get URLs for a resource for all data docs sites.

    This function will return URLs for any configured site even if the sites have not
    been built yet.

    :param resource_identifier: optional. It can be an identifier of ExpectationSuite's,
            ValidationResults and other resources that have typed identifiers.
            If not provided, the method will return the URLs of the index page.
    :return: a list of URLs. Each item is the URL for the resource for a data docs site
    """

    site_urls = []

    site_names = None
    sites = self._project_config_with_variables_substituted.data_docs_sites
    if sites:
        logger.debug("Found data_docs_sites.")

        for site_name, site_config in sites.items():
            if (site_names and site_name in site_names) or not site_names:
                complete_site_config = site_config
                module_name = "great_expectations.render.renderer.site_builder"
                site_builder = instantiate_class_from_config(
                    config=complete_site_config,
                    runtime_environment={
                        "data_context": self,
                        "root_directory": self.root_directory,
                    },
                    config_defaults={"module_name": module_name},
                )
                if not site_builder:
                    raise ge_exceptions.ClassInstantiationError(
                        module_name=module_name,
                        package_name=None,
                        class_name=complete_site_config["class_name"],
                    )
                url = site_builder.get_resource_url(
                    resource_identifier=resource_identifier
                )
                site_urls.append({"site_name": site_name, "site_url": url})

    return site_urls


# Traceback (botocore.exceptions.ClientError)
Running great_expectations docs build --site-name local_site
Building Data Docs...
The following Data Docs sites were built:
- local_site: file:///great_expectations/uncommitted/data_docs/local_site/index.html
Traceback (most recent call last):
File "/usr/local/bin/great_expectations", line 8, in <module>
sys.exit(main())
File "/usr/local/lib/python3.7/site-packages/great_expectations/cli/cli.py", line 67, in main
cli()
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 829, in __call__
return self.main(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 782, in main
rv = self.invoke(ctx)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1259, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 1066, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/usr/local/lib/python3.7/site-packages/click/core.py", line 610, in invoke
return callback(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/great_expectations/cli/docs.py", line 40, in docs_build
build_docs(context, site_name=site_name, view=view)
File "/usr/local/lib/python3.7/site-packages/great_expectations/cli/docs.py", line 147, in build_docs
context.open_data_docs()
File "/usr/local/lib/python3.7/site-packages/great_expectations/core/usage_statistics/usage_statistics.py", line 215, in usage_statistics_wrapped_method
result = func(*args, **kwargs)
File "/usr/local/lib/python3.7/site-packages/great_expectations/data_context/data_context.py", line 428, in open_data_docs
data_docs_urls = self.get_docs_sites_urls(resource_identifier=resource_identifier)
File "/usr/local/lib/python3.7/site-packages/great_expectations/data_context/data_context.py", line 411, in get_docs_sites_urls
url = site_builder.get_resource_url(resource_identifier=resource_identifier)
File "/usr/local/lib/python3.7/site-packages/great_expectations/render/renderer/site_builder.py", line 253, in get_resource_url
return self.target_store.get_url_for_resource(resource_identifier=resource_identifier)
File "/usr/local/lib/python3.7/site-packages/great_expectations/data_context/store/html_site_store.py", line 168, in get_url_for_resource
return store_backend.get_url_for_key(key)
File "/usr/local/lib/python3.7/site-packages/great_expectations/data_context/store/tuple_store_backend.py", line 380, in get_url_for_key
location = boto3.client('s3').get_bucket_location(Bucket=self.bucket)['LocationConstraint']
File "/usr/local/lib/python3.7/site-packages/botocore/client.py", line 357, in _api_call
return self._make_api_call(operation_name, kwargs)
File "/usr/local/lib/python3.7/site-packages/botocore/client.py", line 661, in _make_api_call
raise error_class(parsed_response, operation_name)
botocore.exceptions.ClientError: An error occurred (InvalidAccessKeyId) when calling the GetBucketLocation operation: The AWS Access Key Id you provided does not exist in our records.

# Fixed code
def get_docs_sites_urls(
    self, resource_identifier=None, site_name: Optional[str] = None
) -> List[Dict[str, str]]:
    """
    Get URLs for a resource for all data docs sites.

    This function will return URLs for any configured site even if the sites
    have not been built yet.

    Args:
        resource_identifier (object): optional. It can be an identifier of
            ExpectationSuite's, ValidationResults and other resources that
            have typed identifiers. If not provided, the method will return
            the URLs of the index page.
        site_name: Optionally specify which site to open. If not specified,
            return all urls in the project.

    Returns:
        list: a list of URLs. Each item is the URL for the resource for a
            data docs site
    """
    sites = self._project_config_with_variables_substituted.data_docs_sites
    if not sites:
        logger.debug("Found no data_docs_sites.")
        return []
    logger.debug(f"Found {len(sites)} data_docs_sites.")

    if site_name:
        if site_name not in sites.keys():
            raise ge_exceptions.DataContextError(
                f"Could not find site named {site_name}. Please check your configurations"
            )
        site = sites[site_name]
        site_builder = self._load_site_builder_from_site_config(site)
        url = site_builder.get_resource_url(resource_identifier=resource_identifier)
        return [{"site_name": site_name, "site_url": url}]

    site_urls = []
    for _site_name, site_config in sites.items():
        site_builder = self._load_site_builder_from_site_config(site_config)
        url = site_builder.get_resource_url(resource_identifier=resource_identifier)
        site_urls.append({"site_name": _site_name, "site_url": url})

    return site_urls