curryer.kernels.path_utils ========================== .. py:module:: curryer.kernels.path_utils .. autoapi-nested-parse:: Kernel utilities for path handling and temp directory management. This module provides utility functions used across the kernels package, particularly for handling SPICE's 80-character path limitation. Attributes ---------- .. autoapisummary:: curryer.kernels.path_utils.logger Functions --------- .. autoapisummary:: curryer.kernels.path_utils.get_short_temp_dir curryer.kernels.path_utils.create_short_symlink curryer.kernels.path_utils.get_path_strategy_config curryer.kernels.path_utils._is_file_property curryer.kernels.path_utils._convert_paths_to_strings curryer.kernels.path_utils.copy_to_short_path curryer.kernels.path_utils.update_invalid_paths Module Contents --------------- .. py:data:: logger .. py:function:: get_short_temp_dir() -> pathlib.Path Get a short base directory for temporary files. Returns a platform-appropriate short path that respects environment variables for customization. This avoids SPICE's 80-character path limit by using short base directories. :returns: A short base path for temporary directories. :rtype: Path :raises ValueError: If CURRYER_TEMP_DIR is set to an invalid path (too long). .. rubric:: Notes Priority order: 1. CURRYER_TEMP_DIR environment variable (if set and validated) 2. /tmp on Unix (bypasses macOS TMPDIR which can be longer by default) 3. C:\Temp on Windows (shorter than default AppData path) 4. Python's tempfile.gettempdir() (fallback, could be 40 characters) Why not just use tempfile.gettempdir()? - On macOS, TMPDIR is set to /var/folders/.../T (~49 chars) - This leaves only ~30 chars for filenames - We prefer /tmp (4 chars) to maximize filename space (75 chars) - Users can still override with CURRYER_TEMP_DIR if needed .. rubric:: Examples >>> import os >>> os.environ["CURRYER_TEMP_DIR"] = "/custom/path" >>> get_short_temp_dir() PosixPath('/custom/path') .. py:function:: create_short_symlink(source_path: pathlib.Path, temp_dir: pathlib.Path) -> pathlib.Path | None Create a symlink in a short temp directory. Uses a simple naming scheme since symlinks are cheap to create/replace. If a symlink already exists, it's replaced (idempotent operation). :param source_path: Original file path :type source_path: Path :param temp_dir: Short base directory for symlink (e.g., /tmp) :type temp_dir: Path :returns: Path to symlink if successful, None if creation failed :rtype: Path | None .. rubric:: Notes - Works on Linux/macOS by default - May fail on Windows or restricted environments - Failures are logged but don't raise exceptions - Idempotent: reusing the same symlink name is safe .. py:function:: get_path_strategy_config() -> dict Read path shortening configuration from environment variables. Supported variables: - CURRYER_DISABLE_COPY: "true" to disable file copying (default: "false") - CURRYER_TEMP_DIR: Custom short temp directory (handled by get_short_temp_dir()) :returns: Configuration with keys: disable_copy, try_symlink, try_copy :rtype: dict .. rubric:: Examples >>> import os >>> os.environ["CURRYER_DISABLE_COPY"] = "true" >>> config = get_path_strategy_config() >>> config["try_copy"] False .. py:function:: _is_file_property(key: str) -> bool Check if a property key likely contains file paths. :param key: Property key name :type key: str :returns: True if the property likely contains file paths :rtype: bool .. rubric:: Notes Two matching strategies (either one triggers processing): 1. Regex: Matches keys ending in _FILE or _FILE_NAME (e.g., LEAPSECONDS_FILE, INPUT_DATA_FILE) This handles most SPICE tool config files which follow this naming convention 2. Explicit list: Known meta-kernel properties that don't follow the _FILE convention (clock_kernel, frame_kernel, etc.) - these are standard SPICE meta-kernel keys This dual approach covers both user configs and meta-kernel properties .. py:function:: _convert_paths_to_strings(obj) Recursively convert all Path objects to strings in a data structure. :param obj: Object to convert (dict, list, Path, or other) :type obj: any :returns: Object with all Path instances converted to strings :rtype: any .. py:function:: copy_to_short_path(source_path: pathlib.Path, temp_dir: pathlib.Path, max_len: int) -> pathlib.Path | None Copy file to temp directory with short path. Returns Path object for consistency with create_short_symlink(). :param source_path: Original file path :type source_path: Path :param temp_dir: Temporary directory base :type temp_dir: Path :param max_len: Maximum path length (default: 80 for SPICE) :type max_len: int :returns: Path to copied file if successful, None if copy failed :rtype: Path | None .. rubric:: Notes Uses tempfile.mkstemp() for unique naming. Warns if temp directory base path is too long. .. py:function:: update_invalid_paths(configs, max_len=80, try_copy=True, parent_dir=None, temp_dir=None) Update invalid paths (too long) by creating symlinks or copying to short temp paths. Attempts to fix paths that exceed the maximum length by trying strategies in order: 1. Symlink to temp directory with short path (always tried first - zero cost) 2. Copy file to temp directory with short path (fallback if symlink fails) :param configs: Configuration dictionary to update :type configs: dict :param max_len: Maximum path length (default: 80 for SPICE string values) :type max_len: int :param try_copy: Try to copy file to temp directory with short path (default: True) :type try_copy: bool :param parent_dir: Parent directory for resolving relative paths :type parent_dir: Path :param temp_dir: Base directory for temp copies (default: uses tempfile.gettempdir()) :type temp_dir: Path :returns: (updated_config_dict, list_of_temp_files) - updated_config_dict: Configuration with shortened paths - list_of_temp_files: List of temp file paths created (for cleanup) :rtype: tuple .. seealso:: :py:obj:`https` //naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/kernel.html