pykeepass is a free, open source identity & access management (iam) project written in Python and released under GPL-3.0. It has 511 GitHub stars, 103 forks and 42 open issues, and was last pushed 2 months ago. On this registry it ranks #58 of 58 tracked projects in Identity & Access Management (IAM), with 5 head-to-head comparisons available.

What is pykeepass?

pykeepass is a Python library for reading, writing and automating KeePass .kdbx password databases (KDBX3 and KDBX4) for developers and self-hosters who want programmatic access to their credentials.

What it is

pykeepass is a Python library, published on PyPI as pykeepass, that opens and manipulates KeePass password databases directly from code. It lives in the Python ecosystem alongside tools such as pyotp and depends on python3-lxml; it is released under the GPL-3.0 licence. Rather than driving a graphical client, it exposes a PyKeePass object whose groups, entries, binaries and attachments can be searched, created, edited and saved.

The concrete problem it solves is that KeePass databases are normally edited only through a desktop GUI, which makes bulk or scripted credential management impossible. pykeepass replaces manual GUI editing by giving you programmatic equivalents of every routine operation: finding entries by title or group path, updating passwords and notes, reorganising the group tree, and persisting changes with a single kp.save() call. It supports both the KDBX3 and KDBX4 database formats, so existing databases can be opened without conversion.

Key capabilities

  • Open a database with PyKeePass('db.kdbx', password=...) and enumerate kp.entries, kp.groups, kp.root_group, kp.binaries and kp.attachments.
  • Search entries and groups with find_entries and find_groups, supporting exact names, regex=True matching and path=['social'] lookups that return subgroups.
  • Create, delete and reorganise content with add_entry, add_group, delete_entry, delete_group, move_entry and move_group, then commit changes via kp.save().
  • Read and set per-entry metadata, including entry.password, entry.notes, entry.ctime with timezone-aware datetime values, and entry.touch(modify=True) to update access times.
  • Manage OTP credentials: retrieve entry.otp as an otpauth://totp/... URI and combine the library with pyotp.parse_uri(...).now() to generate codes.
  • Attach files to entries with kp.add_binary(b'Hello world') and e.add_attachment(binary_id, 'hello.txt'), then search, read or delete them through find_attachments, delete_attachment and delete_binary.
  • Preserve entry revisions using entry.save_history(), and run the test suite with python tests/tests.py (optionally naming a specific test).

Who uses it and how

  • Developers embedding credential lookup into scripts, fetching a stored password or OTP secret for a specific service with a single find_entries(title=..., first=True) call.
  • Automation tasks that populate or prune databases in bulk, adding groups such as email under the root group and writing many entries before one kp.save().
  • Teams restructuring existing databases, moving entries between groups with move_entry and reorganising subgroups such as social/gmail without opening a GUI.
  • Users who need file attachments stored inside the database, uploading binary blobs and referencing them from entries as named files like hello.txt.
  • Contributors working on the project through its Hacktoberfest topic and its Matrix channel at #pykeepass:matrix.org.

Getting started

Install it from PyPI with pip install pykeepass (the README also calls for sudo apt install python3-lxml), then load a database in Python with from pykeepass import PyKeePass.

How it compares

pykeepass stands alone in this registry as a library rather than a password manager application: it does not provide a user interface, sync service or browser integration of its own, but instead operates on .kdbx files that other KeePass clients create and read. Its scope is deliberately limited to database manipulation from Python.

When to use it — and when not

You should pick it when you already keep credentials in a KeePass database and want to automate access to them from Python, and skip it if you want a complete password manager with clients, sharing and syncing, since pykeepass only reads and writes the file and assumes you handle storage yourself. Note the project carries 42 open issues, so complex or edge-case databases may hit unresolved behaviour; its licence is GPL-3.0, which matters if you intend to distribute software built on it.

project readme (upstream, from github) — read inline

pykeepass

This library allows you to write entries to a KeePass database.

Come chat at #pykeepass:matrix.org on Matrix.

Installation

sudo apt install python3-lxml
pip install pykeepass

Quickstart

General database manipulation

from pykeepass import PyKeePass

# load database
>>> kp = PyKeePass('db.kdbx', password='somePassw0rd')

# get all entries
>>> kp.entries
[Entry: "foo_entry (myusername)", Entry: "foobar_entry (myusername)", ...]

# find any group by its name
>>> group = kp.find_groups(name='social', first=True)

# get the entries in a group
>>> group.entries
[Entry: "social/facebook (myusername)", Entry: "social/twitter (myusername)"]

# find any entry by its title
>>> entry = kp.find_entries(title='facebook', first=True)

# retrieve the associated password and OTP information
>>> entry.password
's3cure_p455w0rd'
>>> entry.otp
otpauth://totp/test:lkj?secret=TEST%3D%3D%3D%3D&period=30&digits=6&issuer=test

