code: def package_user_module_file(
      instance_name: str, module_path: str, pipeline_root: str
  ) -> Tuple[str, str]:
      """Package the given user module file into a Python Wheel package.
  
      Args:
          instance_name: Name of the component instance, for creating a unique wheel
            package name.
          module_path: Path to the module file to be packaged.
          pipeline_root: Text
  
      Returns:
          dist_file_path: Path to the generated wheel file.
          user_module_path: Path for referencing the user module when stored
            as the _MODULE_PATH_KEY execution property. Format should be treated
            as opaque by the user.
  
      Raises:
          RuntimeError: When wheel building fails.
      """
      module_path = os.path.abspath(io_utils.ensure_local(module_path))
      if not module_path.endswith(".py"):
          raise ValueError(
              f'Module path {module_path!r} is not a ".py" file.'
          )
      if not os.path.exists(module_path):
          raise ValueError(
              f"Module path {module_path!r} does not exist."
          )
  
      user_module_dir, module_file_name = os.path.split(module_path)
      user_module_name = re.sub(r"\.py$", "", module_file_name)
      source_files = []
  
      # Discover all Python source files in this directory for inclusion.
      for file_name in os.listdir(user_module_dir):
          if file_name.endswith(".py"):
              source_files.append(file_name)
      module_names = []
      for file_name in source_files:
          if file_name in (
              _EPHEMERAL_SETUP_PY_FILE_NAME,
              "__init__.py",
          ):
              continue
          module_name = re.sub(r"\.py$", "", file_name)
          module_names.append(module_name)
  
      # Set up build directory.
      build_dir = tempfile.mkdtemp()
      for source_file in source_files:
          shutil.copyfile(
              os.path.join(user_module_dir, source_file),
              os.path.join(build_dir, source_file),
          )
  
      # Generate an ephemeral wheel for this module.
      logging.info(
          "Generating ephemeral wheel package for %r (including modules: %s).",
          module_path,
          module_names,
      )
  
      version_hash = _get_version_hash(user_module_dir, source_files)
      logging.info(
          "User module package has hash fingerprint version %s.",
          version_hash,
      )
  
      setup_py_path = os.path.join(
          build_dir, _EPHEMERAL_SETUP_PY_FILE_NAME
      )
      with open(setup_py_path, "w", encoding="utf-8") as f:
          f.write(
              _get_ephemeral_setup_py_contents(
                  f"tfx-user-code-{instance_name}",
                  f"0.0+{version_hash}",
                  module_names,
              )
          )
  
      temp_dir = tempfile.mkdtemp()
      dist_dir = tempfile.mkdtemp()
      bdist_command = [
          sys.executable,
          setup_py_path,
          "bdist_wheel",
          "--bdist-dir",
          temp_dir,
          "--dist-dir",
          dist_dir,
      ]
      logging.info("Executing: %s", bdist_command)
      try:
          subprocess.check_call(bdist_command, cwd=build_dir)
      except subprocess.CalledProcessError as e:
          raise RuntimeError("Failed to build wheel.") from e
  
      dist_files = os.listdir(dist_dir)
      if len(dist_files) != 1:
          raise RuntimeError(
              f"Unexpectedly found {len(dist_files)} output files "
              f"in wheel output directory {dist_dir}."
          )
      build_dist_file_path = os.path.join(dist_dir, dist_files[0])
      # Copy wheel file atomically to wheel staging directory.
      dist_wheel_directory = os.path.join(pipeline_root, "_wheels")
      dist_file_path = os.path.join(dist_wheel_directory, dist_files[0])
      temp_dist_file_path = dist_file_path + ".tmp"
      fileio.makedirs(dist_wheel_directory)
      fileio.copy(
          build_dist_file_path, temp_dist_file_path, overwrite=True
      )
      fileio.rename(temp_dist_file_path, dist_file_path, overwrite=True)
      logging.info(
          (
              "Successfully built user code wheel distribution at %r; target user "
              "module is %r."
          ),
          dist_file_path,
          user_module_name,
      )
  
      # Encode the user module key as a specification of a user module name within
      # a packaged wheel path.
      assert "@" not in user_module_name, (
          "Unexpected invalid module name: " + user_module_name
      )
      user_module_path = f"{user_module_name}@{dist_file_path}"
      logging.info("Full user module path is %r", user_module_path)
  
      return dist_file_path, user_module_path
  
imports: import hashlib
  import os
  import re
  import shutil
  import struct
  import subprocess
  import sys
  import tempfile
  from typing import Any, Callable, Dict, List, Optional, Tuple
  from absl import logging
  from tfx.dsl.components.base import base_component
  from tfx.dsl.io import fileio
  from tfx.utils import import_utils
  from tfx.utils import io_utils
label_desc: Use image node_id 7 for calling a global function with example usage: package_user_module_file(instance_name, module_path, pipeline_root) and returns: dist_file_path,  user_module_path