Make Secure Temp File For Atomic Write
June 22, 2026 ยท View on GitHub
Two types of failure modes that can occur while writing to a shared file on the file system are 1) a corrupted file due to a crash mid-write and 2) another process reading a partial file mid-write.
One way I've handled this in py-vmt is
to perform the write operations on a secure temp file and then use the OS-level
atomic rename operation. I do this by creating a
contextmanager
that uses
tempfile.mkstemp
and os.replace.
Here is what the contextmanager looks like:
from contextlib import contextmanager
from pathlib import Path
import os, tempfile
@contextmanager
def atomic_write(path: Path):
# write to a tmp file in the same directory, then atomically swap it
fd, temp_file_path = tempfile.mkstemp(dir=path.parent, suffix=".tmp")
try:
with os.fdopen(fd, "w") as file:
yield file
os.replace(temp_file_path, path)
except BaseException:
os.unlink(temp_file_path)
raise
This explicitly creates a secure temp file in the same directory as the given
path with .tmp as the suffix. I then open the file descriptor using the
os.fdopen context manager (which will manage closing the file descriptor for
me). The @contextmanager decorator plus the yield file are what allow this
to be used as a with block. Once any file operations are done, then I use
os.replace to atomically swap out the original file with the temp file.
Here is how I use it to write updates to JSON data files:
def write_active_session(self, session: Session) -> None:
with atomic_write(self.active_session_file) as file:
json.dump(session.marshal(), file)