File Tools
pymdtools.filetools provides high-level helpers for text files and local
template folders. It builds on pymdtools.common for path normalization,
file checks, encoding detection, backups, and writes.
Template Helpers
Template helpers resolve files under a template/ directory next to the
current module or next to a caller-provided start_folder.
from pymdtools.filetools import get_template_file
html = get_template_file("emails/welcome.html", start_folder=".")
Template paths are intentionally constrained:
paths must be relative;
parent traversal with
..is rejected;resolved files must remain inside the
template/directory.
FileName
FileName stores one normalized path and exposes convenient properties for
the complete path, basename, parent directory, and suffix.
from pymdtools.filetools import FileName
name = FileName("docs/readme.txt")
name.filename = "README.md"
name.filename_ext = ".rst"
FileName only manipulates the stored path value. It does not create, move,
or rename files on disk.
FileContent
FileContent extends FileName with an in-memory text buffer.
from pymdtools.filetools import FileContent
content = FileContent("README.md")
text = content.content or ""
content.content = text.replace("old", "new")
content.write()
When backup is enabled, writing over an existing file creates a backup first.
Public API
pymdtools.filetools
High-level helpers for working with template files and text file content.
This module builds on pymdtools.common instead of reimplementing low-level
filesystem behavior. It provides:
get_template_file: read a file from a localtemplate/directory.get_template_files_in_folder: list direct files under a template subfolder.FileName: keep and edit a normalized file path by path/name/suffix.FileContent: keep a file path together with an editable text buffer.
The module is intentionally text-oriented. Binary detection, encoding detection,
atomic writes, backups, and path validation are delegated to pymdtools.common.
- class pymdtools.filetools.FileContent(filename: str | PathLike[str] | Path | None = None, content: str | None = None, *, backup: bool = True, encoding: str | None = None)
Bases:
FileNameFile wrapper that stores text content and reads/writes it from disk.
FileContentextendsFileNamewith an in-memory text buffer:if instantiated with an existing filename and
content is None, the file is read immediately;setting
contentmarks the object as needing a save;read()reloads content from disk and clearssave_needed;write()writes the current content to disk and clearssave_needed;if
backupis true,write()creates a numbered backup before overwriting an existing file.
contentmay beNoneto represent an empty/unloaded buffer, butwrite()requires actual text. Assigning any non-string, non-Nonevalue raisesTypeError.- property backup: bool
Return whether writes create a backup before overwriting a file.
- property content: str | None
Return the in-memory text content, or
Noneif unloaded.
- read(filename: str | PathLike[str] | Path | None = None, *, encoding: str | None = None) None
Read text content from disk into memory.
If
filenameis provided, it replaces the current stored path only after a successful read.encoding=Nonedelegates encoding detection tocommon.get_file_content.
- property save_needed: bool
Return whether the in-memory content should be written to disk.
- write(filename: str | PathLike[str] | Path | None = None, *, encoding: str = 'utf-8', backup_ext: str = '.bak') None
Write the in-memory text content to disk.
If
filenameis provided, it replaces the current stored path only after a successful write. When backups are enabled and the target file already exists, a backup is created before writing the new content.
- class pymdtools.filetools.FileName(filename: str | PathLike[str] | Path | None = None)
Bases:
objectUtility object to manipulate a file path.
FileNamekeeps a normalizedPathinternally while preserving the historical public interface based on strings. It is useful when code needs to keep one file reference and update only one part of it:full_filename: complete path, returned asstr | None.filename: basename with suffix, for example"report.md".filename_path: parent directory, returned asstr | None.filename_ext: suffix, including the leading dot, for example".md".
Assigning to these properties updates the stored path:
setting
full_filenameaccepts anycommon.PathInput;setting
filenamesanitizes the basename withcommon.get_valid_filename;setting
filename_pathmoves the stored file reference to another directory;setting
filename_extreplaces the suffix and requires a leading dot.
The object does not create, move, or rename files on disk. It only updates the path value it stores. Use
is_file()andis_dir()to inspect the current filesystem state.- property filename: str | None
Return the basename, including suffix, or
None.
- property filename_ext: str | None
Return the file suffix, including the leading dot, or
None.
- property filename_path: str | None
Return the parent directory as a string, or
None.
- property full_filename: str | None
Return the complete normalized filename as a string, or
None.
- is_dir() bool
Return
Truewhen the stored path currently exists as a directory.
- is_file() bool
Return
Truewhen the stored path currently exists as a file.
- pymdtools.filetools.get_template_file(filename: str | PathLike[str] | Path, start_folder: str | PathLike[str] | Path | None = None) str
Load and return the content of a template file located under a
template/directory.The lookup root is
<base>/template. Whenstart_folderis provided,baseis that folder, or the parent folder whenstart_folderpoints to a file. When it is omitted,baseis derived from this module’s own location.filenamemust be relative to the template directory. Absolute paths, parent traversal with.., and resolved paths escaping the template directory are rejected.- Parameters:
filename – Template filename or relative path inside
template/.start_folder – Optional folder or file used to locate
template/.
- Returns:
The template file content.
- Raises:
ValueError – If
filenameis empty, absolute, or escapes the template directory.FileNotFoundError – If the template directory or file does not exist.
NotADirectoryError – If the template path is not a directory.
OSError – Propagated from the underlying file read operation.
- pymdtools.filetools.get_template_files_in_folder(folder: str | PathLike[str] | Path, start_folder: str | PathLike[str] | Path | None = None) List[str]
List template files contained in template/<folder>.
- Parameters:
folder – Subfolder name under the local template/ directory.
start_folder – Optional folder or file used to locate
template/.
- Returns:
A list of relative template paths (POSIX-style), e.g. [“emails/a.html”]. The result is sorted for determinism.
- Raises:
ValueError – If
folderis empty, absolute, or attempts path traversal.FileNotFoundError – If the template folder does not exist.
NotADirectoryError – If the resolved template folder is not a directory.