Skip to main content

rpmrepo_metadata

PyPI Python

A Python library for reading, writing, and managing RPM repository metadata. Built on a Rust core for performance.

RPM repository metadata consists of several XML files — primary.xml, filelists.xml, other.xml, repomd.xml, updateinfo.xml, and comps.xml — that together describe the packages available in a repository. This library provides high-level APIs for working with all of these metadata types.

Installation

pip install rpmrepo_metadata

Requires Python >= 3.10. Pre-built wheels are available for Linux, macOS, and Windows.

Examples


Read a repository and iterate packages

Use RepositoryReader to stream through packages without loading everything into memory.

from rpmrepo_metadata import RepositoryReader

reader = RepositoryReader("path/to/repo/")

packages = reader.iter_packages()
print(f"Total packages: {packages.total_packages}")

for pkg in packages:
    print(f"{pkg.nevra()} - {pkg.summary}")
    print(f"  Size: {pkg.size_package} bytes")
    print(f"  Checksum: {pkg.checksum}")
    print(f"  Location: {pkg.location_href}")

Read advisories (updateinfo)

from rpmrepo_metadata import RepositoryReader

reader = RepositoryReader("path/to/repo/")

for advisory in reader.iter_advisories():
    print(f"[{advisory.update_type}] {advisory.id} - {advisory.title}")
    print(f"  Severity: {advisory.severity}")
    print(f"  Issued: {advisory.issued_date}")

    for ref in advisory.references:
        print(f"  {ref.reftype}: {ref.href}")

    for collection in advisory.pkglist:
        for pkg in collection.packages:
            print(f"  Package: {pkg.name}-{pkg.version}-{pkg.release}.{pkg.arch}")

Read comps data (groups, categories, environments)

from rpmrepo_metadata import RepositoryReader

reader = RepositoryReader("path/to/repo/")

comps = reader.read_comps()
if comps is not None:
    for group in comps.groups:
        print(f"Group: {group.name} ({group.id})")
        for pkg_req in group.packages:
            print(f"  {pkg_req.reqtype}: {pkg_req.name}")

    for category in comps.categories:
        print(f"Category: {category.name}")
        for group_id in category.group_ids:
            print(f"  Group: {group_id}")

    for env in comps.environments:
        print(f"Environment: {env.name} ({env.id})")
        for group_id in env.group_ids:
            print(f"  Group: {group_id}")
        for option in env.option_ids:
            print(f"  Optional: {option.group_id} (default={option.default})")

Create and populate a Package

from rpmrepo_metadata import Package

pkg = Package()
pkg.name = "my-package"
pkg.epoch = 0
pkg.version = "1.2.3"
pkg.release = "4.el9"
pkg.arch = "x86_64"

pkg.summary = "An example package"
pkg.description = "A longer description of the package"
pkg.url = "https://example.com"
pkg.rpm_license = "MIT"

pkg.checksum = ("sha256", "a" * 64)
pkg.location_href = "Packages/m/my-package-1.2.3-4.el9.x86_64.rpm"

pkg.size_package = 12345
pkg.size_installed = 67890
pkg.time_build = 1700000000

# Dependencies are tuples of (name, flags, epoch, version, release, preinstall)
pkg.requires = [
    ("glibc", "GE", "0", "2.17", "", False),
    ("bash", None, None, None, None, False),
]
pkg.provides = [("my-package", "EQ", "0", "1.2.3", "4.el9", False)]

# Files are tuples of (type, path) where type is None, "dir", or "ghost"
pkg.files = [
    (None, "/usr/bin/my-package"),
    ("dir", "/etc/my-package"),
]

# Changelogs are tuples of (author, timestamp, description)
pkg.changelogs = [
    ("John Doe <john@example.com>", 1700000000, "- Initial release"),
]

print(pkg.nevra())       # "my-package-0:1.2.3-4.el9.x86_64"
print(pkg.pkgid)          # "aaaa...aaaa"

Read an RPM file directly

Extract metadata from .rpm files on disk.

from rpmrepo_metadata import Package, ChecksumType

# Using defaults (SHA-256 checksum, 10 changelog entries)
pkg = Package.from_file("packages/foo-1.0-1.el9.x86_64.rpm")
print(f"{pkg.nevra()} - {len(pkg.files)} files")

