Skip to content

cdm_data_loaders.parsers.uniprot.relnotes

Parser for UniProt release notes.

parse_relnotes

parse_relnotes(relnotes_path: Path) -> dict[str, Any]

Open and read the release notes file, returning it as a text string.

Parameters:

Name Type Description Default
relnotes_path Path

path to the release notes file

required

Returns:

Type Description
str

string

Source code in src/cdm_data_loaders/parsers/uniprot/relnotes.py
def parse_relnotes(relnotes_path: Path) -> dict[str, Any]:
    """Open and read the release notes file, returning it as a text string.

    :param relnotes_path: path to the release notes file
    :type relnotes_path: Path
    :return: string
    :rtype: str
    """
    rel_text = relnotes_path.read_text()
    return parse(rel_text)

parse

parse(relnotes: str) -> dict[str, Any]

Parse the release notes for a UniProt release.

Parameters:

Name Type Description Default
relnotes str

contents of the release notes file as a string

required

Returns:

Type Description
dict[str, Any]

key-value pairs with vital release stats

Source code in src/cdm_data_loaders/parsers/uniprot/relnotes.py
def parse(relnotes: str) -> dict[str, Any]:
    """Parse the release notes for a UniProt release.

    :param relnotes: contents of the release notes file as a string
    :type relnotes: str
    :return: key-value pairs with vital release stats
    :rtype: dict[str, Any]
    """
    errors = []
    stats = {}

    relnotes_parts = relnotes.strip().split("\n\n", 1)
    if len(relnotes_parts) != 2:
        msg = "Could not find double line break. Relnotes file format may have changed."
        logger.error(msg)
        raise RuntimeError(msg)

    (intro_str, stats_str) = relnotes_parts

    # remove line breaks for ease of parsing
    intro_str = intro_str.replace("\n", " ")

    rv = re.search(RELEASE_VERSION_DATE, intro_str)
    if not rv:
        errors.append("Could not find text matching the release version date regex.")
    else:
        stats["version"] = rv.groups()[0]
        stats["date_published"] = dt.datetime.strptime(rv.groups()[1], DATE_FORMAT)  # noqa: DTZ007

    # parse the stats section
    uniprot_trembl = re.search(UNIPROT_TREMBL_STATS, stats_str)
    if not uniprot_trembl:
        errors.append("Could not find text matching the UniProt/TrEMBL stats regex.")
    else:
        numbers = uniprot_trembl.groups()
        stats["UniProtKB"] = numbers[0]
        stats["UniProtKB/Swiss-Prot"] = numbers[1]
        stats["UniProtKB/TrEMBL"] = numbers[2]

    all_releases = re.findall(RELEASE_STATS, stats_str)
    if not all_releases:
        errors.append("Could not find text matching the release stats regex.")
    else:
        for release in all_releases:
            (db, number) = release
            if db not in stats:
                stats[db] = number

    # make sure that we have all the UniRef stats
    errors.extend([f"No stats for UniRef{n} found." for n in ["50", "90", "100"] if f"UniRef{n}" not in stats])

    if errors:
        logger.error("\n".join(errors))
        raise RuntimeError("\n".join(errors))

    return stats