### Run tests and style checks using tox Source: https://github.com/untitaker/python-atomicwrites/blob/master/CONTRIBUTING.rst This snippet demonstrates how to install the tox automation tool and execute specific environments for unit testing and style verification. It assumes the user is in the root directory of the project. ```bash pip install tox tox -e py-test tox -e py-stylecheck ``` -------------------------------- ### Customize Atomic Writes with AtomicWriter Class Source: https://context7.com/untitaker/python-atomicwrites/llms.txt Shows how to use the AtomicWriter class for advanced control. It includes an example of subclassing to implement custom file permissions during the write and commit process. ```python from atomicwrites import AtomicWriter, atomic_write import os import tempfile import io # Basic usage with AtomicWriter class writer = AtomicWriter('/tmp/output.txt', mode='w', overwrite=True) with writer.open() as f: f.write('Hello, World!') # Custom subclass with modified behavior class SecureAtomicWriter(AtomicWriter): def get_fileobject(self, **kwargs): dir_path = os.path.normpath(os.path.dirname(self._path)) descriptor, name = tempfile.mkstemp(suffix='.tmp', prefix='secure_', dir=dir_path) os.chmod(name, 0o600) os.close(descriptor) kwargs['mode'] = self._mode kwargs['file'] = name return io.open(**kwargs) def commit(self, f): super().commit(f) os.chmod(self._path, 0o644) # Use the custom writer with SecureAtomicWriter('/tmp/secret.txt', overwrite=True).open() as f: f.write('sensitive data') # Using custom writer class with atomic_write function with atomic_write('/tmp/secure.txt', writer_cls=SecureAtomicWriter, overwrite=True) as f: f.write('more sensitive data') ``` -------------------------------- ### ChecksumAtomicWriter Example Source: https://context7.com/untitaker/python-atomicwrites/llms.txt Demonstrates how to use ChecksumAtomicWriter to write content with expected hash verification. ```APIDOC ## ChecksumAtomicWriter Example ### Description This example shows how to create a custom `ChecksumAtomicWriter` that verifies the content's SHA256 hash before committing the write operation. This ensures data integrity. ### Method N/A (Illustrative Example) ### Endpoint N/A (Illustrative Example) ### Parameters N/A ### Request Example ```python import hashlib class ChecksumAtomicWriter(AtomicWriter): """AtomicWriter that verifies content integrity before commit.""" def __init__(self, path, expected_hash=None, **kwargs): super().__init__(path, **kwargs) self.expected_hash = expected_hash self._written_content = [] def get_fileobject(self, **kwargs): """Wrap file object to track written content.""" f = super().get_fileobject(**kwargs) self._written_content = [] return f def sync(self, f): """Sync and optionally verify hash.""" super().sync(f) if self.expected_hash: f.seek(0) content = f.read() actual_hash = hashlib.sha256(content.encode()).hexdigest() if actual_hash != self.expected_hash: raise ValueError(f"Hash mismatch: expected {self.expected_hash}, got {actual_hash}") f.seek(0, 2) # Seek back to end # Usage with checksum verification content = "verified content" expected = hashlib.sha256(content.encode()).hexdigest() with ChecksumAtomicWriter('/tmp/verified.txt', expected_hash=expected, overwrite=True).open() as f: f.write(content) ``` ### Response N/A #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### Perform Atomic Configuration Updates Source: https://context7.com/untitaker/python-atomicwrites/llms.txt Demonstrates how to safely update a configuration file by writing to a temporary file first, syncing to disk, and then performing an atomic replacement. ```python import os import tempfile def safe_config_update(config_path, new_content): temp_fd, temp_path = tempfile.mkstemp( dir=os.path.dirname(config_path), suffix='.tmp' ) try: with os.fdopen(temp_fd, 'w') as f: f.write(new_content) f.flush() os.fsync(f.fileno()) replace_atomic(temp_path, config_path) except Exception: if os.path.exists(temp_path): os.unlink(temp_path) raise safe_config_update('/tmp/app.conf', 'setting=value\n') ``` -------------------------------- ### Perform Atomic File Writes with atomic_write Source: https://context7.com/untitaker/python-atomicwrites/llms.txt Demonstrates the high-level atomic_write context manager. It covers basic text writing, handling overwrite permissions, specifying encodings, binary mode, and automatic rollback on failure. ```python from atomicwrites import atomic_write # Basic text file write with overwrite enabled with atomic_write('/tmp/config.txt', overwrite=True) as f: f.write('database_host=localhost\n') f.write('database_port=5432\n') # Write without overwrite - raises FileExistsError if file exists try: with atomic_write('/tmp/config.txt', overwrite=False) as f: f.write('new content') except OSError as e: import errno if e.errno == errno.EEXIST: print("File already exists, not overwriting") # Write with specific encoding with atomic_write('/tmp/unicode.txt', overwrite=True, encoding='utf-8') as f: f.write('Hello, ') # Binary mode write with atomic_write('/tmp/data.bin', mode='wb', overwrite=True) as f: f.write(b'\x00\x01\x02\x03') # Automatic rollback on exception - no partial file is left behind try: with atomic_write('/tmp/important.txt', overwrite=True) as f: f.write('partial content') raise ValueError("Something went wrong") except ValueError: pass ``` -------------------------------- ### Perform Atomic File Write in Python Source: https://github.com/untitaker/python-atomicwrites/blob/master/README.rst Demonstrates how to use the atomic_write context manager to safely write to a file. The overwrite parameter controls whether the target file can be replaced if it already exists. ```python from atomicwrites import atomic_write with atomic_write('foo.txt', overwrite=True) as f: f.write('Hello world.') ``` -------------------------------- ### Usage of ChecksumAtomicWriter Source: https://context7.com/untitaker/python-atomicwrites/llms.txt Demonstrates how to instantiate and use the ChecksumAtomicWriter to write data to a file securely. It calculates the expected hash beforehand and passes it to the writer to ensure the file content matches the expected state upon completion. ```python content = "verified content" expected = hashlib.sha256(content.encode()).hexdigest() with ChecksumAtomicWriter('/tmp/verified.txt', expected_hash=expected, overwrite=True).open() as f: f.write(content) ``` -------------------------------- ### Extend AtomicWriter for Custom Logging Source: https://context7.com/untitaker/python-atomicwrites/llms.txt Shows how to subclass AtomicWriter to implement custom logging during the file lifecycle, including creation, syncing, committing, and rolling back. ```python from atomicwrites import AtomicWriter import os import io import logging class LoggingAtomicWriter(AtomicWriter): def get_fileobject(self, **kwargs): dir_path = os.path.normpath(os.path.dirname(self._path)) descriptor, name = tempfile.mkstemp(suffix='.atomic', dir=dir_path) self._temp_path = name os.close(descriptor) kwargs['mode'] = self._mode kwargs['file'] = name return io.open(**kwargs) def sync(self, f): f.flush() os.fsync(f.fileno()) def commit(self, f): super().commit(f) def rollback(self, f): if f is not None: os.unlink(f.name) ``` -------------------------------- ### Atomic File Moves and Unique File Creation Source: https://context7.com/untitaker/python-atomicwrites/llms.txt Uses move_atomic to ensure file moves are race-free and demonstrates a pattern for creating unique numbered files without collision. ```python from atomicwrites import move_atomic import os import errno def create_numbered_file(base_path, content, max_attempts=100): temp_fd, temp_path = tempfile.mkstemp(dir=os.path.dirname(base_path)) with os.fdopen(temp_fd, 'w') as f: f.write(content) f.flush() os.fsync(f.fileno()) base, ext = os.path.splitext(base_path) for i in range(max_attempts): target = f"{base}_{i:04d}{ext}" try: move_atomic(temp_path, target) return target except OSError as e: if e.errno != errno.EEXIST: raise os.unlink(temp_path) raise RuntimeError("Could not create unique file") ``` -------------------------------- ### atomic_write Context Manager Source: https://github.com/untitaker/python-atomicwrites/blob/master/README.rst The primary interface for performing atomic file writes. It handles the creation of a temporary file and its atomic replacement of the target file upon completion. ```APIDOC ## atomic_write(path, overwrite=False) ### Description A context manager that provides a file-like object for writing data. Once the block exits, the temporary file is moved to the target path atomically. ### Parameters #### Path Parameters - **path** (str) - Required - The target file path to write to. #### Optional Parameters - **overwrite** (bool) - Optional - If set to True, the target file will be overwritten if it already exists. Defaults to False. ### Request Example ```python from atomicwrites import atomic_write with atomic_write('foo.txt', overwrite=True) as f: f.write('Hello world.') ``` ### Response #### Success Response (None) - The file is created or updated at the specified path upon successful exit of the context manager. ``` -------------------------------- ### Atomic Write Summary Source: https://context7.com/untitaker/python-atomicwrites/llms.txt Provides a summary of the atomicwrites library's purpose, use cases, and integration patterns. ```APIDOC ## Atomic Writes Summary ### Description This section summarizes the key aspects of the `atomicwrites` library, highlighting its benefits for reliable file persistence and how it integrates into Python applications. ### Method N/A ### Endpoint N/A ### Parameters N/A ### Request Example N/A ### Response #### Success Response (200) N/A #### Response Example N/A ## Summary Atomicwrites is ideal for applications that require reliable file persistence, including configuration management, database journaling, log rotation, and any scenario where partial writes could lead to data corruption. The high-level `atomic_write` function handles most common use cases, while the `AtomicWriter` class enables customization for specialized requirements like permission handling, logging, or integrity verification. Integration follows standard Python patterns: use `atomic_write` as a context manager for simple writes, subclass `AtomicWriter` for custom behavior, or use the low-level `replace_atomic` and `move_atomic` functions when building specialized file management systems. Error handling is consistent across platforms, with all filesystem errors being subclasses of `OSError` with appropriate `errno` values, making it straightforward to handle conditions like `EEXIST` for file-already-exists scenarios. ``` -------------------------------- ### Error Handling Source: https://github.com/untitaker/python-atomicwrites/blob/master/docs/index.rst Information on how errors are handled by the atomicwrites library. ```APIDOC ## Error Handling ### Description All filesystem errors raised by the atomicwrites library are subclasses of Python's built-in :py:exc:`OSError`. - On UNIX systems, errors originating from Python's standard library calls are propagated. - On Windows systems, errors from Python's ``ctypes`` calls are propagated. The ``errno`` attribute on the thrown exception provides a specific error code that maps to the standard ``errno`` module. ### Method N/A ### Endpoint N/A ### Parameters N/A ### Request Example ```python from atomicwrites import atomic_write import errno try: with atomic_write('/nonexistent_dir/file.txt') as f: f.write('test') except OSError as e: print(f"An OSError occurred: {e}") print(f"Error code: {e.errno}") if e.errno == errno.ENOENT: print("Error: Directory not found.") ``` ### Response #### Success Response (200) N/A #### Response Example N/A ``` -------------------------------- ### AtomicWriter Class Source: https://context7.com/untitaker/python-atomicwrites/llms.txt A class-based API for performing atomic writes with full control over the file handling process. It can be subclassed to customize temporary file creation, sync behavior, commit logic, and rollback handling. ```APIDOC ## AtomicWriter Class ### Description Provides a class-based interface for atomic file writes, allowing for customization through subclassing. ### Method Class instantiation and context manager (`.open()`) ### Endpoint N/A (Python class) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from atomicwrites import AtomicWriter import os import tempfile # Basic usage with AtomicWriter class writer = AtomicWriter('/tmp/output.txt', mode='w', overwrite=True) with writer.open() as f: f.write('Hello, World!') # Custom subclass with modified behavior class SecureAtomicWriter(AtomicWriter): """AtomicWriter that sets restrictive permissions on temporary files.""" def get_fileobject(self, **kwargs): """Create temporary file with restricted permissions (0600).""" dir_path = os.path.normpath(os.path.dirname(self._path)) descriptor, name = tempfile.mkstemp( suffix='.tmp', prefix='secure_', dir=dir_path ) # Set restrictive permissions before writing os.chmod(name, 0o600) os.close(descriptor) kwargs['mode'] = self._mode kwargs['file'] = name import io return io.open(**kwargs) def commit(self, f): """Commit with final permission adjustment.""" super().commit(f) os.chmod(self._path, 0o644) # Set final permissions # Use the custom writer with SecureAtomicWriter('/tmp/secret.txt', overwrite=True).open() as f: f.write('sensitive data') # Using custom writer class with atomic_write function with atomic_write('/tmp/secure.txt', writer_cls=SecureAtomicWriter, overwrite=True) as f: f.write('more sensitive data') ``` ### Response #### Success Response (200) File is written atomically to the target path upon successful exit of the `with` block. #### Response Example None (operation is side-effect based) ``` -------------------------------- ### Atomically Replace Files with replace_atomic Source: https://context7.com/untitaker/python-atomicwrites/llms.txt Uses the low-level replace_atomic function to move a source file to a destination path atomically. This is useful for replacing existing files without risk of data corruption. ```python from atomicwrites import replace_atomic import tempfile import os # Create a temporary file with new content temp_fd, temp_path = tempfile.mkstemp(dir='/tmp') with os.fdopen(temp_fd, 'w') as f: f.write('new configuration content') # Atomically replace the target file target_path = '/tmp/config.ini' replace_atomic(temp_path, target_path) ``` -------------------------------- ### Move Atomic Function Source: https://github.com/untitaker/python-atomicwrites/blob/master/docs/index.rst Atomically moves a file from a source path to a destination path. ```APIDOC ## move_atomic ### Description Atomically moves a file from `src` to `dst`. ### Method Not applicable (function call) ### Endpoint Not applicable (function call) ### Parameters * **src** (str or Path) - Required - The path to the source file. * **dst** (str or Path) - Required - The path to the destination file. * **overwrite** (bool) - Optional - If True, overwrite the destination file if it exists. Defaults to False. ### Request Example ```python from atomicwrites import move_atomic # Assuming 'source_file.txt' exists move_atomic('source_file.txt', 'destination_file.txt', overwrite=True) ``` ### Response #### Success Response (200) No direct response, the operation modifies the file system. #### Response Example N/A ``` -------------------------------- ### AtomicWriter Class Source: https://github.com/untitaker/python-atomicwrites/blob/master/docs/index.rst A class for managing atomic writes, providing more control over the writing process. ```APIDOC ## AtomicWriter ### Description A context manager that provides an atomic file writing interface. It handles the creation of temporary files and the final atomic move/replace operation. ### Method Not applicable (class) ### Endpoint Not applicable (class) ### Parameters * **fpath** (str or Path) - Required - The path to the target file. * **mode** (str) - Optional - The mode in which to open the file (e.g., 'w', 'wb'). Defaults to 'w'. * **encoding** (str) - Optional - The encoding to use when writing text data. Defaults to None. * **errors** (str) - Optional - The error handling scheme for encoding. Defaults to None. * **newline** (str) - Optional - Controls universal newlines mode. Defaults to None. * **suffix** (str) - Optional - Suffix for the temporary file. Defaults to None. * **dir** (str or Path) - Optional - Directory to create the temporary file in. Defaults to the directory of `fpath`. * **overwrite** (bool) - Optional - If True, overwrite the target file if it exists. Defaults to False. ### Request Example ```python from atomicwrites import AtomicWriter writer = AtomicWriter('my_atomic_file.txt', overwrite=True) with writer.open() as f: f.write('This is atomic content.') ``` ### Response #### Success Response (200) No direct response, the operation modifies the file system. #### Response Example N/A ``` -------------------------------- ### Atomic Write Function Source: https://github.com/untitaker/python-atomicwrites/blob/master/docs/index.rst The main function for performing atomic writes to a file. ```APIDOC ## atomic_write ### Description Performs an atomic write operation to a file. This ensures that the file is either fully written or not written at all, preventing data corruption. ### Method Not applicable (function call) ### Endpoint Not applicable (function call) ### Parameters * **fpath** (str or Path) - Required - The path to the file to write to. * **data** (bytes or str) - Required - The data to write to the file. * **overwrite** (bool) - Optional - If True, overwrite the file if it exists. Defaults to False. * **encoding** (str) - Optional - The encoding to use when writing text data. Defaults to None. * **errors** (str) - Optional - The error handling scheme for encoding. Defaults to None. * **newline** (str) - Optional - Controls universal newlines mode. Defaults to None. ### Request Example ```python from atomicwrites import atomic_write with atomic_write('my_file.txt', overwrite=True) as f: f.write('Hello, atomic writes!') ``` ### Response #### Success Response (200) No direct response, the operation modifies the file system. #### Response Example N/A ``` -------------------------------- ### atomic_write Function Source: https://context7.com/untitaker/python-atomicwrites/llms.txt The primary high-level function for performing atomic file writes. It returns a context manager that yields a file object for writing; upon successful completion, the temporary file is atomically moved to the target path. ```APIDOC ## atomic_write Function ### Description Performs atomic file writes using a context manager. Ensures that either the entire file is written successfully or no changes are made. ### Method Context Manager (used with `with` statement) ### Endpoint N/A (Python function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from atomicwrites import atomic_write # Basic text file write with overwrite enabled with atomic_write('/tmp/config.txt', overwrite=True) as f: f.write('database_host=localhost\n') f.write('database_port=5432\n') # Write without overwrite - raises FileExistsError if file exists try: with atomic_write('/tmp/config.txt', overwrite=False) as f: f.write('new content') except OSError as e: import errno if e.errno == errno.EEXIST: print("File already exists, not overwriting") # Write with specific encoding with atomic_write('/tmp/unicode.txt', overwrite=True, encoding='utf-8') as f: f.write('Hello, ') # Binary mode write with atomic_write('/tmp/data.bin', mode='wb', overwrite=True) as f: f.write(b'\x00\x01\x02\x03') # Automatic rollback on exception - no partial file is left behind try: with atomic_write('/tmp/important.txt', overwrite=True) as f: f.write('partial content') raise ValueError("Something went wrong") except ValueError: pass # File '/tmp/important.txt' remains unchanged or doesn't exist ``` ### Response #### Success Response (200) File is written atomically to the target path upon successful exit of the `with` block. #### Response Example None (operation is side-effect based) ``` -------------------------------- ### Implement ChecksumAtomicWriter for Integrity Verification Source: https://context7.com/untitaker/python-atomicwrites/llms.txt This snippet defines a custom AtomicWriter subclass that tracks written content and verifies its SHA-256 hash against an expected value during the sync process. It ensures that data is only committed if the integrity check passes, preventing corrupted writes. ```python import hashlib class ChecksumAtomicWriter(AtomicWriter): def __init__(self, path, expected_hash=None, **kwargs): super().__init__(path, **kwargs) self.expected_hash = expected_hash self._written_content = [] def get_fileobject(self, **kwargs): f = super().get_fileobject(**kwargs) self._written_content = [] return f def sync(self, f): super().sync(f) if self.expected_hash: f.seek(0) content = f.read() actual_hash = hashlib.sha256(content.encode()).hexdigest() if actual_hash != self.expected_hash: raise ValueError(f"Hash mismatch: expected {self.expected_hash}, got {actual_hash}") f.seek(0, 2) ``` -------------------------------- ### replace_atomic Function Source: https://context7.com/untitaker/python-atomicwrites/llms.txt Low-level function that atomically moves a source file to a destination path, silently overwriting the destination if it exists. Both paths must reside on the same filesystem for the operation to be atomic. ```APIDOC ## replace_atomic Function ### Description Atomically replaces a destination file with a source file. The operation is atomic only if both files are on the same filesystem. ### Method Function call ### Endpoint N/A (Python function) ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```python from atomicwrites import replace_atomic import tempfile import os # Create a temporary file with new content temp_fd, temp_path = tempfile.mkstemp(dir='/tmp') with os.fdopen(temp_fd, 'w') as f: f.write('new configuration content') # Atomically replace the target file target_path = '/tmp/config.ini' replace_atomic(temp_path, target_path) # temp_path no longer exists, target_path has new content ``` ### Response #### Success Response (200) File is replaced atomically. #### Response Example None (operation is side-effect based) ``` -------------------------------- ### Replace Atomic Function Source: https://github.com/untitaker/python-atomicwrites/blob/master/docs/index.rst Atomically replaces the contents of a file with new data. ```APIDOC ## replace_atomic ### Description Atomically replaces the contents of a file at `fpath` with the contents of `src`. ### Method Not applicable (function call) ### Endpoint Not applicable (function call) ### Parameters * **fpath** (str or Path) - Required - The path to the file to be replaced. * **src** (str or Path) - Required - The path to the source file whose contents will replace the target file. * **overwrite** (bool) - Optional - If True, overwrite the target file if it exists. Defaults to False. ### Request Example ```python from atomicwrites import replace_atomic # Assuming 'original.txt' exists and 'new_content.txt' contains the new data replace_atomic('original.txt', 'new_content.txt', overwrite=True) ``` ### Response #### Success Response (200) No direct response, the operation modifies the file system. #### Response Example N/A ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.