# With custom options
pkg = Package.from_file(
    "packages/foo-1.0-1.el9.x86_64.rpm",
    checksum_type=ChecksumType.Sha512,
    location_href="Packages/f/foo-1.0-1.el9.x86_64.rpm",
    location_base="https://example.com/repo/",
    changelog_limit=5,
)
print(f"Checksum type: {pkg.checksum_type}")  # "sha512"
print(f"Location: {pkg.location_href}")

Parse an RPM buffer

With a complete RPM buffer, from_buffer derives a checksum using checksum_type (SHA-256 by default) and the package size. Supplying both values permits a header-only buffer instead. Supplying only one is rejected because they both describe the full RPM file. Supplied values are trusted and are not verified against the buffer.

from rpmrepo_metadata import ChecksumType, Package

with open("packages/foo-1.0-1.el9.x86_64.rpm", "rb") as rpm_file:
    rpm_bytes = rpm_file.read()

pkg = Package.from_buffer(
    rpm_bytes,
    time_file=1_700_000_000,
    location_href="Packages/f/foo-1.0-1.el9.x86_64.rpm",
    checksum_type=ChecksumType.Sha512,
)

Write a repository with RepositoryWriter

Stream packages to disk one at a time, keeping memory usage low.

from rpmrepo_metadata import RepositoryWriter, Package

writer = RepositoryWriter("output/repo/", num_pkgs=100)

# Add packages
for rpm_path in rpm_files:
    pkg = Package.from_file(rpm_path)
    writer.add_package(pkg)

# Add advisories
advisory = UpdateRecord()
advisory.id = "EXAMPLE-2024:001"
advisory.title = "Important security fix"
advisory.update_type = "security"
advisory.severity = "Important"
writer.add_advisory(advisory)

# Finalize — writes repomd.xml and closes all files
writer.finish()

Work with Repository in-memory

Repository loads all metadata into memory, convenient for smaller repositories.

from rpmrepo_metadata import Repository

# Load from disk
repo = Repository.load_from_directory("path/to/repo/")

# Write to a new location
repo.write_to_directory("output/repo/")

Parse and compare EVR version strings

from rpmrepo_metadata import EVR

evr1 = EVR.parse("1:2.3.4-5.el9")
evr2 = EVR.parse("2.3.4-6.el9")

print(f"{evr1} vs {evr2}")
print(f"epoch={evr1.epoch}, version={evr1.version}, release={evr1.release}")

# Comparison operators
assert evr1 > evr2  # epoch 1 beats no epoch
assert EVR.parse("1.0-1") == EVR.parse("0:1.0-1")  # epoch 0 is the default
assert EVR.parse("1.0-2") > EVR.parse("1.0-1")

# Destructure into components
epoch, version, release = evr1.components()

Parse comps XML from a string

from rpmrepo_metadata import CompsData

xml = """<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE comps PUBLIC "-//Red Hat, Inc.//DTD Comps info//EN" "comps.dtd">
<comps>
  <group>
    <id>core</id>
    <name>Core</name>
    <description>Minimal system</description>
    <packagelist>
      <packagereq type="mandatory">bash</packagereq>
      <packagereq type="mandatory">coreutils</packagereq>
    </packagelist>
  </group>
</comps>"""

comps = CompsData.from_xml(xml)
print(f"{len(comps.groups)} groups")

# Serialize back to XML
output_xml = comps.to_xml()

Work with UpdateRecord (advisories)

from rpmrepo_metadata import (
    UpdateRecord, UpdateReference, UpdateCollection,
    UpdateCollectionPackage,
)

record = UpdateRecord()
record.id = "RHSA-2024:1234"
record.title = "Critical: kernel security update"
record.update_type = "security"
record.severity = "Critical"
record.issued_date = "2024-03-15"
record.summary = "An update for kernel is now available."
record.description = "The kernel packages contain the Linux kernel."

# Add a reference
ref = UpdateReference(
    href="https://bugzilla.redhat.com/show_bug.cgi?id=12345",
    id="12345",
    title="kernel vulnerability",
    reftype="bugzilla",
)
record.references = [ref]

# Add affected packages
pkg = UpdateCollectionPackage()
pkg.name = "kernel"
pkg.version = "5.14.0"
pkg.release = "362.24.1.el9_3"
pkg.arch = "x86_64"
pkg.epoch = "0"
pkg.filename = "kernel-5.14.0-362.24.1.el9_3.x86_64.rpm"

