Content and attachments¶
Bundles can have local content embedded in the XML document, or attachments. Attachments are files that are referenced from the XML using the src attribute. Bundles with attachments are stored as zip files.
The <link>, <repository> and <file> nodes of the bundle XML all have an optional src attribute that
can reference attachments. The path of src is relative to the location of the XML document of the bundle.
The src attribute can refer to a single file or a directory. When src references a directory, all files
in that directory and subdirectories thereof are part of the bundle. When working with an existing zip bundle,
the files are accessed directly from the zip file.
The Link, Repository and
File classes provide several methods to access the attachment, for example
open() and
copy_to(). All file access methods are documented
in the SrcAttachmentMixin mixin.
When creating a bundle the src attribute should refer to the file or directory to attach.
These files or directories need to remain available on the filesystem until the bundle has been exported using the
to_buffer(), to_file() or
to_directory() methods, and when using the latter export method,
the src paths may not overlap the path to export the bundle to.
API¶
- exception momotor.bundles.elements.content.AttachmentContent¶
Raised when the content is in an attachment.
Subclass of
ValueError. This exception is raised when trying to access thevalueproperty of an element that has content stored in an external attachment (via thesrcattribute) rather than inline content.
- exception momotor.bundles.elements.content.NoContent¶
Raised when no content was provided.
Subclass of
ValueError. This exception is raised when trying to access thevalueproperty of an element that has no content set.
- class momotor.bundles.elements.content.ContentAttachmentElement(bundle)¶
A full content element supporting attachments.
Contents can be string, bytes, boolean, integer, float or
decimal.Decimalvalues, or provided as an attachment using thesrcattribute.and
Bundleitself.- has_writable_content()¶
Check if the attachment content can be written.
- Returns:
True if the element has attachment content that can be written
- is_dir(path=None)¶
Check if the attachment is a directory.
- Parameters:
path (
str|PurePath|None) – Optional subpath within the attachment- Return type:
- Returns:
True if the attachment (or subpath) refers to a directory
- Raises:
FileNotFoundError – If the attachment or path doesn’t exist
- open(path=None)¶
Open the attachment file for reading. Handles opening files directly from filesystem and from zipped bundles
- Parameters:
path (
str|PurePath|None) – for directory attachments, path selects a file in that directory- Return type:
- Returns:
the opened file
- Raises:
FileNotFoundError – if the element has no attachment (when
srcis None), or when it’s a directory and path does not exist in that directoryIsADirectoryError – when it’s a directory
- read(path=None)¶
Read the contents of the attachment
- class momotor.bundles.elements.content.ContentBasicElement(bundle)¶
- A basic content element. Contents can be string or boolean values.
and
Bundleitself.
- class momotor.bundles.elements.content.ContentFullElement(bundle)¶
A full content element.
- Contents can be string, bytes, boolean, integer, float or
decimal.Decimalvalues. and
Bundleitself.
- VALID_PROCESSED_TYPES: ClassVar[tuple[type, ...]] = (<class 'str'>, <class 'bool'>, <class 'bytes'>, <class 'int'>, <class 'float'>, <class 'decimal.Decimal'>)¶
- Contents can be string, bytes, boolean, integer, float or
- momotor.bundles.elements.content.NO_CONTENT = <object object>¶
A sentinel value indicating there is no content.
- class momotor.bundles.mixins.attachments.SrcAttachmentMixin(*args, **kwargs)¶
Mixin providing external file attachment functionality.
Adds support for referencing external files via the
srcattribute. Handles both filesystem and ZIP bundle-based attachments with validation, copying, and export capabilities.See attachments for details on how attachments are handled differently for new vs. existing bundles.
- copy_to(destination, *, name=None)¶
Copy an attachment this element refers to, to given destination directory.
If the attachment is a file, creates a new file in the given directory. If name is provided this will be the name of the new file, otherwise the name of the source file is used.
If the attachment is a directory, copies the contents of the source directory to the destination directory. If name is provided it is created as a new directory inside the destination directory.
Will not overwrite an existing file or directory.
- Parameters:
- Raises:
ValueError – when the attachment is not writeable as a file
FileExistsError – when a file already exists
- Return type:
- file_ctime(path=None)¶
Get file creation time for the attachment.
- Return type:
- file_hashes(hash_names)¶
Calculate the hashes of the file.
Only for file attachments. Will return an empty dictionary if the file does not exist or is a directory.
- has_attachment_content()¶
Check if the element has attachment content.
- Return type:
- Returns:
True if the element has an attachment with content
- has_bundle()¶
Check if src references a file associated with a bundle.
- Return type:
- Returns:
True if src references a file associated with a bundle
- has_writable_content()¶
Check if the attachment content can be written.
- Return type:
- Returns:
True if the element has attachment content that can be written
- has_zip_bundle()¶
Check if src references a file in a zipped bundle.
- Return type:
- Returns:
True if src references a file associated with a zipped bundle
- is_dir(path=None)¶
Check if the attachment is a directory.
- Parameters:
path (
str|PurePath|None) – Optional subpath within the attachment- Return type:
- Returns:
True if the attachment (or subpath) refers to a directory
- Raises:
FileNotFoundError – If the attachment or path doesn’t exist
- iterdir(*, include_empty_root=False)¶
Recursively iterate the contents of a directory attachment. The returned paths are relative to self.absolute_path
If the attachment is an empty directory and include_empty_root is True, a single None value is yielded
- open(path=None)¶
Open the attachment file for reading. Handles opening files directly from filesystem and from zipped bundles
- Parameters:
path (
str|PurePath|None) – for directory attachments, path selects a file in that directory- Return type:
- Returns:
the opened file
- Raises:
FileNotFoundError – if the element has no attachment (when
srcis None), or when it’s a directory and path does not exist in that directoryIsADirectoryError – when it’s a directory
- read(path=None)¶
Read the contents of the attachment
- validate_hashes(expected_hashes)¶
Validate hash values of the file.
Only for file attachments
- property absolute_path: Path¶
Get the absolute path of the attachment referenced by
src- Raises:
ZippedAttachment – when the attachment is in a zipped bundle and therefor has no filesystem path
- bundle¶
- property export_src: PurePath¶
The export path of the attachment, converted to be safe for use in ZIP files
- property src_bundle: Bundle | None¶
If src is a relative path, the
Bundlesrcreferences to.An
srcattribute with a relative path is always associated with a bundle, either the current bundle or another bundle from which thissrcwas copied from usingrecreate(). The bundle provides the base path for the relative path.
- class momotor.bundles.mixins.attachments.AttachmentSrc(path=None, bundle=None, *, validate=True)¶
Represents a source reference for bundle attachments.
Encapsulates the path and bundle information for an attachment, handling both absolute filesystem paths and relative paths within bundles. Validates that the referenced path exists when validation is enabled.
- Parameters:
- Raises:
FileNotFoundError – If validate=True and the path doesn’t exist