Python bindings for rpmrepo_metadata: create and parse RPM repository metadata
Project description
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_with_options(
"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}")
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
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rpmrepo_metadata-0.5.2.tar.gz.
File metadata
- Download URL: rpmrepo_metadata-0.5.2.tar.gz
- Upload date:
- Size: 86.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Fedora Linux","version":"44","id":"","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7da7505cac50a960139ec6802dcdf8c0e959272f3c37ea82d5908cae34977121
|
|
| MD5 |
9aae77e4a34b70275a4e9034985252f2
|
|
| BLAKE2b-256 |
0124a0d6b5647f2657ba4ea797ff1ab783405243d47bff689879a8463c474dd8
|
File details
Details for the file rpmrepo_metadata-0.5.2-cp310-abi3-win_amd64.whl.
File metadata
- Download URL: rpmrepo_metadata-0.5.2-cp310-abi3-win_amd64.whl
- Upload date:
- Size: 1.1 MB
- Tags: CPython 3.10+, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
946ff7f9cbe4c359c25bbf63b47feeecbb1af6ed5d57380bbbc8759feb58ab18
|
|
| MD5 |
103c9e660100e0fd1435f6d48f1182a0
|
|
| BLAKE2b-256 |
e18aa6e2ce44d3555a2eb89e02d6ce59277bc69764344509ab958479b52d64f3
|
Provenance
The following attestation bundles were made for rpmrepo_metadata-0.5.2-cp310-abi3-win_amd64.whl:
Publisher:
release.yml on dralley/rpmrepo_metadata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rpmrepo_metadata-0.5.2-cp310-abi3-win_amd64.whl -
Subject digest:
946ff7f9cbe4c359c25bbf63b47feeecbb1af6ed5d57380bbbc8759feb58ab18 - Sigstore transparency entry: 1714601351
- Sigstore integration time:
-
Permalink:
dralley/rpmrepo_metadata@dc4653abbd0503189dcb1fe40dcf72abe275ba3c -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/dralley
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@dc4653abbd0503189dcb1fe40dcf72abe275ba3c -
Trigger Event:
push
-
Statement type:
File details
Details for the file rpmrepo_metadata-0.5.2-cp310-abi3-manylinux_2_28_x86_64.whl.
File metadata
- Download URL: rpmrepo_metadata-0.5.2-cp310-abi3-manylinux_2_28_x86_64.whl
- Upload date:
- Size: 6.6 MB
- Tags: CPython 3.10+, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b365ba568df50f9a6cc740e8e38ad9f91d84eb31e1bb57c5ed0027c67fbf35bd
|
|
| MD5 |
a5c66e206a7e0bc2cc6ca62caf246449
|
|
| BLAKE2b-256 |
5181799805a69e1b32040ad04933f908484ca1926bb805b162cc8740d57719f5
|
Provenance
The following attestation bundles were made for rpmrepo_metadata-0.5.2-cp310-abi3-manylinux_2_28_x86_64.whl:
Publisher:
release.yml on dralley/rpmrepo_metadata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rpmrepo_metadata-0.5.2-cp310-abi3-manylinux_2_28_x86_64.whl -
Subject digest:
b365ba568df50f9a6cc740e8e38ad9f91d84eb31e1bb57c5ed0027c67fbf35bd - Sigstore transparency entry: 1714601533
- Sigstore integration time:
-
Permalink:
dralley/rpmrepo_metadata@dc4653abbd0503189dcb1fe40dcf72abe275ba3c -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/dralley
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@dc4653abbd0503189dcb1fe40dcf72abe275ba3c -
Trigger Event:
push
-
Statement type:
File details
Details for the file rpmrepo_metadata-0.5.2-cp310-abi3-manylinux_2_28_aarch64.whl.
File metadata
- Download URL: rpmrepo_metadata-0.5.2-cp310-abi3-manylinux_2_28_aarch64.whl
- Upload date:
- Size: 6.1 MB
- Tags: CPython 3.10+, manylinux: glibc 2.28+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
279b62bd805e2f4dab9419fe4602b0cdbf6b1d2c72b9631f1b4509bddc9cac65
|
|
| MD5 |
8972a4f167e6e0e4fe0744ce097f19e4
|
|
| BLAKE2b-256 |
62c08ed2de0037bbce0ec61e6a234cc74af2785ab661c4f4f21cd41892135ff9
|
Provenance
The following attestation bundles were made for rpmrepo_metadata-0.5.2-cp310-abi3-manylinux_2_28_aarch64.whl:
Publisher:
release.yml on dralley/rpmrepo_metadata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rpmrepo_metadata-0.5.2-cp310-abi3-manylinux_2_28_aarch64.whl -
Subject digest:
279b62bd805e2f4dab9419fe4602b0cdbf6b1d2c72b9631f1b4509bddc9cac65 - Sigstore transparency entry: 1714601284
- Sigstore integration time:
-
Permalink:
dralley/rpmrepo_metadata@dc4653abbd0503189dcb1fe40dcf72abe275ba3c -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/dralley
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@dc4653abbd0503189dcb1fe40dcf72abe275ba3c -
Trigger Event:
push
-
Statement type:
File details
Details for the file rpmrepo_metadata-0.5.2-cp310-abi3-macosx_11_0_arm64.whl.
File metadata
- Download URL: rpmrepo_metadata-0.5.2-cp310-abi3-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.2 MB
- Tags: CPython 3.10+, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6c368acfa7b13e723bda89f1f9c070bc47a86078c488a3ca90df87ae83f666c
|
|
| MD5 |
bcce8f38a5533397696bc9f1f2bfd253
|
|
| BLAKE2b-256 |
3785af86fb455694144bc70b41a3e8d1662c423dad9f034ba6884edfa365b8cd
|
Provenance
The following attestation bundles were made for rpmrepo_metadata-0.5.2-cp310-abi3-macosx_11_0_arm64.whl:
Publisher:
release.yml on dralley/rpmrepo_metadata
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rpmrepo_metadata-0.5.2-cp310-abi3-macosx_11_0_arm64.whl -
Subject digest:
b6c368acfa7b13e723bda89f1f9c070bc47a86078c488a3ca90df87ae83f666c - Sigstore transparency entry: 1714601426
- Sigstore integration time:
-
Permalink:
dralley/rpmrepo_metadata@dc4653abbd0503189dcb1fe40dcf72abe275ba3c -
Branch / Tag:
refs/tags/v0.5.2 - Owner: https://github.com/dralley
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@dc4653abbd0503189dcb1fe40dcf72abe275ba3c -
Trigger Event:
push
-
Statement type: