Skip to main content

Python bindings for rpmrepo_metadata: create and parse RPM repository metadata

Project description

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_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

Mozilla Public License 2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rpmrepo_metadata-0.5.3.tar.gz (86.2 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

rpmrepo_metadata-0.5.3-cp310-abi3-win_amd64.whl (1.1 MB view details)

Uploaded CPython 3.10+Windows x86-64

rpmrepo_metadata-0.5.3-cp310-abi3-manylinux_2_28_x86_64.whl (6.6 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ x86-64

rpmrepo_metadata-0.5.3-cp310-abi3-manylinux_2_28_aarch64.whl (6.1 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

rpmrepo_metadata-0.5.3-cp310-abi3-macosx_11_0_arm64.whl (1.2 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

Details for the file rpmrepo_metadata-0.5.3.tar.gz.

File metadata

  • Download URL: rpmrepo_metadata-0.5.3.tar.gz
  • Upload date:
  • Size: 86.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rpmrepo_metadata-0.5.3.tar.gz
Algorithm Hash digest
SHA256 d3a5721dd1148c4d452103abbb596d63966be17ebe1f82f277fcab9f3f7b34d4
MD5 78eb4eafec455b7f446c0caf9d05f84d
BLAKE2b-256 2ffcc92e34683303ad2662180923de2e751d31784ee2ec7f6c9ab09b751cd2b4

See more details on using hashes here.

Provenance

The following attestation bundles were made for rpmrepo_metadata-0.5.3.tar.gz:

Publisher: release.yml on dralley/rpmrepo_metadata

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rpmrepo_metadata-0.5.3-cp310-abi3-win_amd64.whl.

File metadata

File hashes

Hashes for rpmrepo_metadata-0.5.3-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 4f7682855b46d5517d1086e42aae6045c08c8ccad1d4b06dff7acb139c677dc9
MD5 cea35be499ae0011712cf9a7d587a6d0
BLAKE2b-256 328b60f9626dcb765edbe40503d7c63f7022d75f3721d239a4441c556d1388cb

See more details on using hashes here.

Provenance

The following attestation bundles were made for rpmrepo_metadata-0.5.3-cp310-abi3-win_amd64.whl:

Publisher: release.yml on dralley/rpmrepo_metadata

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rpmrepo_metadata-0.5.3-cp310-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for rpmrepo_metadata-0.5.3-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 41f902dc6b10c73ca636b705317ca87098204e6654e147986e3bfed7f58c5d8e
MD5 9377f08c81b53913db1b49c5c9e3b25d
BLAKE2b-256 bf8efb6b6e4b99139d90eca224ee4143db7eb850b8d872f47671a9c2cd23a6ad

See more details on using hashes here.

Provenance

The following attestation bundles were made for rpmrepo_metadata-0.5.3-cp310-abi3-manylinux_2_28_x86_64.whl:

Publisher: release.yml on dralley/rpmrepo_metadata

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rpmrepo_metadata-0.5.3-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for rpmrepo_metadata-0.5.3-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 e179542541b383209fe0f61b8fd78d7c968746ec596e8070303709cc305cf21f
MD5 3cfc8d98e90602d448c1265e8bce5e47
BLAKE2b-256 4ad0d7f5984254c8a4e6ad45b74c8387384583328ebfa9f0cb33ae13fc7fd288

See more details on using hashes here.

Provenance

The following attestation bundles were made for rpmrepo_metadata-0.5.3-cp310-abi3-manylinux_2_28_aarch64.whl:

Publisher: release.yml on dralley/rpmrepo_metadata

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rpmrepo_metadata-0.5.3-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for rpmrepo_metadata-0.5.3-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 464e7adc5cd491170fa073130afd33c4a2024c6545206181e15c3c9e7db41d35
MD5 bb3f609a1045ceb9df193606720c602e
BLAKE2b-256 9c3def9e2235586e146b2e9623c9e0b9e0ac0973dde2e1c3030e76f1d9c98c08

See more details on using hashes here.

Provenance

The following attestation bundles were made for rpmrepo_metadata-0.5.3-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: release.yml on dralley/rpmrepo_metadata

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page