class_docstr: Stores artifacts as files in a remote directory, via ftp.
class_docstr_tok: ["Stores","artifacts","as","files","in","a","remote","directory",",","via","ftp","."]
code: def log_artifacts(self, local_dir, artifact_path=None):
      dest_path = (
          posixpath.join(self.path, artifact_path)
          if artifact_path
          else self.path
      )
  
      local_dir = os.path.abspath(local_dir)
      for root, _, filenames in os.walk(local_dir):
          upload_path = dest_path
          if root != local_dir:
              rel_path = os.path.relpath(root, local_dir)
              rel_upload_path = relative_path_to_artifact_path(rel_path)
              upload_path = posixpath.join(dest_path, rel_upload_path)
          if not filenames:
              with self.get_ftp_client() as ftp:
                  self._mkdir(ftp, upload_path)
          for f in filenames:
              if os.path.isfile(os.path.join(root, f)):
                  self.log_artifact(os.path.join(root, f), upload_path)
  
imports: import ftplib
  import os
  import posixpath
  import urllib.parse
  from contextlib import contextmanager
  from ftplib import FTP
  from urllib.parse import unquote
  from mlflow.entities.file_info import FileInfo
  from mlflow.exceptions import MlflowException
  from mlflow.store.artifact.artifact_repo import ArtifactRepository
  from mlflow.utils.file_utils import relative_path_to_artifact_path
label_desc: Use image node_id 7 for calling the FTPArtifactRepository obj's underlying member method code with example usage: obj.log_artifacts(local_dir, artifact_path) without return types