Source code for konnect.curl.certificates.files

# Copyright 2025-2026  Dom Sekotill <dom.sekotill@kodo.org.uk>

"""
File storage helper class for encoded cryptographic formats
"""

from __future__ import annotations

from pathlib import Path
from typing import Final
from typing import Generic
from typing import TypeVar
from typing import final

from .encodings import Encoding

T = TypeVar("T", bound=Encoding, covariant=True)
C = TypeVar("C", bound=Encoding)

DEFAULT_MAX_READ: Final = 2**16  # 64kiB


[docs] @final class EncodedFile(Generic[T]): """ Combines decoding data with file path information """ def __init__(self, contents: T, path: Path) -> None: self.contents = contents self.path = path
[docs] @classmethod def read( cls: type[EncodedFile[C]], path: Path, encoding: type[C], /, maxsize: int = DEFAULT_MAX_READ, ) -> EncodedFile[C]: """ Read encoded data from the file path if it exists and return an `EncodedFile` The value of 'maxsize' is a safety net to prevent arbitrarily large files being read into memory. The default should be suitable for most certificate and key files but can be overridden to allow unusually large files to be read (probably ASCII armored files containing many items). Can raise the normal range of `OSError` exceptions that may occur when opening and reading a file. """ with path.open("rb") as handle: contents = encoding.from_bytes(handle.read(maxsize)) return cls(contents, path)
[docs] @staticmethod def write(path: Path, contents: C, /, *, exists_ok: bool = False) -> EncodedFile[C]: """ Write encoded data to the file path If 'exists_ok' is false the file will be opened in create-only mode, raising `FileExistsError` if there is already a file at the path; otherwise the file is opened in normal write mode and truncated before writing the encoded data. Either way the data is never appended to the file. Can raise the normal range of `OSError` exceptions that may occur when opening and writing to a file. """ # Its a shame this cannot be a @classmethod to inject EncodedFile subclasses but it # cannot be done without subscripting the subclass with the contents type when # called. mode = "wb" if exists_ok else "xb" with path.open(mode) as handle: handle.write(contents.to_bytes()) return EncodedFile(contents, path)