# update an entry
>>> entry.notes = 'primary facebook account'

# create a new group
>>> group = kp.add_group(kp.root_group, 'email')

# create a new entry
>>> kp.add_entry(group, 'gmail', 'myusername', 'myPassw0rdXX')
Entry: "email/gmail (myusername)"

# save database
>>> kp.save()

Finding and manipulating entries

# add a new entry to the Root group
>>> kp.add_entry(kp.root_group, 'testing', 'foo_user', 'passw0rd')
Entry: "testing (foo_user)"

# add a new entry to the social group
>>> group = kp.find_groups(name='social', first=True)
>>> entry = kp.add_entry(group, 'testing', 'foo_user', 'passw0rd')
Entry: "testing (foo_user)"

# save the database
>>> kp.save()

# delete an entry
>>> kp.delete_entry(entry)

# move an entry
>>> kp.move_entry(entry, kp.root_group)

# save the database
>>> kp.save()

# change creation time
>>> from datetime import datetime, timezone
>>> entry.ctime = datetime(2023, 1, 1, tzinfo=timezone.utc)

# update modification or access time
>>> entry.touch(modify=True)

# save entry history
>>> entry.save_history()

Finding and manipulating groups

>>> kp.groups
[Group: "foo", Group "foobar", Group: "social", Group: "social/foo_subgroup"]

>>> kp.find_groups(name='foo', first=True)
Group: "foo"

>>> kp.find_groups(name='foo.*', regex=True)
[Group: "foo", Group "foobar"]

>>> kp.find_groups(path=['social'], regex=True)
[Group: "social", Group: "social/foo_subgroup"]

>>> kp.find_groups(name='social', first=True).subgroups
[Group: "social/foo_subgroup"]

>>> kp.root_group
Group: "/"

# add a new group to the Root group
>>> group = kp.add_group(kp.root_group, 'social')

# add a new group to the social group
>>> group2 = kp.add_group(group, 'gmail')
Group: "social/gmail"

# save the database
>>> kp.save()

# delete a group
>>> kp.delete_group(group)

# move a group
>>> kp.move_group(group2, kp.root_group)

# save the database
>>> kp.save()

# change creation time
>>> from datetime import datetime, timezone
>>> group.ctime = datetime(2023, 1, 1, tzinfo=timezone.utc)

# update modification or access time
>>> group.touch(modify=True)

Attachments

>>> e = kp.add_entry(kp.root_group, title='foo', username='', password='')

# add attachment data to the db
>>> binary_id = kp.add_binary(b'Hello world')

>>> kp.binaries
[b'Hello world']

# add attachment reference to entry
>>> a = e.add_attachment(binary_id, 'hello.txt')
>>> a
Attachment: 'hello.txt' -> 0

# access attachments
>>> a
Attachment: 'hello.txt' -> 0
>>> a.id
0
>>> a.filename
'hello.txt'
>>> a.data
b'Hello world'
>>> e.attachments
[Attachment: 'hello.txt' -> 0]

# list all attachments in the database
>>> kp.attachments
[Attachment: 'hello.txt' -> 0]

# search attachments
>>> kp.find_attachments(filename='hello.txt')
[Attachment: 'hello.txt** -> 0]

# delete attachment reference
>>> e.delete_attachment(a)

# or, delete both attachment reference and binary
>>> kp.delete_binary(binary_id**

OTP codes

# find an entry which has otp attribute
>>> e = kp.find_entries(otp='.*', regex=True, first=True)
>>> import pyotp
>>> pyotp.parse_uri(e.otp).now()
799270

Tests and Debugging

Run tests with python tests/tests.py or python tests/tests.py SomeSpecificTest

Enable debugging when doing tests in console:

>>> from pykeepass.pykeepass import debug_setup
>>> debug_setup()
>>> kp.entries[0]
DEBUG:pykeepass.pykeepass:xpath query: //Entry
DEBUG:pykeepass.pykeepass:xpath query: (ancestor::Group)[last()]
DEBUG:pykeepass.pykeepass:xpath query: (ancestor::Group)[last()]
DEBUG:pykeepass.pykeepass:xpath query: String/Key[text()="Title"]/../Value
DEBUG:pykeepass.pykeepass:xpath query: String/Key[text()="UserName"]/../Value
Entry: "root_entry (foobar_user)"

Frequently asked questions

Is pykeepass free to use?

pykeepass is open source under the GPL-3.0 licence. There is no licence fee and no seat count — you can self-host it or, where the project offers one, pay a vendor for a managed version instead.

What does pykeepass do?

Python library to interact with keepass databases (supports KDBX3 and KDBX4)

What is pykeepass written in?

pykeepass is primarily written in Python. Its source is publicly available at https://github.com/libkeepass/pykeepass, and it has 511 GitHub stars.