Skip to content

omex

COMBINE archive (OMEX) support.

A COMBINE archive is a single file which bundles everything belonging to a modeling project: models (SBML, CellML), simulation experiments (SED-ML), data, figures and documentation. It is a ZIP container with a manifest.xml at its root listing every file together with its format, given as an identifiers.org URI rather than guessed from the file suffix.

This module provides three classes:

  • Omex: the archive; reading, writing and access to its files
  • Manifest: the entries of the archive, i.e., the manifest.xml
  • ManifestEntry: a single file with location, format and master
Example

Read an existing archive and list the SBML models it contains:

from pathlib import Path
from pymetadata.omex import Omex

omex = Omex.from_omex(Path("archive.omex"))
for entry in omex.entries_by_format("sbml"):
    print(entry.location, omex.get_path(entry.location))

Create an archive from single files:

from pymetadata.omex import EntryFormat, ManifestEntry, Omex

omex = Omex()
omex.add_entry(
    entry_path=Path("model.xml"),
    entry=ManifestEntry(
        location="./model.xml", format=EntryFormat.SBML_L3V2, master=True
    ),
)
omex.to_omex(Path("archive.omex"))

Encrypted archives can be read by passing a password; writing encrypted archives is not supported. Manipulation of OMEX metadata is not supported.

References

Bergmann FT, Adams R, Moodie S, Cooper J, Glont M, Golebiewski M, Hucka M, Laibe C, Miller AK, Nickerson DP, Olivier BG, Rodriguez N, Sauro HM, Scharm M, Soiland-Reyes S, Waltemath D, Yvon F, Le Novere N. COMBINE archive and OMEX format: one file to share all information to reproduce a modeling project. BMC Bioinformatics. 2014;15(1):369. https://doi.org/10.1186/s12859-014-0369-z

Bergmann FT, Rodriguez N, Le Novere N. COMBINE Archive Specification Version 1. J Integr Bioinform. 2015;12(2):261. https://doi.org/10.2390/biecoll-jib-2015-261

EntryFormat

Bases: str, Enum

Format URIs used in the manifest.xml.

COMBINE specifications (SBML, SED-ML, CellML, SBGN, BioPAX, OMEX metadata, FROG results) are identified by http://identifiers.org/combine.specifications/* URIs, all other files by their media type via https://purl.org/NET/mediatypes/*. Where a specification is versioned, both the generic and the level and version specific term exist, e.g., SBML and SBML_L3V2.

ManifestEntry

Bases: BaseModel

A single file of the archive, as listed in the manifest.xml.

Attributes:

Name Type Description
location str

location of the file in the archive, relative and starting with ./, e.g., ./models/model.xml

format str

format URI of the file, see EntryFormat

master bool

marks the entry a tool should open first, e.g., the SED-ML file of a simulation study

Example
entry = ManifestEntry(
    location="./model.xml", format=EntryFormat.SBML_L3V2, master=True
)

is_format staticmethod

is_format(format_key, format)

Check if a format URI matches a format key.

Parameters:

Name Type Description Default
format_key str

sbml, sedml or sbgn, which match all level and version variants, or the name of an EntryFormat

required
format str

format URI to check

required

Returns:

Type Description
bool

True if the format matches the key.

is_sbml

is_sbml()

Check if entry is SBML.

is_sedml

is_sedml()

Check if entry is SED-ML.

is_sbgn

is_sbgn()

Check if entry is SBGN.

Manifest

Manifest(**data)

Bases: BaseModel

Content of the manifest.xml, i.e., the entries of an archive.

The manifest behaves like a mapping keyed by location and always contains the two entries required by the specification: the archive itself (.) and the manifest (./manifest.xml).

Attributes:

Name Type Description
entries list[ManifestEntry]

the manifest entries

Example
print(len(omex.manifest))
print("./model.xml" in omex.manifest)
entry = omex.manifest["./model.xml"]

Initialize Manifest.

from_manifest classmethod

from_manifest(manifest_path)

Read a manifest from a manifest.xml file.

Parameters:

Name Type Description Default
manifest_path Path

path of the manifest.xml

required

Returns:

Type Description
Manifest

Manifest with the entries listed in the file.

to_manifest_xml

to_manifest_xml()

Serialize the manifest to manifest.xml content.

Returns:

Type Description
str

The XML of the manifest as a string.

to_manifest

to_manifest(manifest_path)

Write the manifest to a manifest.xml file.

Parameters:

Name Type Description Default
manifest_path Path

path of the file to write

required

add_entry

add_entry(entry)

Add an entry to the manifest.

The location is normalized to a relative path starting with ./. Duplicated locations are not checked, use Omex.add_entry to add a file together with its entry.

Parameters:

Name Type Description Default
entry ManifestEntry

entry to add

required

remove_entry_for_location

remove_entry_for_location(location)

Remove entry for given location.

Omex

Omex()

COMBINE archive (OMEX), version 1.

The content of the archive is kept in a temporary directory, manifest holds the corresponding entries. Use the from_* constructors to read an archive and the to_* methods to write one:

read write
Omex.from_omex from an omex file Omex.to_omex to an omex file
Omex.from_url from a url Omex.to_directory to a directory
Omex.from_directory from a directory

An empty archive is filled with Omex.add_entry.

Attributes:

Name Type Description
manifest Manifest

entries of the archive, i.e., the content of the manifest.xml

Example

Using the archive as a context manager removes the temporary directory when the block is left:

with Omex.from_omex(Path("archive.omex")) as omex:
    print(omex)

