rpmrepo_metadata
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
Metadata
Release files for rpmrepo-metadata 0.8.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rpmrepo_metadata-0.8.0.tar.gz | 107.5 kB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| rpmrepo_metadata-0.8.0-cp310-abi3-win_amd64.whl | CPython 3.10 | abi3 | Windows x86-64 | Details |
| rpmrepo_metadata-0.8.0-cp310-abi3-manylinux_2_28_x86_64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ x86-64 | Details |
| rpmrepo_metadata-0.8.0-cp310-abi3-manylinux_2_28_aarch64.whl | CPython 3.10 | abi3 | Linux glibc 2.28+ ARM64 | Details |
| rpmrepo_metadata-0.8.0-cp310-abi3-macosx_11_0_arm64.whl | CPython 3.10 | abi3 | macOS 11.0+ ARM64 | Details |
Total release size: 15.8 MB
Release files / rpmrepo_metadata-0.8.0.tar.gz
| Download URL | rpmrepo_metadata-0.8.0.tar.gz |
|---|---|
| Size | 107.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
37c4752a5c0a265a334b53d6226d4659feffa12f8c247e64c5bc105f4c296db5
|
|
BLAKE2b-256 checksum How to use checksums |
e2ad5bd0c5368dfd3d6443cadfe095030e1b736678622bbb42ce345d593f2d40
|
| 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 1, 2026.
Transparency logRelease files / rpmrepo_metadata-0.8.0-cp310-abi3-win_amd64.whl
| Download URL | rpmrepo_metadata-0.8.0-cp310-abi3-win_amd64.whl |
|---|---|
| Size | 1.2 MB |
| Tags | CPython 3.10 Windows x86-64 abi3 |
|
SHA-256 checksum How to use checksums |
9ca132c3f01904e9927f3bb45aae6a537b4aabe7c1d92e587af79426ccc3d290
|
|
BLAKE2b-256 checksum How to use checksums |
647753621135e234c46f334748e58599ab7de2e1db56a31a38f9f9c02e6cceab
|
| 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 1, 2026.
Transparency logRelease files / rpmrepo_metadata-0.8.0-cp310-abi3-manylinux_2_28_x86_64.whl
| Download URL | rpmrepo_metadata-0.8.0-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 |
e4fdad3f8c45055fe05e25bab0794a968d9d6ae4f08a24d09aae504f4c64c001
|
|
BLAKE2b-256 checksum How to use checksums |
2a82ce832919d25d4261d7df3c13bf6d634f4558f028a8558bf92b4d25a3989f
|
| 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 1, 2026.
Transparency logRelease files / rpmrepo_metadata-0.8.0-cp310-abi3-manylinux_2_28_aarch64.whl
| Download URL | rpmrepo_metadata-0.8.0-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 |
1bd594ea1a7678ad26ba4f93317bdf9e75cd66a36beca9d8d482334634b5c92e
|
|
BLAKE2b-256 checksum How to use checksums |
c55355300a940c77972796d058ed094ed8f6d005eae26779fb56922386f8f117
|
| 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 1, 2026.
Transparency logRelease files / rpmrepo_metadata-0.8.0-cp310-abi3-macosx_11_0_arm64.whl
| Download URL | rpmrepo_metadata-0.8.0-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 |
34c408a61e6f97e455357707a5af95c9c69147cf39fd98287ce6ac108a474258
|
|
BLAKE2b-256 checksum How to use checksums |
cf6e7a6b5fcca0314146d967955485eb8cb90b347ef30568f6d300f15cc87f44
|
| 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 1, 2026.
Transparency log