Python library to interact with keepass databases (supports KDBX3 and KDBX4)
Project description
This library allows you to write entries to a KeePass database.
Come chat at #pykeepass on Freenode or #pykeepass:matrix.org on Matrix.
Example
from pykeepass import PyKeePass
# load database
>>> kp = PyKeePass('db.kdbx', password='somePassw0rd')
# 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
>>> entry.password
's3cure_p455w0rd'
# 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()
# opening in a context
>>> with PyKeePass('db.kdbx', password='somePassw0rd') as kp:
>>> entry = kp.find_entries(title='facebook', first=True)
>>> entry.password
's3cure_p455w0rd'
Finding Entries
find_entries (title=None, username=None, password=None, url=None, notes=None, path=None, uuid=None, string=none, group=None, recursive=True, regex=False, flags=None, history=False, first=False)
Returns entries which match all provided parameters, where title, username, password, url, notes, path, uuid and autotype_sequence are strings, string is a dict, autotype_enabled is a boolean. This function has optional regex boolean and flags string arguments, which means to interpret search strings as XSLT style regular expressions with flags.
The path string can be a direct path to an entry, or (when ending in /) the path to the group to recursively search under.
The string dict allows for searching custom string fields. ex. {'custom_field1': 'custom value', 'custom_field2': 'custom value'}
The group argument determines what Group to search under, and the recursive boolean controls whether to search recursively.
The history (default False) boolean controls whether history entries should be included in the search results.
The first (default False) boolean controls whether to return the first matched item, or a list of matched items.
if first=False, the function returns a list of Entry s or [] if there are no matches
if first=True, the function returns the first Entry match, or None if there are no matches
entries
a flattened list of all entries in the database
>>> kp.entries
[Entry: "foo_entry (myusername)", Entry: "foobar_entry (myusername)", Entry: "social/gmail (myusername)", Entry: "social/facebook (myusername)"]
>>> kp.find_entries(title='gmail', first=True)
Entry: "social/gmail (myusername)"
>>> kp.find_entries(title='foo.*', regex=True)
[Entry: "foo_entry (myusername)", Entry: "foobar_entry (myusername)"]
>>> entry = kp.find_entries(title='foo.*', url='.*facebook.*', regex=True, first=True)
>>> entry.url
'facebook.com'
>>> entry.title
'foo_entry'
>>> group = kp.find_group(name='social', first=True)
>>> kp.find_entries(title='facebook', group=group, recursive=False, first=True)
Entry: "social/facebook (myusername)"
Finding Groups
find_groups (name=None, path=None, uuid=None, notes=None, group=None, recursive=True, regex=False, flags=None, first=False)
where name, path, uuid and notes are strings. This function has optional regex boolean and flags string arguments, which means to interpret search strings as XSLT style regular expressions with flags.
The path string must end in /.
The group argument determines what Group to search under, and the recursive boolean controls whether to search recursively.
The first (default False) boolean controls whether to return the first matched item, or a list of matched items.
if first=False, the function returns a list of Group s or [] if there are no matches
if first=True, the function returns the first Group match, or None if there are no matches
root_group
the Root group to the database
groups
a flattened list of all groups in the database
>>> 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: "/"
Adding Entries
add_entry (destination_group, title, username, password, url=None, notes=None, tags=None, expiry_time=None, icon=None, force_creation=False)
delete_entry (entry)
move_entry (entry, destination_group)
where destination_group is a Group instance. entry is an Entry instance. title, username, password, url, notes, tags, icon are strings. expiry_time is a datetime instance.
If expiry_time is a naive datetime object (i.e. expiry_time.tzinfo is not set), the timezone is retrieved from dateutil.tz.gettz().
# 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 = 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()
Adding Groups
add_group (destination_group, group_name, icon=None, notes=None)
delete_group (group)
move_group (group, destination_group)
destination_group and group are instances of Group. group_name is a string
# 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()
Attachments
add_binary (data, compressed=True, protected=True)
where data is bytes. Adds a blob of data to the database. The attachment reference must still be added to an entry (see below). compressed only applies to KDBX3 and protected only applies to KDBX4. Returns id of attachment.
delete_binary (id)
where id is an int. Removes attachment data from the database and deletes any references to it within entries. Note that since attachments are ID’ed by their index, reference ids greater than id will be automatically decremented.
find_attachments (id=None, filename=None, element=None, recursive=True, regex=False, flags=None, history=False, first=False)
where id is an int, filename is a string, and element is an Entry or Group to search under.
if first=False, the function returns a list of Attachment s or [] if there are no matches
if first=True, the function returns the first Attachment match, or None if there are no matches
binaries
list of bytes containing attachment data. List index corresponds to attachment id.
attachments
list containing all Attachment s in the database.
Entry.add_attachment (id, filename)
where id is an int and filename is a string. Creates a reference using the given filename to a database attachment. The existence of an attachment with the given id is not checked. Returns Attachment.
Entry.delete_attachment (attachment)
where attachment is an Attachment. Deletes a reference to a database attachment.
Entry.attachments
list of Attachment s for this Entry.
Attachment.id
id of data that this attachment points to
Attachment.filename
string representing this attachment
Attachment.data
the data that this attachment points to. Raises AttachmentError if data does not exist.
>>> e = kp.add_entry(kp.root_group, title='foo', username='', password='')
# add attachment data to the db
>>> attachment_id = kp.add_binary(b'Hello world')
>>> kp.attachments
[b'Hello world']
# add attachment reference to entry
>>> a = e.add_attachment(attachment_id, 'hello.txt')
>>> a
Attachment: 'hello.txt' -> 0
# access attachments
>>> a.id
0
>>> a.filename
'hello.txt'
>>> a.data
b'Hello world'
>>> e.attachments
[Attachment: 'hello.txt' -> 0]
# search attachments
>>> kp.find_attachments(filename='he.*', regex=True)
[Attachment: 'hello.txt' -> 0]
# delete attachment reference
>>> e.delete_attachment(a)
# or, delete both attachment reference and binary
>>> kp.delete_binary(attachment_id)
Miscellaneous
read (filename, password=None, keyfile=None, transformed_key=None)
where filename, password, and keyfile are strings. filename is the path to the database, password is the master password string, and keyfile is the path to the database keyfile. At least one of password and keyfile is required. Alternatively, the derived key can be supplied directly through transformed_key.
save (filename=None)
where filename is the path of the file to save to. If filename is not given, the path given in read will be used.
password
string containing database password. Can also be set. Use None for no password.
keyfile
string containing path to the database keyfile. Can also be set. Use None for no keyfile.
version
tuple containing database version. e.g. (3, 1) is a KDBX version 3.1 database.
encryption_algorithm
string containing algorithm used to encrypt database. Possible values are aes256, chacha20, and twofish.
Tests
To run them issue python tests/tests.py
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.