{"id":4198,"library":"pymongocrypt","title":"PyMongoCrypt","description":"PyMongoCrypt provides the Python bindings for `libmongocrypt`, a C library that powers MongoDB's Client-Side Field Level Encryption (CSFLE) and Queryable Encryption features. It is currently at version 1.17.0 and releases are typically tied to `libmongocrypt` and PyMongo updates, often occurring every few months.","status":"active","version":"1.17.0","language":"en","source_language":"en","source_url":"https://github.com/mongodb/libmongocrypt/tree/master/bindings/python","tags":["mongodb","encryption","database","security","csfle"],"install":[{"cmd":"pip install pymongocrypt","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"note":"While pymongocrypt provides the underlying C bindings, the high-level Python API for client-side encryption is exposed through `pymongo.encryption.ClientEncryption`.","wrong":"from pymongocrypt import ClientEncryption","symbol":"ClientEncryption","correct":"from pymongo.encryption import ClientEncryption"},{"note":"For advanced use cases or direct interaction with `libmongocrypt`'s FFI, the `_lib` module can be imported. This is less common for typical application development.","symbol":"_lib","correct":"from pymongocrypt import _lib"}],"quickstart":{"code":"import os\nfrom pymongo import MongoClient\nfrom pymongo.encryption import ClientEncryption\n\n# A 96-byte local master key (for demonstration purposes).\n# In production, use a secure Key Management System (KMS).\nlocal_key = os.environ.get(\"MONGO_LOCAL_MASTER_KEY\", \"A\" * 96).encode('utf-8')\nif len(local_key) != 96:\n    # Generate a temporary key if not set correctly for quick local run\n    local_key = os.urandom(96)\n    print(f\"WARNING: MONGO_LOCAL_MASTER_KEY not set or invalid length. Using a generated temporary key.\")\n\nkms_providers = {\n    \"local\": {\"key\": local_key}\n}\n\n# Key Vault setup\nconnection_string = os.environ.get(\"MONGO_URI\", \"mongodb://localhost:27017/\")\nclient = MongoClient(connection_string)\nkey_vault_db = \"encryption\"\nkey_vault_coll = \"__keyVault\"\nkey_vault_namespace = f\"{key_vault_db}.{key_vault_coll}\"\n\n# Ensure key vault collection exists and has the required index\nclient.get_database(key_vault_db).get_collection(key_vault_coll).create_index(\n    [('keyAltNames', 1)],\n    unique=True,\n    partialFilterExpression={'keyAltNames': {'$exists': True}}\n)\n\n# Initialize ClientEncryption\n# This object implicitly uses the libmongocrypt bindings provided by pymongocrypt.\n# Note: kms_tls_options is required even if empty for local KMS.\nclient_encryption = ClientEncryption(\n    kms_providers=kms_providers,\n    key_vault_namespace=key_vault_namespace,\n    kms_tls_options={},\n    key_vault_client=client\n)\n\n# Create a data key (if one doesn't exist) for encryption\ntry:\n    key_id = client_encryption.get_key_by_alt_name(\"my_data_key\")[\"_id\"]\n    print(f\"Using existing data key ID: {key_id}\")\nexcept Exception: # Key not found, create one\n    key_id = client_encryption.create_data_key(\n        \"local\",\n        key_alt_names=[\"my_data_key\"]\n    )\n    print(f\"Created new data key ID: {key_id}\")\n\n# Encrypt a value\nvalue_to_encrypt = \"My secret data that should be encrypted\"\nencrypted_value = client_encryption.encrypt(\n    value_to_encrypt,\n    key_id=key_id,\n    algorithm=\"AEAD_AES256_CBC_HMAC_SHA521_Deterministic\" # Or Random\n)\nprint(f\"Original value: {value_to_encrypt}\")\nprint(f\"Encrypted value (Binary type): {encrypted_value}\")\n\n# Decrypt the value\ndecrypted_value = client_encryption.decrypt(encrypted_value)\nprint(f\"Decrypted value: {decrypted_value}\")\n\n# Clean up\nclient.drop_database(key_vault_db)\nclient.close()\n","lang":"python","description":"This quickstart demonstrates how to set up a `ClientEncryption` object using a local master key, create a data encryption key, and then encrypt and decrypt a string. This high-level API from `pymongo.encryption` utilizes `pymongocrypt` transparently for the underlying cryptographic operations."},"warnings":[{"fix":"Upgrade your Python environment to Python 3.9 or newer. PyMongoCrypt requires Python >=3.9.","message":"Python 3.8 support was dropped. Users on Python 3.8 or older must upgrade their Python version to use pymongocrypt 1.15.0 and newer.","severity":"breaking","affected_versions":">=1.15.0"},{"fix":"Ensure that your text encryption options include the `contention` field, if applicable to your algorithm choice, to avoid validation errors.","message":"When using Queryable Encryption text search options, the `contention` field is now required for certain algorithms. Previously, it might have been optional.","severity":"breaking","affected_versions":">=1.15.1"},{"fix":"Whenever possible, use the stable `pymongo.encryption` API. If `_lib` is necessary, thoroughly test your code after any `pymongocrypt` upgrade.","message":"Direct use of `pymongocrypt._lib` (the low-level FFI bindings) is for advanced use cases and its API may change between minor versions without explicit warnings, as it's considered an internal implementation detail.","severity":"gotcha","affected_versions":"all"},{"fix":"For most users, installing `pymongocrypt` via `pip` (which installs pre-built wheels) is recommended to ensure correct `libmongocrypt` bundling. If building or linking manually, refer to the official documentation for compatibility matrix.","message":"If you are building `pymongocrypt` from source or providing your own `libmongocrypt` binary via the `lib_path` option in `AutoEncryptionOpts`, ensure compatibility with the `pymongocrypt` Python version. Wheels bundle a compatible `libmongocrypt`.","severity":"gotcha","affected_versions":"all"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}