Create an empty COMBINE archive.

get_path

get_path(location)

Get the path of an entry in the extracted archive.

Parameters:

Name Type Description Default
location str

location of the entry, e.g., ./model.xml

required

Returns:

Type Description
Path

Path of the file in the temporary directory of the archive, which

Path

can be passed on to a reader such as libsbml.

Raises:

Type Description
KeyError

if no entry exists for the location

is_omex staticmethod

is_omex(omex_path)

Check if the path is a COMBINE archive.

The file must be a zip archive containing a manifest.xml.

Parameters:

Name Type Description Default
omex_path Path

path to check

required

Returns:

Type Description
bool

True if the path is a COMBINE archive.

Raises:

Type Description
ValueError

if the path does not exist or is not a file

from_omex staticmethod

from_omex(omex_path, password=None)

Read a COMBINE archive from a path.

The archive is extracted into a temporary directory; the entries are taken from the manifest.xml of the archive.

Parameters:

Name Type Description Default
omex_path Path

path of the omex file

required
password bytes | None

password of an encrypted archive

None

Returns:

Type Description
Omex

Omex with the content of the archive.

Raises:

Type Description
ValueError

if the path does not exist or is not a file

Example
omex = Omex.from_omex(Path("archive.omex"))

from_url staticmethod

from_url(omex_url, password=None)

Read a COMBINE archive from a url.

The archive is downloaded to a temporary file and read from there.

Parameters:

Name Type Description Default
omex_url str

url of the omex file

required
password bytes | None

password of an encrypted archive

None

Returns:

Type Description
Omex

Omex with the content of the archive.

Raises:

Type Description
HTTPError

if the archive could not be downloaded

Example
omex = Omex.from_url(
    "https://github.com/matthiaskoenig/canagliflozin-model/"
    "releases/download/0.7.0/canagliflozin_model.omex"
)

from_directory classmethod

from_directory(directory)

Create a COMBINE archive from a directory.

If the directory contains a manifest.xml, the entries listed there are reused. The format of every other file is inferred with Omex.guess_format; SED-ML files added this way get master=True, as they are the entry point of a simulation study.

Parameters:

Name Type Description Default
directory Path

directory with the content of the archive

required

Returns:

Type Description
Omex

Omex with one entry per file in the directory.

Raises:

Type Description
ValueError

if the directory does not exist or is not a directory

Example
omex = Omex.from_directory(Path("./study"))
omex.to_omex(Path("study.omex"))

add_entry

add_entry(entry_path, entry)

Add a file to the archive.

The file is copied into the archive, i.e., later changes to the source file do not affect the content of the archive. Adding a second entry for an existing location replaces the first one and logs a warning.

Parameters:

Name Type Description Default
entry_path Path

path of the file to add

required
entry ManifestEntry

manifest entry describing location, format and master flag

required

Raises:

Type Description
ValueError

if entry_path does not exist or is not a file

Example
omex.add_entry(
    entry_path=Path("model.xml"),
    entry=ManifestEntry(
        location="./model.xml",
        format=EntryFormat.SBML_L3V2,
        master=True,
    ),
)

remove_entry_for_location

remove_entry_for_location(location)

Remove an entry and the corresponding file from the archive.

Parameters:

Name Type Description Default
location str

location of the entry, e.g., ./model.xml

required

Returns:

Type Description
ManifestEntry | None

The removed entry, or None if no entry exists for the location.

to_omex

to_omex(
    omex_path,
    password=None,
    compression=ZIP_DEFLATED,
    compresslevel=9,
)

Write the archive to an omex file.

The manifest.xml is generated from the entries of the archive. By definition OMEX files are zip deflated.

Parameters:

Name Type Description Default
omex_path Path

path of the omex file to write

required
password str | None

unused, encrypted archives cannot be written yet

None
compression int

zipfile compression algorithm

ZIP_DEFLATED
compresslevel int

level of compression. Has no effect for ZIP_STORED and ZIP_LZMA; 0-9 for ZIP_DEFLATED (see zlib) and 1-9 for ZIP_BZIP2 (see bz2). Larger values compress better.

9
Example
omex.to_omex(Path("archive.omex"))

to_directory

to_directory(output_dir)

Extract the archive to a directory.

The manifest.xml is written next to the files, so the result can be read back with Omex.from_directory.

Parameters:

Name Type Description Default
output_dir Path

directory to write to, created if it does not exist

required
Example
omex.to_directory(Path("./unpacked"))

entries_by_format

entries_by_format(format_key)

Get all entries of a given format.

Parameters:

Name Type Description Default
format_key str

sbml, sedml or sbgn, which match all level and version variants, or the name of an EntryFormat

required

Returns:

Type Description
list[ManifestEntry]

List of matching entries, empty if the archive contains none.

Example
for entry in omex.entries_by_format("sbml"):
    print(entry.location)

lookup_format staticmethod

lookup_format(format_key)

Look up the format URI for a format key.

Parameters:

Name Type Description Default
format_key str

name of an EntryFormat, e.g., sbml or csv

required

Returns:

Type Description
str

The format URI, or the URI for an unknown media type if the key

str

cannot be resolved.

guess_format staticmethod

guess_format(path)

Guess the format URI of a file.

The start of .xml files is inspected to tell SBML, SED-ML, CellML and COPASI apart; for every other file the suffix decides.

Parameters:

Name Type Description Default
path Path

path of the file

required

Returns:

Type Description
str

The format URI, or the URI for an unknown media type if the format

str

cannot be determined.