code: def _do_multipart_upload(self, stream, metadata, size, num_retries):
          
          data = stream.read(size)
          if len(data) < size:
              msg = _READ_LESS_THAN_SIZE.format(size, len(data))
              raise ValueError(msg)
  
          headers = _get_upload_headers(self._connection.USER_AGENT)
  
          upload_url = _MULTIPART_URL_TEMPLATE.format(project=self.project)
          upload = MultipartUpload(upload_url, headers=headers)
  
          if num_retries is not None:
              upload._retry_strategy = resumable_media.RetryStrategy(
                  max_retries=num_retries
              )
  
          response = upload.transmit(self._http, data, metadata, _GENERIC_CONTENT_TYPE)
  
          return response
docs: Perform a multipart upload.
  
          :type stream: IO[bytes]
          :param stream: A bytes IO object open for reading.
  
          :type metadata: dict
          :param metadata: The metadata associated with the upload.
  
          :type size: int
          :param size: The number of bytes to be uploaded (which will be read
                       from ``stream``). If not provided, the upload will be
                       concluded once ``stream`` is exhausted (or :data:`None`).
  
          :type num_retries: int
          :param num_retries: Number of upload retries. (Deprecated: This
                              argument will be removed in a future release.)
  
          :rtype: :class:`~requests.Response`
          :returns: The "200 OK" response object returned after the multipart
                    upload request.
          :raises: :exc:`ValueError` if the ``stream`` has fewer than ``size``
                   bytes remaining.