Wiki

Clone wiki

Python Keyring Lib / Redesign

Redesign proposal

Rationale

The Python Keyring library is a wrapper library used by developers, which should be aimed at simplifying access and interaction with os-specific keyrings.

Using the keyring library

Backend access

The developer, in order to use the library, should either:

  • pick a specific keyring backend if he wants to, e.g.
from keyring.backend import FooKeyring
keyring = FooKeyring()
  • or could call an entry point factory method, which could allow an arbitrary KeyringPickStrategy to be injected, but would come with a DefaultKeyringPickStrategy:
from keyring import get_configured_keyring
keyring = get_configured_keyring()

keyring interface

All keyrings would share the very same interface, that is:

class Keyring(object):
    def set_password(self, service, username, password):
        """
        @return None: if password was set OK.
        @raise TransientKeyringError: if a transient error, e.g. user clicked "no"
               on keyring access, has occurred
        @raise Exception: any other error that might occur while setting
               the password.
        """
        pass

    def get_password(self, service, username):
        @return None: if no password is available for such service and username
        @return password: if a password was found for such service and username
        @raise TransientKeyringError: if a transient error, e.g. user clicked "no"
               on keyring access, has occurred
        @raise Exception: any other error that might occur while getting
               the password.
        """
        pass

maybe it would be better if we set and get unicode objects only, it will prevent a lot of headaches later on and will give us an easy python 3 forward support path.

keyring object initialization

If a keyring object can be instanced, then it can be used on that platform.

we can decide if we want to do all the dirty work, e.g. checking whether the keyring could work on the platfrom, in the init or in a factory method which can be static or classbound.

KeyringPickStrategy

Would take as input the list of all working keyring on the current platform, and should return the best suited keyring

DefaultKeyringPickStrategy

  • check if a keyring was configured in keyring.cfg
  • if it's configured and it was passed in input keyrings, return it.
  • it it's configured but wasn't passed as an input keyring, raise an exception?
  • if there's no configured keyring, guess depending on platform, available keyrings, ecc. and return it.

Utilities

ForgivingKeyringProxy

Just accepts a backend as input and exposes the very same interface as a backend, but never raises an exception on set/get password errors.

StringKeyringProxy

If we assume a backend should just accept and return unicode object, this could be useful to let quick and safe string conversions to happen:

keyring = get_configured_keyring()
string_keyring = StringKeyringProxy(keyring, "utf-8")

Updated