code: def generate(self) -> Generator[FileChunk, Any, None]:
      chunk_size = self._get_chunk_size()
      last_offset = 0
      last_change: Optional = (
          os.stat(self._filename).st_mtime if self._filename else None
      )
      while last_offset < self._total_size:
          chunk = self._fobj.read(chunk_size)
          if chunk:
              if (
                  last_change
                  and last_change < os.stat(self._filename).st_mtime
              ):
                  raise UploadedFileChanged(self._filename)
              if isinstance(chunk, str):
                  chunk = chunk.encode("utf-8")
              new_offset = last_offset + len(chunk)
              yield FileChunk(
                  data=chunk, start=last_offset, end=new_offset
              )
              last_offset = new_offset
  
file_path: neptune-client/src/neptune/common/storage/datastream.py
imports: import dataclasses
  import io
  import math
  import os
  import tarfile
  from typing import Any, Generator, Optional
  from neptune.common.backends.api_model import MultipartConfig
  from neptune.common.exceptions import InternalClientError, UploadedFileChanged
label_desc: Use image node_id 3 for calling the FileChunker obj's underlying member method code with example usage: obj.generate() without return types