collection = UpdateCollection(name="Red Hat Enterprise Linux 9", shortname="RHEL-9")
collection.packages = [pkg]
record.pkglist = [collection]

Rust library

This package is built on a Rust library of the same name, also available on crates.io. See the Rust README and API documentation for Rust usage.

License

Mozilla Public License 2.0

Metadata

Release files for rpmrepo-metadata 0.8.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for rpmrepo-metadata 0.8.3
File Size Uploaded Provenance Actions
rpmrepo_metadata-0.8.3.tar.gz 108.0 kB With provenance Details for rpmrepo_metadata-0.8.3.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for rpmrepo-metadata 0.8.3
File Actions
rpmrepo_metadata-0.8.3-cp310-abi3-win_amd64.whl CPython 3.10 abi3 Windows x86-64 Details for rpmrepo_metadata-0.8.3-cp310-abi3-win_amd64.whl
rpmrepo_metadata-0.8.3-cp310-abi3-manylinux_2_28_x86_64.whl CPython 3.10 abi3 Linux glibc 2.28+ x86-64 Details for rpmrepo_metadata-0.8.3-cp310-abi3-manylinux_2_28_x86_64.whl
rpmrepo_metadata-0.8.3-cp310-abi3-manylinux_2_28_aarch64.whl CPython 3.10 abi3 Linux glibc 2.28+ ARM64 Details for rpmrepo_metadata-0.8.3-cp310-abi3-manylinux_2_28_aarch64.whl
rpmrepo_metadata-0.8.3-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details for rpmrepo_metadata-0.8.3-cp310-abi3-macosx_11_0_arm64.whl

Total release size: 15.9 MB

Release files / rpmrepo_metadata-0.8.3.tar.gz

Download URL rpmrepo_metadata-0.8.3.tar.gz
Size 108.0 kB
Tags Source
SHA-256 checksum
How to use checksums
40ac64cb8c54b437d27e72dba121afc9ccad9070c9026df96fa3a0c7359beafd
BLAKE2b-256 checksum
How to use checksums
6ec2d82d331ea5ac7cb07f8439c90fe302993eabfa35eea0c9a95fa35bae5e80
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release files / rpmrepo_metadata-0.8.3-cp310-abi3-win_amd64.whl

Download URL rpmrepo_metadata-0.8.3-cp310-abi3-win_amd64.whl
Size 1.2 MB
Tags CPython 3.10 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
7c1cbb29042adf48523e9143cf4496701e5b03b844eefd0a53c21e2efe0c732b
BLAKE2b-256 checksum
How to use checksums
52eadf491d6ae60454560363836e5e71c2ebcabbc09b442ed73c892630538ecc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release files / rpmrepo_metadata-0.8.3-cp310-abi3-manylinux_2_28_x86_64.whl

Download URL rpmrepo_metadata-0.8.3-cp310-abi3-manylinux_2_28_x86_64.whl
Size 7.0 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
a4177913a831eb9f04a1f691c06000530178b3743e39a7da0d650de140adb6ce
BLAKE2b-256 checksum
How to use checksums
e2f1cbd3aeb80a334536e70664373597058742637b4af7e0d5ca2d0ba91c3e78
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release files / rpmrepo_metadata-0.8.3-cp310-abi3-manylinux_2_28_aarch64.whl

Download URL rpmrepo_metadata-0.8.3-cp310-abi3-manylinux_2_28_aarch64.whl
Size 6.3 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
9878c88b83630f226f8b137d0fe2abb3274f3df7a02f65d90f96f2586e042e30
BLAKE2b-256 checksum
How to use checksums
6858226bd1144b68be02528d40aabb37db69e80bfd7bce6bbb46b12aa156bfc3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release files / rpmrepo_metadata-0.8.3-cp310-abi3-macosx_11_0_arm64.whl

Download URL rpmrepo_metadata-0.8.3-cp310-abi3-macosx_11_0_arm64.whl
Size 1.3 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
6b201a8aecce1e395334a6b7b31c74ac58688ab71e2db12b93da4437aa2fb31c
BLAKE2b-256 checksum
How to use checksums
66507fa86b1233a8c8e62c35d3828ab8905e0dc7a24cc544fe836fd8ca5deab8
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Security for rpmrepo-metadata 0.8.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 5 files in this release have been uploaded with provenance metadata.

Select from 5 files

Attestation for rpmrepo_metadata-0.8.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page