Source code for dgs.utils.files

"""
Contains helper functions for loading and interacting with files and paths.
"""

import json
import os

from dgs.utils.constants import PROJECT_ROOT
from dgs.utils.exceptions import InvalidPathException
from dgs.utils.types import FilePath


[docs] def is_project_file(filepath: FilePath, root: FilePath = PROJECT_ROOT) -> bool: """Returns whether this filepath is an existing path in this project. Args: filepath (FilePath): The path to check. root (FilePath): The absolute path to the root of the project. It can be modified to point to other locations. Default: PROJECT_ROOT. Returns: bool: True if the ``filepath`` is a file inside ``root``, False otherwise. """ return os.path.isfile(os.path.normpath(os.path.join(root, filepath)))
[docs] def is_project_dir(filepath: FilePath, root: FilePath = PROJECT_ROOT) -> bool: """Returns whether this filepath is a path of an existing directory in this project. Args: filepath (FilePath): The path to check. root (FilePath): The absolute path to the root of the project. It can be modified to point to other locations. Default: PROJECT_ROOT. Returns: bool: True if the ``filepath`` is a directory inside ``root``, False otherwise. """ return os.path.isdir(os.path.join(root, filepath))
[docs] def is_abs_file(filepath: FilePath) -> bool: """Returns whether this filepath is an existing files absolute path. Args: filepath (FilePath): The path to check. Returns: bool: True if the filepath is an absolute file, False otherwise. """ return os.path.isfile(filepath) and os.path.isabs(filepath)
[docs] def is_abs_dir(filepath: FilePath) -> bool: """Returns whether this filepath is an existing absolute directory. Args: filepath (FilePath): The path to check. Returns: bool: True if the filepath is an absolute directory, False otherwise.""" return os.path.isdir(filepath) and os.path.isabs(filepath)
[docs] def is_file(filepath: FilePath) -> bool: """Returns whether this filepath is an existing file either everywhere or from this project. Args: filepath (FilePath): The path to check. Returns: bool: True if the filepath is either a local, global, or absolute path, False otherwise.""" return os.path.isfile(filepath) or is_abs_file(filepath) or is_project_file(filepath)
[docs] def is_dir(filepath: FilePath) -> bool: """Returns whether this filepath is an existing directory either everywhere or from this project. Args: filepath (FilePath): The path to check. Returns: bool: True if the filepath is either a local, global, or absolute directory, False otherwise.""" return os.path.isdir(filepath) or is_abs_dir(filepath) or is_project_dir(filepath)
[docs] def to_abspath(filepath: FilePath, root: FilePath = PROJECT_ROOT) -> FilePath: """Given a path return the absolute path of this file or directory. Will first check if the filepath already is an absolute file or path and then if it is a local project file. Args: filepath: str or path object as local or abspath. root (FilePath): The absolute path to the root of the project. It can be modified to point to other locations. Default: PROJECT_ROOT. Returns: A valid path, if one exists, as an absolute and normalized path. Raises: InvalidPathException: If the path doesn't exist globally or locally. """ if is_abs_file(filepath) or is_abs_dir(filepath): return os.path.normpath(filepath) if is_project_file(filepath, root=root) or is_project_dir(filepath, root=root): return os.path.normpath(os.path.join(root, filepath)) raise InvalidPathException(f"{filepath} is neither local nor global path.")
[docs] def mkdir_if_missing(dirname: FilePath) -> None: # pragma: no cover """Creates leaf directory and all intermediates if it is missing.""" if not os.path.exists(dirname): os.makedirs(dirname, exist_ok=True)
[docs] def read_json(filepath: FilePath) -> dict[any, any] | list[any]: """Reads json file from a path. Args: filepath: str or path object with ending Returns: Loaded json from file as a dictionary. Raises: InvalidPathException: If filepath doesn't contain `.json` ending. """ if not filepath.endswith(".json"): raise InvalidPathException(f"Presumed JSON file {filepath} does not have .json ending.") fpath = to_abspath(filepath) with open(fpath, encoding="utf-8") as f: obj = json.load(f) return obj
[docs] def write_json(obj: dict, filepath: FilePath): # pragma: no cover """Writes to a json file. Args: obj: the dict or JSON to be written. filepath: The absolute path to the .json file that should be created. """ mkdir_if_missing(os.path.dirname(filepath)) with open(filepath, "w", encoding="utf-8") as f: json.dump(obj, f, indent=None, separators=(",", ":"))