{"id":1126,"library":"python-gnupg","title":"Python-GnuPG","description":"Python-GnuPG is a Python wrapper for the GNU Privacy Guard (GnuPG) command-line tool, enabling Python programs to perform cryptographic operations like encryption, decryption, digital signing, and key management. It provides a high-level, Pythonic interface to GnuPG's functionality. The library is actively maintained, with version 2.3.1 being the latest as of April 2026, and typically follows GnuPG's release cycle for compatibility updates.","status":"active","version":"2.3.1","language":"python","source_language":"en","source_url":"https://github.com/isislovecruft/python-gnupg","tags":["gnupg","gpg","encryption","cryptography","security","wrapper","openpgp"],"install":[{"cmd":"pip install python-gnupg","lang":"bash","label":"Install with pip"}],"dependencies":[{"reason":"This library is a wrapper around the GnuPG command-line tool; the 'gpg' executable must be installed and accessible on the system.","package":"GnuPG","optional":false}],"imports":[{"note":"The primary class 'GPG' is typically accessed as 'gnupg.GPG' after importing the top-level 'gnupg' module.","wrong":"from gnupg import GPG","symbol":"GPG","correct":"import gnupg\ngpg = gnupg.GPG()"}],"quickstart":{"code":"import gnupg\nimport os\n\n# Ensure the GnuPG home directory exists and has correct permissions\ngnupghome = os.path.expanduser('~/.gnupg_test')\nif not os.path.exists(gnupghome):\n    os.makedirs(gnupghome, mode=0o700)\n\ngpg = gnupg.GPG(gnupghome=gnupghome)\n# Ensure the GnuPG binary path is correct if not in system PATH\n# gpg = gnupg.GPG(gnupghome=gnupghome, gpgbinary='/usr/local/bin/gpg')\n\n# Generate a key pair (example, use stronger keys and secure passphrases in production)\npassphrase = os.environ.get('GPG_PASSPHRASE', 'mysecurepassphrase')\ninput_data = gpg.gen_key_input(\n    key_type=\"RSA\",\n    key_length=2048,\n    name_real=\"Test User\",\n    name_email=\"test@example.com\",\n    passphrase=passphrase\n)\nkey = gpg.gen_key(input_data)\n\nif key:\n    print(f\"Generated Key ID: {key.fingerprint}\")\n\n    # Encrypt a message\n    message = \"Hello, GnuPG! This is a secret message.\"\n    encrypted_data = gpg.encrypt(message, recipients=[key.fingerprint], passphrase=passphrase)\n\n    if encrypted_data.ok:\n        print(\"\\nEncrypted Message:\")\n        print(str(encrypted_data))\n\n        # Decrypt the message\n        decrypted_data = gpg.decrypt(str(encrypted_data), passphrase=passphrase)\n\n        if decrypted_data.ok:\n            print(\"\\nDecrypted Message:\")\n            print(str(decrypted_data))\n            assert str(decrypted_data) == message\n        else:\n            print(f\"\\nDecryption Failed: {decrypted_data.status}\")\n            print(f\"Stderr: {decrypted_data.stderr}\")\n    else:\n        print(f\"\\nEncryption Failed: {encrypted_data.status}\")\n        print(f\"Stderr: {encrypted_data.stderr}\")\nelse:\n    print(f\"Key generation failed: {gpg.gen_key(input_data).stderr}\")","lang":"python","description":"This quickstart demonstrates how to initialize the GPG object, generate a new key pair, encrypt a string using the generated public key, and then decrypt it using the corresponding private key and passphrase. It emphasizes the importance of setting a `gnupghome` directory for GnuPG operations."},"warnings":[{"fix":"Add `allow-loopback-pinentry` as a single line to the `gpg-agent.conf` file in the GnuPG home directory being used by your application. Some specific 2.1.x versions may still exhibit unhelpful behavior. Ensure you have a recent, stable GnuPG executable.","message":"GnuPG versions 2.1 and later changed passphrase handling. Programmatic passphrase input (e.g., for `gen_key`, `decrypt`) often requires `allow-loopback-pinentry` to be present in `gpg-agent.conf` within your GnuPG home directory. Without this, GnuPG might prompt interactively or fail, even if a passphrase is provided in the Python code.","severity":"breaking","affected_versions":"GnuPG >= 2.1 (not python-gnupg versions)"},{"fix":"Always ensure the directory specified for `gnupghome` (and its contents, especially keyrings) has strict permissions, ideally `chmod 0o700 /path/to/gnupghome`. When running in environments like web servers or Docker, verify the user executing the Python script has appropriate ownership and permissions.","message":"File permissions for the GnuPG home directory (`gnupghome`) are critical. GnuPG is very particular about permissions (typically `0o700` or `rwx------` for the owner). Incorrect permissions can lead to 'secret key not available' or other unexpected failures, even if the key exists.","severity":"gotcha","affected_versions":"All"},{"fix":"Explicitly pass the full path to the GnuPG executable, e.g., `gpg = gnupg.GPG(gpgbinary='/usr/local/bin/gpg', gnupghome='...')`, or ensure `gpg` is discoverable via the system's PATH environment variable for the user running the Python script.","message":"The `gpgbinary` parameter to `gnupg.GPG()` is crucial if the `gpg` executable is not in the system's PATH. If `python-gnupg` cannot find the `gpg` binary, it will fail to initialize or execute GnuPG commands.","severity":"gotcha","affected_versions":"All"},{"fix":"Omit the `secret_keyring` argument when initializing `gnupg.GPG` if you are using GnuPG 2.1 or newer. The primary `keyring` argument should still be used if you need to specify a non-default keyring file name.","message":"The `secret_keyring` argument for `gnupg.GPG` is no longer used when working with GnuPG versions 2.1 and later, as GnuPG 2.1+ merges public and secret keyrings.","severity":"deprecated","affected_versions":"python-gnupg versions used with GnuPG >= 2.1"},{"fix":"Set the `gpg.encoding` attribute explicitly to `utf-8` or another appropriate encoding if your data contains non-`latin-1` characters, especially when dealing with text. E.g., `gpg = gnupg.GPG(encoding='utf-8', ...)`.","message":"Default encoding for I/O with GnuPG commands changed from locale-based/UTF-8 to `latin-1` in `python-gnupg` version 0.3.7. Using the wrong encoding can lead to exceptions or data corruption, especially with non-ASCII characters.","severity":"gotcha","affected_versions":"python-gnupg < 0.3.7 might have different defaults; all versions require careful encoding handling."}],"env_vars":null,"search_vec":"'2.3.1':55 '2026':62 'activ':51 'april':61 'command':18 'command-lin':17 'compat':71 'cryptograph':26 'cryptographi':76 'cycl':69 'decrypt':30 'digit':31 'enabl':21 'encrypt':29,75 'follow':65 'function':47 'gnu':13 'gnupg':3,6,16,45,66,73 'gpg':74 'guard':15 'high':40 'high-level':39 'interfac':43 'key':34 'latest':58 'level':41 'librari':49 'like':28 'line':19 'maintain':52 'manag':35 'openpgp':79 'oper':27 'perform':25 'privaci':14 'program':23 'provid':37 'python':2,5,9,22,42 'python-gnupg':1,4 'releas':68 'secur':77 'sign':32 'tool':20 'typic':64 'updat':72 'version':54 'wrapper':10,78","created_at":"2026-04-05T13:06:48.850688+00:00","updated_at":"2026-04-16T20:21:05.982113+00:00","problems":[{"fix":"Install GnuPG on your system and ensure its executable is in your system's PATH. Alternatively, specify the exact path to the `gpg` binary when initializing `gnupg.GPG`: `gpg = gnupg.GPG(gpgbinary='/usr/local/bin/gpg')`.","cause":"The `gpg` executable, which `python-gnupg` wraps, is not installed on the system or is not discoverable in the system's PATH.","error":"FileNotFoundError: [Errno 2] No such file or directory: 'gpg'"},{"fix":"Encode the string to bytes (e.g., using `str.encode()`) before passing it to the GnuPG function: `encrypted_data = gpg.encrypt(plaintext_data.encode('utf-8'), recipients)`.","cause":"`python-gnupg` functions like `encrypt`, `decrypt`, `sign`, or `verify` expect binary data (bytes) as input, but a Python string was provided.","error":"TypeError: a bytes-like object is required, not 'str'"},{"fix":"Ensure the correct private key is available in the `gnupghome` keyring, provide the correct passphrase using the `passphrase` argument, or verify the integrity and correct encryption of the input data. Check `result.stderr` for more detailed GnuPG error messages.","cause":"Decryption or signature verification failed because the necessary private key was not found in the keyring, the passphrase was incorrect, or the encrypted data was corrupted. The `gpg.decrypt()` or `gpg.verify()` method returns a result object with `ok=False` and this status.","error":"\"decryption failed\""},{"fix":"Create the `gnupghome` directory manually or programmatically with appropriate permissions before initializing `gnupg.GPG`: `import os; os.makedirs('/path/to/gnupghome', exist_ok=True); gpg = gnupg.GPG(gnupghome='/path/to/gnupghome')`.","cause":"The directory specified for `gnupghome`, which GnuPG uses for keyrings and configuration, does not exist on the filesystem or is inaccessible.","error":"ValueError: GnuPG home directory does not exist: /path/to/gnupghome"}],"ecosystem":"pypi","meta_description":null,"install_score":100,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"0.5.6","cli_name":"","cli_version":null,"type":"library","homepage":null,"github":"https://github.com/vsajip/python-gnupg","docs":"https://gnupg.readthedocs.io/","changelog":null,"pypi":"https://pypi.org/project/python-gnupg/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["auth-security","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-27","next_check":"2026-07-28","install_tag":"verified"}}