class_docstr: Store and load checkpoints from S3.
code: def __init__(
      self,
      bucket: str,
      access_key: Optional[str] = None,
      secret_key: Optional[str] = None,
      endpoint_url: Optional[str] = None,
      prefix: Optional[str] = None,
      temp_dir: Optional[str] = None,
  ) -> None:
      super().__init__(
          temp_dir if temp_dir is not None else tempfile.gettempdir()
      )
      import boto3
  
      from determined.common.storage import boto3_credential_manager
  
      boto3_credential_manager.initialize_boto3_credential_providers()
      self.bucket_name = bucket
      self.s3 = boto3.resource(
          "s3",
          endpoint_url=endpoint_url,
          aws_access_key_id=access_key,
          aws_secret_access_key=secret_key,
      )
      self.bucket = self.s3.Bucket(self.bucket_name)
  
      self.prefix = normalize_prefix(prefix)
  
      # Detect if we are talking to minio, because boto3 has a client-side bug parsing the output
      # of the minio server.
      self._use_minio_workaround = False
      if endpoint_url is not None:
          try:
              r = requests.get(endpoint_url)
          except ConnectionError:
              pass
          else:
              if r.headers.get("Server", "").lower() == "minio":
                  self._use_minio_workaround = True
                  logger.info(
                      "MinIO backend detected.  To work around a boto3 bug, empty directories"
                      "will not be uploaded in checkpoints."
                  )
  
file_path: determined/harness/determined/common/storage/s3.py
imports: import logging
  import os
  import re
  import tempfile
  from typing import Dict, List, Optional, Union
  import requests
  from determined import errors
  from determined.common import storage, util
label_desc: Use image node_id 1 to create a new S3StorageManager object from inherited base classes: storage with example: obj = S3StorageManager(bucket, access_key, secret_key, endpoint_url, prefix, temp_dir)