code: def save_bytes(
      self, path_and_bytes_iter, overwrite=False, len_hint=0
  ):
      def _convert():
          # Output format is the same as what is needed for S3PutObject:
          # key, value, path, content_type, metadata
          for path, obj in path_and_bytes_iter:
              if isinstance(obj, tuple):
                  yield path, obj[0], None, None, obj[1]
              else:
                  yield path, obj, None, None, None
  
      with S3(
          s3root=self.datastore_root,
          tmproot=ARTIFACT_LOCALROOT,
          external_client=self.s3_client,
      ) as s3:
          # HACK: The S3 datatools we rely on does not currently do a good job
          # determining if uploading things in parallel is more efficient than
          # serially. We use a heuristic for now where if we have a lot of
          # files, we will go in parallel and if we have few files, we will
          # serially upload them. This is not ideal because there is also a size
          # factor and one very large file with a few other small files, for
          # example, would benefit from a parallel upload.
          #
          # In the case of save_artifacts, currently len_hint is based on the
          # total number of artifacts, not taking into account how many of them
          # already exist in the CAS, i.e. it can be a gross overestimate. As a
          # result, it is possible we take a latency hit by using put_many only
          # for a few artifacts.
          #
          # A better approach would be to e.g. write all blobs to temp files
          # and based on the total size and number of files use either put_files
          # (which avoids re-writing the files) or s3.put sequentially.
          if len_hint > 10:
              # Use put_many
              s3.put_many(starmap(S3PutObject, _convert()), overwrite)
          else:
              # Sequential upload
              for key, obj, _, _, metadata in _convert():
                  s3.put(
                      key, obj, overwrite=overwrite, metadata=metadata
                  )
  
file_path: metaflow/metaflow/plugins/datastores/s3_storage.py
imports: import os
  from itertools import starmap
  from metaflow.plugins.datatools.s3.s3 import S3, S3Client, S3PutObject, check_s3_deps
  from metaflow.metaflow_config import DATASTORE_SYSROOT_S3, ARTIFACT_LOCALROOT
  from metaflow.datastore.datastore_storage import CloseAfterUse, DataStoreStorage
label_desc: Use image node_id 7 for calling the S3Storage obj's underlying member method code with example usage: obj.save_bytes(path_and_bytes_iter, overwrite, len_hint) without return types