Of course. The term "Python crypto rpm" can refer to a few different things, but the most common and practical meaning is "How to create an RPM package for a Python library that provides cryptographic functionality."

I will guide you through this process step-by-step. We'll cover:
- Prerequisites: What you need installed on your system.
- Example Project: A simple Python script and a
setup.pyfile for our crypto library. - The
specFile: The heart of the RPM build process, explained in detail. - Building the RPM: The commands to create the final package.
- Verification: How to check and install the resulting RPM.
Prerequisites
You need a system with the RPM package manager and the necessary tools for building Python packages.
For Fedora / CentOS / RHEL:
# Install the RPM build tools and Python development headers sudo dnf install rpm-build python3-devel redhat-rpm-config
For openSUSE:

sudo zypper install rpm-build python3-devel
This gives you:
rpm-build: The core tool for building RPMs.python3-devel: Provides the C header files needed to compile Python extensions.redhat-rpm-config(on RHEL-based systems): Contains default macros and configurations that simplify building for Python.
Example Project Structure
Let's create a simple Python library called pycrypto_lite. It will have one function to encrypt a string.
Create the following directory structure:
pycrypto-lite/
├── pycrypto_lite/
│ ├── __init__.py
│ └── crypto.py
├── setup.py
└── pycrypto-lite.spec <-- We will create this next
File: pycrypto_lite/pycrypto_lite/__init__.py

