# pykeepass
<a href="https://github.com/libkeepass/pykeepass/actions/workflows/ci.yaml"><img src="https://github.com/libkeepass/pykeepass/actions/workflows/ci.yaml/badge.svg"/></a>
<a href="https://libkeepass.github.io/pykeepass"><img src="https://readthedocs.org/projects/pykeepass/badge/?version=latest"/></a>
<a href="https://matrix.to/#/%23pykeepass:matrix.org"><img src="https://img.shields.io/badge/chat-%23pykeepass-green"/></a>
This library allows you to write entries to a KeePass database.
Come chat at [#pykeepass:matrix.org](https://matrix.to/#/%23pykeepass:matrix.org) on Matrix.
# Installation
``` bash
sudo apt install python3-lxml
pip install pykeepass
```
# Quickstart
General database manipulation
``` python
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
``` python
# 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
``` python
>>> 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
``` python
>>> 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
``` python
# 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:
``` python
>>> 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)"
```
Raw data
{
"_id": null,
"home_page": null,
"name": "pykeepass",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.7",
"maintainer_email": null,
"keywords": "vault, keepass",
"author": null,
"author_email": "Philipp Schmitt <philipp@schmitt.co>, Evan Widloski <evan_gh@widloski.com>",
"download_url": "https://files.pythonhosted.org/packages/29/1d/0e909a73eb95cc21b2048685f59d028d2bbac7b3365a2ac2cca6aad53de9/pykeepass-4.1.1.post1.tar.gz",
"platform": null,
"description": "# pykeepass\n\n<a href=\"https://github.com/libkeepass/pykeepass/actions/workflows/ci.yaml\"><img src=\"https://github.com/libkeepass/pykeepass/actions/workflows/ci.yaml/badge.svg\"/></a>\n<a href=\"https://libkeepass.github.io/pykeepass\"><img src=\"https://readthedocs.org/projects/pykeepass/badge/?version=latest\"/></a>\n<a href=\"https://matrix.to/#/%23pykeepass:matrix.org\"><img src=\"https://img.shields.io/badge/chat-%23pykeepass-green\"/></a>\n \nThis library allows you to write entries to a KeePass database.\n\nCome chat at [#pykeepass:matrix.org](https://matrix.to/#/%23pykeepass:matrix.org) on Matrix.\n\n# Installation\n\n``` bash\nsudo apt install python3-lxml\npip install pykeepass\n```\n\n# Quickstart\n\nGeneral database manipulation\n\n``` python\nfrom pykeepass import PyKeePass\n\n# load database\n>>> kp = PyKeePass('db.kdbx', password='somePassw0rd')\n\n# get all entries\n>>> kp.entries\n[Entry: \"foo_entry (myusername)\", Entry: \"foobar_entry (myusername)\", ...]\n\n# find any group by its name\n>>> group = kp.find_groups(name='social', first=True)\n\n# get the entries in a group\n>>> group.entries\n[Entry: \"social/facebook (myusername)\", Entry: \"social/twitter (myusername)\"]\n\n# find any entry by its title\n>>> entry = kp.find_entries(title='facebook', first=True)\n\n# retrieve the associated password and OTP information\n>>> entry.password\n's3cure_p455w0rd'\n>>> entry.otp\notpauth://totp/test:lkj?secret=TEST%3D%3D%3D%3D&period=30&digits=6&issuer=test\n\n# update an entry\n>>> entry.notes = 'primary facebook account'\n\n# create a new group\n>>> group = kp.add_group(kp.root_group, 'email')\n\n# create a new entry\n>>> kp.add_entry(group, 'gmail', 'myusername', 'myPassw0rdXX')\nEntry: \"email/gmail (myusername)\"\n\n# save database\n>>> kp.save()\n```\n\nFinding and manipulating entries\n\n``` python\n# add a new entry to the Root group\n>>> kp.add_entry(kp.root_group, 'testing', 'foo_user', 'passw0rd')\nEntry: \"testing (foo_user)\"\n\n# add a new entry to the social group\n>>> group = kp.find_groups(name='social', first=True)\n>>> entry = kp.add_entry(group, 'testing', 'foo_user', 'passw0rd')\nEntry: \"testing (foo_user)\"\n\n# save the database\n>>> kp.save()\n\n# delete an entry\n>>> kp.delete_entry(entry)\n\n# move an entry\n>>> kp.move_entry(entry, kp.root_group)\n\n# save the database\n>>> kp.save()\n\n# change creation time\n>>> from datetime import datetime, timezone\n>>> entry.ctime = datetime(2023, 1, 1, tzinfo=timezone.utc)\n\n# update modification or access time\n>>> entry.touch(modify=True)\n\n# save entry history\n>>> entry.save_history()\n```\n\nFinding and manipulating groups\n\n``` python\n>>> kp.groups\n[Group: \"foo\", Group \"foobar\", Group: \"social\", Group: \"social/foo_subgroup\"]\n\n>>> kp.find_groups(name='foo', first=True)\nGroup: \"foo\"\n\n>>> kp.find_groups(name='foo.*', regex=True)\n[Group: \"foo\", Group \"foobar\"]\n\n>>> kp.find_groups(path=['social'], regex=True)\n[Group: \"social\", Group: \"social/foo_subgroup\"]\n\n>>> kp.find_groups(name='social', first=True).subgroups\n[Group: \"social/foo_subgroup\"]\n\n>>> kp.root_group\nGroup: \"/\"\n\n# add a new group to the Root group\n>>> group = kp.add_group(kp.root_group, 'social')\n\n# add a new group to the social group\n>>> group2 = kp.add_group(group, 'gmail')\nGroup: \"social/gmail\"\n\n# save the database\n>>> kp.save()\n\n# delete a group\n>>> kp.delete_group(group)\n\n# move a group\n>>> kp.move_group(group2, kp.root_group)\n\n# save the database\n>>> kp.save()\n\n# change creation time\n>>> from datetime import datetime, timezone\n>>> group.ctime = datetime(2023, 1, 1, tzinfo=timezone.utc)\n\n# update modification or access time\n>>> group.touch(modify=True)\n```\n\nAttachments\n\n``` python\n>>> e = kp.add_entry(kp.root_group, title='foo', username='', password='')\n\n# add attachment data to the db\n>>> binary_id = kp.add_binary(b'Hello world')\n\n>>> kp.binaries\n[b'Hello world']\n\n# add attachment reference to entry\n>>> a = e.add_attachment(binary_id, 'hello.txt')\n>>> a\nAttachment: 'hello.txt' -> 0\n\n# access attachments\n>>> a\nAttachment: 'hello.txt' -> 0\n>>> a.id\n0\n>>> a.filename\n'hello.txt'\n>>> a.data\nb'Hello world'\n>>> e.attachments\n[Attachment: 'hello.txt' -> 0]\n\n# list all attachments in the database\n>>> kp.attachments\n[Attachment: 'hello.txt' -> 0]\n\n# search attachments\n>>> kp.find_attachments(filename='hello.txt')\n[Attachment: 'hello.txt** -> 0]\n\n# delete attachment reference\n>>> e.delete_attachment(a)\n\n# or, delete both attachment reference and binary\n>>> kp.delete_binary(binary_id**\n```\n\nOTP codes\n\n``` python\n# find an entry which has otp attribute\n>>> e = kp.find_entries(otp='.*', regex=True, first=True)\n>>> import pyotp\n>>> pyotp.parse_uri(e.otp).now()\n799270\n```\n\n\n# Tests and Debugging\n\nRun tests with `python tests/tests.py` or `python tests/tests.py SomeSpecificTest`\n\nEnable debugging when doing tests in console:\n\n``` python\n>>> from pykeepass.pykeepass import debug_setup\n>>> debug_setup()\n>>> kp.entries[0]\nDEBUG:pykeepass.pykeepass:xpath query: //Entry\nDEBUG:pykeepass.pykeepass:xpath query: (ancestor::Group)[last()]\nDEBUG:pykeepass.pykeepass:xpath query: (ancestor::Group)[last()]\nDEBUG:pykeepass.pykeepass:xpath query: String/Key[text()=\"Title\"]/../Value\nDEBUG:pykeepass.pykeepass:xpath query: String/Key[text()=\"UserName\"]/../Value\nEntry: \"root_entry (foobar_user)\"\n```\n\n",
"bugtrack_url": null,
"license": "GPL-3.0",
"summary": "Python library to interact with keepass databases (supports KDBX3 and KDBX4)",
"version": "4.1.1.post1",
"project_urls": {
"Changelog": "https://github.com/libkeepass/pykeepass/blob/master/CHANGELOG.rst",
"Homepage": "https://github.com/libkeepass/pykeepass",
"Issues": "https://github.com/libkeepass/pykeepass/issues",
"Repository": "https://github.com/libkeepass/pykeepass"
},
"split_keywords": [
"vault",
" keepass"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "ac046cf0687780c68e7fb0525e7210ec5477987c0481904f600c2e5d81bbb7dd",
"md5": "678431debfd017ea33968b50a96a89ed",
"sha256": "4cfd54f376cb1f58dd8f11fbe7923282bc7dd97ffdf1bb622004a6e718bfe379"
},
"downloads": -1,
"filename": "pykeepass-4.1.1.post1-py3-none-any.whl",
"has_sig": false,
"md5_digest": "678431debfd017ea33968b50a96a89ed",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.7",
"size": 55584,
"upload_time": "2025-03-06T00:41:57",
"upload_time_iso_8601": "2025-03-06T00:41:57.201515Z",
"url": "https://files.pythonhosted.org/packages/ac/04/6cf0687780c68e7fb0525e7210ec5477987c0481904f600c2e5d81bbb7dd/pykeepass-4.1.1.post1-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "291d0e909a73eb95cc21b2048685f59d028d2bbac7b3365a2ac2cca6aad53de9",
"md5": "2e9262d91f4ff96159d71be387b35b3a",
"sha256": "28f4927454ebe507ef7294d3ec6b5a72ee3a5c97fcc21b1080b8ddc09f2097dd"
},
"downloads": -1,
"filename": "pykeepass-4.1.1.post1.tar.gz",
"has_sig": false,
"md5_digest": "2e9262d91f4ff96159d71be387b35b3a",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.7",
"size": 55429,
"upload_time": "2025-03-06T00:41:58",
"upload_time_iso_8601": "2025-03-06T00:41:58.887904Z",
"url": "https://files.pythonhosted.org/packages/29/1d/0e909a73eb95cc21b2048685f59d028d2bbac7b3365a2ac2cca6aad53de9/pykeepass-4.1.1.post1.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-03-06 00:41:58",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "libkeepass",
"github_project": "pykeepass",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [
{
"name": "argon2-cffi",
"specs": [
[
"==",
"23.1.0"
]
]
},
{
"name": "argon2-cffi-bindings",
"specs": [
[
"==",
"21.2.0"
]
]
},
{
"name": "cffi",
"specs": [
[
"==",
"1.17.1"
]
]
},
{
"name": "construct",
"specs": [
[
"==",
"2.10.70"
]
]
},
{
"name": "Jinja2",
"specs": [
[
"==",
"3.1.5"
]
]
},
{
"name": "lxml",
"specs": [
[
"==",
"5.3.1"
]
]
},
{
"name": "MarkupSafe",
"specs": [
[
"==",
"3.0.2"
]
]
},
{
"name": "pdoc",
"specs": [
[
"==",
"15.0.1"
]
]
},
{
"name": "pycparser",
"specs": [
[
"==",
"2.22"
]
]
},
{
"name": "pycryptodomex",
"specs": [
[
"==",
"3.21.0"
]
]
},
{
"name": "Pygments",
"specs": [
[
"==",
"2.19.1"
]
]
},
{
"name": "pykeepass",
"specs": []
},
{
"name": "pyotp",
"specs": [
[
"==",
"2.9.0"
]
]
}
],
"lcname": "pykeepass"
}