Name | pykeepass JSON |
Version |
4.0.7
JSON |
| download |
home_page | |
Summary | Python library to interact with keepass databases (supports KDBX3 and KDBX4) |
upload_time | 2024-02-29 07:24:11 |
maintainer | |
docs_url | None |
author | |
requires_python | |
license | GPL-3.0 |
keywords |
vault
keepass
|
VCS |
|
bugtrack_url |
|
requirements |
No requirements were recorded.
|
Travis-CI |
No Travis.
|
coveralls test coverage |
No coveralls.
|
pykeepass
============
.. image:: https://github.com/libkeepass/pykeepass/workflows/CI/badge.svg
:target: https://github.com/libkeepass/pykeepass/actions?query=workflow%3ACI
.. image:: https://readthedocs.org/projects/pykeepass/badge/?version=latest
:target: https://pykeepass.readthedocs.io/en/latest/?badge=latest
:alt: Documentation Status
.. image:: https://img.shields.io/matrix/pykeepass:matrix.org.svg
:target: https://matrix.to/#/#pykeepass:matrix.org
.. image:: https://img.shields.io/badge/irc-%23pykeepass-brightgreen
:target: https://webchat.freenode.net/?channels=pykeepass
This library allows you to write entries to a KeePass database.
Come chat at `#pykeepass`_ on Freenode or `#pykeepass:matrix.org`_ on Matrix.
.. _#pykeepass: irc://irc.freenode.net
.. _#pykeepass\:matrix.org: https://matrix.to/#/%23pykeepass:matrix.org
Installation
------------
.. code::
sudo apt install python3-lxml
pip install pykeepass
Example
-------
.. code:: python
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()
..
TODO: add `Entry` and `Group` sections to document attributes of each
Finding Entries
---------------
**find_entries** (title=None, username=None, password=None, url=None, notes=None, otp=None, path=None, uuid=None, tags=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``, ``otp``, ``autotype_window`` and ``autotype_sequence`` are strings, ``path`` is a list, ``string`` is a dict, ``autotype_enabled`` is a boolean, ``uuid`` is a ``uuid.UUID`` and ``tags`` is a list of strings. This function has optional ``regex`` boolean and ``flags`` string arguments, which means to interpret search strings as `XSLT style`_ regular expressions with `flags`_.
.. _XSLT style: https://www.xml.com/pub/a/2003/06/04/tr.html
.. _flags: https://www.w3.org/TR/xpath-functions/#flags
The ``path`` list is a full path to an entry (ex. ``['foobar_group', 'foobar_entry']``). This implies ``first=True``. All other arguments are ignored when this is given. This is useful for handling user input.
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
.. code:: python
>>> 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'
>>> entry.title = 'hello'
>>> group = kp.find_group(name='social', first=True)
>>> kp.find_entries(title='facebook', group=group, recursive=False, first=True)
Entry: "social/facebook (myusername)"
>>> entry.otp
otpauth://totp/test:lkj?secret=TEST%3D%3D%3D%3D&period=30&digits=6&issuer=test
Finding Groups
--------------
**find_groups** (name=None, path=None, uuid=None, notes=None, group=None, recursive=True, regex=False, flags=None, first=False)
where ``name`` and ``notes`` are strings, ``path`` is a list, ``uuid`` is a ``uuid.UUID``. This function has optional ``regex`` boolean and ``flags`` string arguments, which means to interpret search strings as `XSLT style`_ regular expressions with `flags`_.
.. _XSLT style: https://www.xml.com/pub/a/2003/06/04/tr.html
.. _flags: https://www.w3.org/TR/xpath-functions/#flags
The ``path`` list is a full path to a group (ex. ``['foobar_group', 'sub_group']``). This implies ``first=True``. All other arguments are ignored when this is given. This is useful for handling user input.
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
.. code:: 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: "/"
Entry Functions and Properties
------------------------------
**add_entry** (destination_group, title, username, password, url=None, notes=None, tags=None, expiry_time=None, icon=None, force_creation=False)
**delete_entry** (entry)
**trash_entry** (entry)
move a group to the recycle bin. The recycle bin is created if it does not exit. ``entry`` must be an empty Entry.
**move_entry** (entry, destination_group)
**atime**
access time
**ctime**
creation time
**mtime**
modification time
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()``.
.. code:: 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)
Group Functions and Properties
------------------------------
**add_group** (destination_group, group_name, icon=None, notes=None)
**delete_group** (group)
**trash_group** (group)
move a group to the recycle bin. The recycle bin is created if it does not exit. ``group`` must be an empty Group.
**empty_group** (group)
delete all entries and subgroups of a group. ``group`` is an instance of ``Group``.
**move_group** (group, destination_group)
**atime**
access time
**ctime**
creation time
**mtime**
modification time
``destination_group`` and ``group`` are instances of ``Group``. ``group_name`` is a string
.. code:: python
# 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
-----------
In this section, *binary* refers to the bytes of the attached data (stored at the root level of the database), while *attachment* is a reference to a binary (stored in an entry). A binary can be referenced by none, one or many 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 (no effect if used on wrong database version). Returns id of attachment.
**delete_binary** (id)
where ``id`` is an int. Removes binary data from the database and deletes any attachments that reference it. Since attachments reference binaries by their positional index, attachments that reference binaries with id > ``id`` will automatically be 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 bytestrings containing binary 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 binary. The existence of a binary with the given id is not checked. Returns ``Attachment``.
**Entry.delete_attachment** (attachment)
where ``attachment`` is an ``Attachment``. Deletes a reference to a database binary.
**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 ``BinaryError`` if data does not exist.
**Attachment.entry**
the entry that this attachment is attached to
.. code:: 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**
Credential Expiry
-----------------
**credchange_date**
datetime object with date of last credentials change
**credchange_required**
boolean whether database credentials have expired and are required to change
**credchange_recommended**
boolean whether database credentials have expired and are recommended to change
**credchange_required_days**
days after **credchange_date** that credential update is required
**credchange_recommended_days**
days after **credchange_date** that credential update is recommended
Miscellaneous
-------------
**read** (filename=None, password=None, keyfile=None, transformed_key=None, decrypt=False)
where ``filename``, ``password``, and ``keyfile`` are strings ( ``filename`` and ``keyfile`` may also be file-like objects). ``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``. ``decrypt`` tells whether the file should be decrypted or not.
Can raise ``CredentialsError``, ``HeaderChecksumError``, or ``PayloadChecksumError``.
**reload** ()
reload database from disk using previous credentials
**save** (filename=None)
where ``filename`` is the path of the file to save to (``filename`` may also be file-like object). 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.
**filename**
string containing path to database. Can also be set
**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``.
**create_database** (filename, password=None, keyfile=None, transformed_key=None)
create a new database at ``filename`` with supplied credentials. Returns ``PyKeePass`` object
**tree**
database lxml tree
**xml**
get database XML data as string
**dump_xml** (filename)
pretty print database XML to file
TOTP
-------
**Entry.otp**
TOTP URI which can be passed to an OTP library to generate codes
.. code:: 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 :code:`python tests/tests.py` or :code:`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)"
Raw data
{
"_id": null,
"home_page": "",
"name": "pykeepass",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "vault,keepass",
"author": "",
"author_email": "Philipp Schmitt <philipp@schmitt.co>, Evan Widloski <evan_gh@widloski.com>",
"download_url": "https://files.pythonhosted.org/packages/e1/ca/2da205bb1baa9f86b9cc36145ab5435fbc50ee3cc136e4a90356dbbdc3d2/pykeepass-4.0.7.tar.gz",
"platform": null,
"description": "pykeepass\n============\n\n.. image:: https://github.com/libkeepass/pykeepass/workflows/CI/badge.svg\n :target: https://github.com/libkeepass/pykeepass/actions?query=workflow%3ACI\n\n.. image:: https://readthedocs.org/projects/pykeepass/badge/?version=latest\n :target: https://pykeepass.readthedocs.io/en/latest/?badge=latest\n :alt: Documentation Status\n\n.. image:: https://img.shields.io/matrix/pykeepass:matrix.org.svg\n :target: https://matrix.to/#/#pykeepass:matrix.org\n\n.. image:: https://img.shields.io/badge/irc-%23pykeepass-brightgreen\n :target: https://webchat.freenode.net/?channels=pykeepass\n \nThis library allows you to write entries to a KeePass database.\n\nCome chat at `#pykeepass`_ on Freenode or `#pykeepass:matrix.org`_ on Matrix.\n\n.. _#pykeepass: irc://irc.freenode.net\n.. _#pykeepass\\:matrix.org: https://matrix.to/#/%23pykeepass:matrix.org\n\nInstallation\n------------\n\n.. code::\n\n sudo apt install python3-lxml\n pip install pykeepass\n\nExample\n-------\n.. code:: python\n\n from pykeepass import PyKeePass\n\n # load database\n >>> kp = PyKeePass('db.kdbx', password='somePassw0rd')\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\n >>> entry.password\n 's3cure_p455w0rd'\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')\n Entry: \"email/gmail (myusername)\"\n\n # save database\n >>> kp.save()\n\n\n..\n TODO: add `Entry` and `Group` sections to document attributes of each\n\nFinding Entries\n---------------\n\n**find_entries** (title=None, username=None, password=None, url=None, notes=None, otp=None, path=None, uuid=None, tags=None, string=None, group=None, recursive=True, regex=False, flags=None, history=False, first=False)\n\nReturns entries which match all provided parameters, where ``title``, ``username``, ``password``, ``url``, ``notes``, ``otp``, ``autotype_window`` and ``autotype_sequence`` are strings, ``path`` is a list, ``string`` is a dict, ``autotype_enabled`` is a boolean, ``uuid`` is a ``uuid.UUID`` and ``tags`` is a list of strings. This function has optional ``regex`` boolean and ``flags`` string arguments, which means to interpret search strings as `XSLT style`_ regular expressions with `flags`_.\n\n.. _XSLT style: https://www.xml.com/pub/a/2003/06/04/tr.html\n.. _flags: https://www.w3.org/TR/xpath-functions/#flags \n\nThe ``path`` list is a full path to an entry (ex. ``['foobar_group', 'foobar_entry']``). This implies ``first=True``. All other arguments are ignored when this is given. This is useful for handling user input.\n\nThe ``string`` dict allows for searching custom string fields. ex. ``{'custom_field1': 'custom value', 'custom_field2': 'custom value'}``\n\nThe ``group`` argument determines what ``Group`` to search under, and the ``recursive`` boolean controls whether to search recursively.\n\nThe ``history`` (default ``False``) boolean controls whether history entries should be included in the search results.\n\nThe ``first`` (default ``False``) boolean controls whether to return the first matched item, or a list of matched items.\n\n* if ``first=False``, the function returns a list of ``Entry`` s or ``[]`` if there are no matches\n* if ``first=True``, the function returns the first ``Entry`` match, or ``None`` if there are no matches\n\n**entries**\n\na flattened list of all entries in the database\n\n.. code:: python\n\n >>> kp.entries\n [Entry: \"foo_entry (myusername)\", Entry: \"foobar_entry (myusername)\", Entry: \"social/gmail (myusername)\", Entry: \"social/facebook (myusername)\"]\n\n >>> kp.find_entries(title='gmail', first=True)\n Entry: \"social/gmail (myusername)\"\n\n >>> kp.find_entries(title='foo.*', regex=True)\n [Entry: \"foo_entry (myusername)\", Entry: \"foobar_entry (myusername)\"]\n\n >>> entry = kp.find_entries(title='foo.*', url='.*facebook.*', regex=True, first=True)\n >>> entry.url\n 'facebook.com'\n >>> entry.title\n 'foo_entry'\n >>> entry.title = 'hello'\n\n >>> group = kp.find_group(name='social', first=True)\n >>> kp.find_entries(title='facebook', group=group, recursive=False, first=True)\n Entry: \"social/facebook (myusername)\"\n\n >>> entry.otp\n otpauth://totp/test:lkj?secret=TEST%3D%3D%3D%3D&period=30&digits=6&issuer=test\n\n\n\nFinding Groups\n--------------\n\n**find_groups** (name=None, path=None, uuid=None, notes=None, group=None, recursive=True, regex=False, flags=None, first=False)\n\nwhere ``name`` and ``notes`` are strings, ``path`` is a list, ``uuid`` is a ``uuid.UUID``. This function has optional ``regex`` boolean and ``flags`` string arguments, which means to interpret search strings as `XSLT style`_ regular expressions with `flags`_.\n\n.. _XSLT style: https://www.xml.com/pub/a/2003/06/04/tr.html\n.. _flags: https://www.w3.org/TR/xpath-functions/#flags \n\nThe ``path`` list is a full path to a group (ex. ``['foobar_group', 'sub_group']``). This implies ``first=True``. All other arguments are ignored when this is given. This is useful for handling user input.\n\nThe ``group`` argument determines what ``Group`` to search under, and the ``recursive`` boolean controls whether to search recursively.\n\nThe ``first`` (default ``False``) boolean controls whether to return the first matched item, or a list of matched items.\n\n* if ``first=False``, the function returns a list of ``Group`` s or ``[]`` if there are no matches\n* if ``first=True``, the function returns the first ``Group`` match, or ``None`` if there are no matches\n\n**root_group**\n\nthe ``Root`` group to the database\n\n**groups**\n\na flattened list of all groups in the database\n\n.. code:: python\n\n >>> kp.groups\n [Group: \"foo\", Group \"foobar\", Group: \"social\", Group: \"social/foo_subgroup\"]\n\n >>> kp.find_groups(name='foo', first=True)\n Group: \"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\n Group: \"/\"\n\n\nEntry Functions and Properties\n------------------------------\n**add_entry** (destination_group, title, username, password, url=None, notes=None, tags=None, expiry_time=None, icon=None, force_creation=False)\n\n**delete_entry** (entry)\n\n**trash_entry** (entry)\n\nmove a group to the recycle bin. The recycle bin is created if it does not exit. ``entry`` must be an empty Entry.\n\n**move_entry** (entry, destination_group)\n\n**atime**\n\naccess time\n\n**ctime**\n\ncreation time\n\n**mtime**\n\nmodification time\n\nwhere ``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.\n\nIf ``expiry_time`` is a naive datetime object (i.e. ``expiry_time.tzinfo`` is not set), the timezone is retrieved from ``dateutil.tz.gettz()``.\n\n.. code:: python\n\n # add a new entry to the Root group\n >>> kp.add_entry(kp.root_group, 'testing', 'foo_user', 'passw0rd')\n Entry: \"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')\n Entry: \"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\nGroup Functions and Properties\n------------------------------\n**add_group** (destination_group, group_name, icon=None, notes=None)\n\n**delete_group** (group)\n\n**trash_group** (group)\n\nmove a group to the recycle bin. The recycle bin is created if it does not exit. ``group`` must be an empty Group.\n\n**empty_group** (group)\n\ndelete all entries and subgroups of a group. ``group`` is an instance of ``Group``.\n\n**move_group** (group, destination_group)\n\n**atime**\n\naccess time\n\n**ctime**\n\ncreation time\n\n**mtime**\n\nmodification time\n\n``destination_group`` and ``group`` are instances of ``Group``. ``group_name`` is a string\n\n.. code:: python\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')\n Group: \"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\nAttachments\n-----------\n\nIn this section, *binary* refers to the bytes of the attached data (stored at the root level of the database), while *attachment* is a reference to a binary (stored in an entry). A binary can be referenced by none, one or many attachments.\n\n**add_binary** (data, compressed=True, protected=True)\n\nwhere ``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 (no effect if used on wrong database version). Returns id of attachment.\n\n**delete_binary** (id)\n\nwhere ``id`` is an int. Removes binary data from the database and deletes any attachments that reference it. Since attachments reference binaries by their positional index, attachments that reference binaries with id > ``id`` will automatically be decremented.\n\n**find_attachments** (id=None, filename=None, element=None, recursive=True, regex=False, flags=None, history=False, first=False)\n\nwhere ``id`` is an int, ``filename`` is a string, and element is an ``Entry`` or ``Group`` to search under.\n\n* if ``first=False``, the function returns a list of ``Attachment`` s or ``[]`` if there are no matches\n* if ``first=True``, the function returns the first ``Attachment`` match, or ``None`` if there are no matches\n\n**binaries**\n\nlist of bytestrings containing binary data. List index corresponds to attachment id\n\n**attachments**\n\nlist containing all ``Attachment`` s in the database.\n\n**Entry.add_attachment** (id, filename)\n\nwhere ``id`` is an int and ``filename`` is a string. Creates a reference using the given filename to a database binary. The existence of a binary with the given id is not checked. Returns ``Attachment``.\n\n**Entry.delete_attachment** (attachment)\n\nwhere ``attachment`` is an ``Attachment``. Deletes a reference to a database binary.\n\n**Entry.attachments**\n\nlist of ``Attachment`` s for this Entry.\n\n**Attachment.id**\n\nid of data that this attachment points to\n\n**Attachment.filename**\n\nstring representing this attachment\n\n**Attachment.data**\n\nthe data that this attachment points to. Raises ``BinaryError`` if data does not exist.\n\n**Attachment.entry**\n\nthe entry that this attachment is attached to\n\n.. code:: python\n\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\n Attachment: 'hello.txt' -> 0\n \n # access attachments\n >>> a\n Attachment: 'hello.txt' -> 0\n >>> a.id\n 0\n >>> a.filename\n 'hello.txt'\n >>> a.data\n b'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\nCredential Expiry\n-----------------\n\n**credchange_date**\n\ndatetime object with date of last credentials change\n\n**credchange_required**\n\nboolean whether database credentials have expired and are required to change\n\n**credchange_recommended**\n\nboolean whether database credentials have expired and are recommended to change\n\n**credchange_required_days**\n\ndays after **credchange_date** that credential update is required\n\n**credchange_recommended_days**\n\ndays after **credchange_date** that credential update is recommended\n\n\nMiscellaneous\n-------------\n**read** (filename=None, password=None, keyfile=None, transformed_key=None, decrypt=False)\n\nwhere ``filename``, ``password``, and ``keyfile`` are strings ( ``filename`` and ``keyfile`` may also be file-like objects). ``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``. ``decrypt`` tells whether the file should be decrypted or not.\n\nCan raise ``CredentialsError``, ``HeaderChecksumError``, or ``PayloadChecksumError``.\n\n**reload** ()\n\nreload database from disk using previous credentials\n\n**save** (filename=None)\n\nwhere ``filename`` is the path of the file to save to (``filename`` may also be file-like object). If ``filename`` is not given, the path given in ``read`` will be used.\n\n**password**\n\nstring containing database password. Can also be set. Use ``None`` for no password.\n\n**filename**\n\nstring containing path to database. Can also be set\n\n**keyfile**\n\nstring containing path to the database keyfile. Can also be set. Use ``None`` for no keyfile.\n\n**version**\n\ntuple containing database version. e.g. ``(3, 1)`` is a KDBX version 3.1 database.\n\n**encryption_algorithm**\n\nstring containing algorithm used to encrypt database. Possible values are ``aes256``, ``chacha20``, and ``twofish``.\n\n**create_database** (filename, password=None, keyfile=None, transformed_key=None)\n\ncreate a new database at ``filename`` with supplied credentials. Returns ``PyKeePass`` object\n\n**tree**\n\ndatabase lxml tree\n\n**xml**\n\nget database XML data as string\n\n**dump_xml** (filename)\n\npretty print database XML to file\n\nTOTP\n-------\n\n**Entry.otp**\n\nTOTP URI which can be passed to an OTP library to generate codes\n\n.. code:: python\n\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()\n 799270\n\n\nTests and Debugging\n-------------------\n\nRun tests with :code:`python tests/tests.py` or :code:`python tests/tests.py SomeSpecificTest`\n\nEnable debugging when doing tests in console:\n\n >>> from pykeepass.pykeepass import debug_setup\n >>> debug_setup()\n >>> kp.entries[0]\n DEBUG:pykeepass.pykeepass:xpath query: //Entry\n DEBUG:pykeepass.pykeepass:xpath query: (ancestor::Group)[last()]\n DEBUG:pykeepass.pykeepass:xpath query: (ancestor::Group)[last()]\n DEBUG:pykeepass.pykeepass:xpath query: String/Key[text()=\"Title\"]/../Value\n DEBUG:pykeepass.pykeepass:xpath query: String/Key[text()=\"UserName\"]/../Value\n Entry: \"root_entry (foobar_user)\"\n",
"bugtrack_url": null,
"license": "GPL-3.0",
"summary": "Python library to interact with keepass databases (supports KDBX3 and KDBX4)",
"version": "4.0.7",
"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": "",
"digests": {
"blake2b_256": "9c8279ce8d02d376767c3d2e2f4917af4a115eb28834c3c1ab785ec20fef9497",
"md5": "965e6a5fbe14bfd95e0b008e578f079e",
"sha256": "bea58d99ab08c885caef873a5fb9eaba83525da66eba91c8e51ca63c36e89d42"
},
"downloads": -1,
"filename": "pykeepass-4.0.7-py3-none-any.whl",
"has_sig": false,
"md5_digest": "965e6a5fbe14bfd95e0b008e578f079e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 55164,
"upload_time": "2024-02-29T07:24:08",
"upload_time_iso_8601": "2024-02-29T07:24:08.819416Z",
"url": "https://files.pythonhosted.org/packages/9c/82/79ce8d02d376767c3d2e2f4917af4a115eb28834c3c1ab785ec20fef9497/pykeepass-4.0.7-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e1ca2da205bb1baa9f86b9cc36145ab5435fbc50ee3cc136e4a90356dbbdc3d2",
"md5": "24b0d16eba5fe233de3a26d5d7108d19",
"sha256": "56ce2a1d22c204c838e6501796e0acce8ba9f50ade821111aaa1458f9d1a775e"
},
"downloads": -1,
"filename": "pykeepass-4.0.7.tar.gz",
"has_sig": false,
"md5_digest": "24b0d16eba5fe233de3a26d5d7108d19",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 57021,
"upload_time": "2024-02-29T07:24:11",
"upload_time_iso_8601": "2024-02-29T07:24:11.059417Z",
"url": "https://files.pythonhosted.org/packages/e1/ca/2da205bb1baa9f86b9cc36145ab5435fbc50ee3cc136e4a90356dbbdc3d2/pykeepass-4.0.7.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-02-29 07:24:11",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "libkeepass",
"github_project": "pykeepass",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pykeepass"
}