# This file makes the pycrypto_lite directory a Python package from .crypto import encrypt_string __version__ = "0.1.0" __all__ = ["encrypt_string"]
File: pycrypto_lite/pycrypto_lite/crypto.py
import base64
from cryptography.fernet import Fernet
def encrypt_string(message: str, key: bytes = None) -> str:
"""
Encrypts a string using Fernet symmetric encryption.
Args:
message: The string to encrypt.
key: Optional 32-byte URL-safe base64-encoded key. If None, a new key is generated.
Returns:
A base64-encoded encrypted string.
"""
if key is None:
# In a real app, you would load or generate a key securely.
# For this example, we'll generate one on each call.
# WARNING: This is NOT secure for production use.
key = Fernet.generate_key()
f = Fernet(key)
encrypted_message = f.encrypt(message.encode())
return encrypted_message.decode()
File: pycrypto_lite/setup.py
This is the standard Python file for defining how to package your library.
from setuptools import setup, find_packages
with open("README.md", "r", encoding="utf-8") as fh:
long_description = fh.read()
setup(
name="pycrypto-lite",
version="0.1.0",
author="Your Name",
author_email="your.email@example.com",
description="A simple lightweight Python cryptography library.",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/yourusername/pycrypto-lite",
packages=find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
],
python_requires=">=3.6",
install_requires=[
'cryptography', # This is the key dependency
],
)
The spec File: pycrypto-lite.spec
This is the most important file. It tells the rpmbuild tool how to build your package, what files to include, dependencies, metadata, etc.
Create pycrypto-lite.spec in the root of your project (pycrypto-lite/).
# The name of the RPM package. Must be lowercase and use underscores.
Name: pycrypto-lite
# The version of your software.
Version: 0.1.0
# The release number of the RPM package. Increment this for rebuilds of the same version.
Release: 1%{?dist}
# The license of your software.
License: MIT
# A short summary of the package.
Summary: A simple lightweight Python cryptography library
# The URL for the project.
URL: https://github.com/yourusername/pycrypto-lite
# The email of the packager.
#Vendor:
#Distribution:
# The source code. rpmbuild will fetch this URL.
# For local builds, you can use: Source0: %{name}-%{version}.tar.gz
# We will create this tarball in the build step.
Source0: %{name}-%{version}.tar.gz
# Build requirements. These are needed to build the package.
BuildRequires: python3-devel
BuildRequires: python3-setuptools
# Runtime requirements. These will be installed when the user installs the RPM.
Requires: python3
Requires: python3-cryptography
%description
A simple Python library that provides basic cryptographic functions.
This package provides an easy-to-use interface for common operations.
%prep
# Prepares the build environment.
# %autosetup extracts the Source0 tarball and cd's into the directory.
%autosetup
%build
# The build step. Here we run 'python3 setup.py build'.
# The %{__python3} macro resolves to the path of the python3 interpreter.
%{__python3} setup.py build
%install
# The install step. Here we run 'python3 setup.py install' into a temporary
# directory ($RPM_BUILD_ROOT), so the files aren't installed on your system.
%{__python3} setup.py install --root=$RPM_BUILD_ROOT
%files
# This section lists all the files that will be included in the RPM.
# Use macros to ensure paths are correct across different systems.
# The main Python package directory
%{python3_sitelib}/pycrypto_lite/
# The metadata file for the package
%{python3_sitelib}/pycrypto_lite-*.dist-info/
%changelog
* Wed Oct 26 2025 Your Name <your.email@example.com> - 0.1.0-1
- Initial package
Key spec File Concepts:
Name,Version,Release: The core identity of your package.Source0: Points to your source tarball. We'll create this automatically.BuildRequires: Packages needed to build the RPM (e.g., compilers, headers).Requires: Packages needed to run the software after installation. This is crucial. We specifypython3-cryptography, which is the name of thecryptographylibrary in the Fedora/CentOS repositories.%prep: Prepares the source.%autosetupis a modern macro that does the heavy lifting.%build: Compiles/installs the software into a temporary build directory.%install: Installs the software into the final destination ($RPM_BUILD_ROOT).%files: Lists every file that will be in the final RPM. Using macros like%{python3_sitelib}is essential for portability.
Building the RPM
Now, let's put it all together. You must be in the directory containing setup.py and pycrypto-lite.spec.
# Navigate to your project root directory cd /path/to/pycrypto-lite
Step 1: Create the Source Tarball
The rpmbuild tool expects a gzipped tarball (.tar.gz) as the source.
# Create a tarball from the project directory # The --exclude flag is important to exclude the spec file and build artifacts # if you are running this from within the project directory. tar --exclude='*.spec' --exclude='build' --exclude='dist' -czvf pycrypto-lite-0.1.0.tar.gz .
Step 2: Run rpmbuild
The standard practice is to build RPMs in a separate directory structure to avoid polluting your source tree.
# Create the required directory structure
mkdir -p ~/rpmbuild/{SOURCES,SRPMS,RPMS,BUILD,BUILDROOT}
# Link your source tarball into the SOURCES directory
ln -s $(pwd)/pycrypto-lite-0.1.0.tar.gz ~/rpmbuild/SOURCES/
# Build the binary RPM
# The -ba flag means "build source and binary packages"
rpmbuild -ba pycrypto-lite.spec
Where is the output?
If the build is successful, the final RPM will be in your ~/rpmbuild/RPMS/ directory, likely inside a subdirectory named noarch (for architecture-independent Python packages).
# Find the RPM file find ~/rpmbuild/RPMS/ -name "*.rpm" # Example output: # /home/user/rpmbuild/RPMS/noarch/pycrypto-lite-0.1.0-1.fc38.noarch.rpm
Verification and Installation
You now have a valid RPM file! Let's inspect it and install it.
Inspect the RPM metadata:
Use the rpm command to check the contents and dependencies.
# Replace with the actual path to your RPM file rpm -qip /home/user/rpmbuild/RPMS/noarch/pycrypto-lite-0.1.0-1.fc38.noarch.rpm
Output:
Name : pycrypto-lite
Version : 0.1.0
Release : 1.fc38
Architecture: noarch
Install Date: (not installed)
Size : 13 k
License : MIT
Signature : (none)
Source RPM : pycrypto-lite-0.1.0-1.fc38.src.rpm
Build Date : Wed Oct 26 10:30:00 2025
Build Host : myhostname
Relocations : (not relocatable)
Packager : Your Name
Vendor :
Summary : A simple lightweight Python cryptography library
Description :
A simple Python library that provides basic cryptographic functions.
This package provides an easy-to-use interface for common operations.
List the files inside the RPM:
rpm -qlp /home/user/rpmbuild/RPMS/noarch/pycrypto-lite-0.1.0-1.fc38.noarch.rpm
Output:
/usr/lib/python3.11/site-packages/pycrypto_lite/__init__.py
/usr/lib/python3.11/site-packages/pycrypto_lite/__pycache__/__init__.cpython-311.pyc
/usr/lib/python3.11/site-packages/pycrypto_lite/__pycache__/crypto.cpython-311.pyc
/usr/lib/python3.11/site-packages/pycrypto_lite/crypto.py
/usr/lib/python3.11/site-packages/pycrypto_lite-0.1.0.dist-info/RECORD
/usr/lib/python3.11/site-packages/pycrypto_lite-0.1.0.dist-info/WHEEL
/usr/lib/python3.11/site-packages/pycrypto_lite-0.1.0.dist-info/METADATA
/usr/lib/python3.11/site-packages/pycrypto_lite-0.1.0.dist-info/top_level.txt
Install the RPM:
# Use sudo to install system-wide sudo dnf install /home/user/rpmbuild/RPMS/noarch/pycrypto-lite-0.1.0-1.fc38.noarch.rpm
Test the installation: Create a small test script to ensure the package works.
File: test_install.py
from pycrypto_lite import encrypt_string
if __name__ == "__main__":
message = "Hello, secure world!"
encrypted = encrypt_string(message)
print(f"Original: {message}")
print(f"Encrypted: {encrypted}")
Run it:
python3 test_install.py
You should see the encrypted output, confirming the package was built and installed correctly.
