Module onepassword.onepassword
Expand source code
import subprocess
import json
import onepassword.exceptions as opex
from packaging.version import Version
from typing import Dict, List
def get_op_cli_version() -> Version:
"""
Retrieves the 1password-cli (op) version and returns the string version
as a Version object.
Returns:
Version: a Version object with the current 1password-cli version information
Raises:
OnePasswordCLINotFound: If the 1password-CLI is not found due to a FileNotFoundError exception
"""
cmd = ['op', '--version']
try:
return Version(subprocess.run(cmd, capture_output=True, text=True).stdout)
except FileNotFoundError:
raise opex.OnePasswordCLINotFound(msg="Cannot find `op`, do you have 1password-cli installed?")
def _run_cmd(cmd: List) -> subprocess.CompletedProcess | opex.OnePasswordRuntimeError:
r = subprocess.run(cmd, capture_output=True)
if r.returncode != 0:
raise opex.OnePasswordRuntimeError(f'Encountered an error when calling subprocess, got: {r.stderr}')
return r
def list_vaults() -> Dict | List[Dict]:
"""
Return a list of all vaults accessible to the 1password account
Returns:
Dict | List[Dict]: either a single dictionary for a vault, or list of dictionaries for multiple vaults
"""
cmd = ['op', 'vault', 'list', '--format', 'json']
return json.loads(_run_cmd(cmd).stdout)
class OnePassword:
"""
Entrypoint class for all 1Password related activities.
There are no credentials to be passed to this class as it will use native integration with 1Password CLI
https://developer.1password.com/docs/cli/get-started/
"""
def __init__(self, vault: str = "Private") -> None:
"""
Initialise the class with a vault, that by default is set to "Private".
The class also grabs the 1Password CLI version and this is used as a catch to ensure that the CLI
is installed before initialisation.
Args:
vault (str): string representation of which vault the class has to be initialised with.
Default is "Private"
"""
self.op_cli_version = get_op_cli_version()
self.vault = vault
def get_item(self, item: str, fields: List = None) -> Dict | List[Dict]:
"""
Returns either a string or dictionary response from 1Password
Args:
item (str): Can be either the name of the resource or its ID
fields (list): (optional) This is to narrow down any field values for your return criteria.
e.g. receiving a list containing: ['username', 'password']
Returns:
Dict | List[Dict]: either a single item as a dictionary or multiple items as a list of dictionaries
Raises:
OnePasswordJSONError: if the response cannot be JSON loaded due to a JSONDecodeError exception
"""
cmd = ['op', 'item', 'get', item, "--format", "json", "--vault", f"{self.vault}"]
if fields:
_fields = []
for field in fields:
_fields.append(f"label={field}")
cmd += ["--fields", ",".join(_fields)]
r = _run_cmd(cmd)
try:
return json.loads(r.stdout)
except json.JSONDecodeError as e:
raise opex.OnePasswordJSONError(f"Cannot JSON load response from 1Password. Got {e}")
def get_value(self, item: str, field: str) -> str:
"""
Retrieve an artefact from 1password and attempt to parse the field's value from it
Args:
item (str): name or UUID of item in Vault
field (str): string of field name to use as label
Returns:
str: a string representation of item's `field` value
Raises:
OnePasswordValueNotFound: if `value` has not been found in the dictionary
"""
try:
return self.get_item(item, fields=[field])['value']
except KeyError as e:
raise opex.OnePasswordValueNotFound(f"Value not found. Got error: {e}")
def get_username(self, item: str) -> str:
"""
Wrapper around `get_value` to get a username value from an item
Args:
item (str): name or UUID of item in Vault
Returns:
str: a string representation of username
"""
return self.get_value(item, "username")
def get_password(self, item: str) -> str:
"""
Wrapper around `get_value` to get a password value from an item
Args:
item (str): name or UUID of item in Vault
Returns:
str: string representation of password
"""
return self.get_value(item, "password")
def get_uuid(self, item: str) -> str:
"""
Retrieve the UUID of an item
Args:
item (str): name of the item
Returns:
str: a string representation of an item's UUID
Raises:
OnePasswordValueNotFound: if `id` has not been found in the dictionary
"""
try:
return self.get_item(item)['id']
except KeyError as e:
raise opex.OnePasswordValueNotFound(f"Value not found. Got error: {e}")
def get_document(self, item: str) -> bytes:
"""
Retrieve's a document from 1Password in bytes format for later use
Args:
item (str): name or UUID of item in Vault
Returns:
bytes: a document in bytes format
"""
cmd = ['op', 'document', 'get', item, '--vault', self.vault]
return _run_cmd(cmd).stdout
def list_items(self, categories: List = None, tags: List = None) -> Dict | List[Dict]:
"""
List all available items within the instantiated vault.
Entries can be filtered with `categories` and `tags`. By default, these are None.
Args:
categories (list): (optional) A list of categories to filter the list with
tags (list): (optional) A list of tags to filter the list with
Returns:
Dict | List[Dict]: either a single item as a dictionary or multiple items as a list of dictionaries
"""
cmd = ['op', 'items', 'list', '--vault', self.vault, '--format', 'json']
if categories:
cmd += ['--categories', ",".join(categories)]
if tags:
cmd += ['--tags', ",".join(tags)]
return json.loads(_run_cmd(cmd).stdout)
Functions
def get_op_cli_version() ‑> packaging.version.Version
-
Retrieves the 1password-cli (op) version and returns the string version as a Version object.
Returns
Version
- a Version object with the current 1password-cli version information
Raises
OnePasswordCLINotFound
- If the 1password-CLI is not found due to a FileNotFoundError exception
Expand source code
def get_op_cli_version() -> Version: """ Retrieves the 1password-cli (op) version and returns the string version as a Version object. Returns: Version: a Version object with the current 1password-cli version information Raises: OnePasswordCLINotFound: If the 1password-CLI is not found due to a FileNotFoundError exception """ cmd = ['op', '--version'] try: return Version(subprocess.run(cmd, capture_output=True, text=True).stdout) except FileNotFoundError: raise opex.OnePasswordCLINotFound(msg="Cannot find `op`, do you have 1password-cli installed?")
def list_vaults() ‑> Union[Dict, List[Dict]]
-
Return a list of all vaults accessible to the 1password account
Returns
Dict | List[Dict]: either a single dictionary for a vault, or list of dictionaries for multiple vaults
Expand source code
def list_vaults() -> Dict | List[Dict]: """ Return a list of all vaults accessible to the 1password account Returns: Dict | List[Dict]: either a single dictionary for a vault, or list of dictionaries for multiple vaults """ cmd = ['op', 'vault', 'list', '--format', 'json'] return json.loads(_run_cmd(cmd).stdout)
Classes
class OnePassword (vault: str = 'Private')
-
Entrypoint class for all 1Password related activities. There are no credentials to be passed to this class as it will use native integration with 1Password CLI https://developer.1password.com/docs/cli/get-started/
Initialise the class with a vault, that by default is set to "Private".
The class also grabs the 1Password CLI version and this is used as a catch to ensure that the CLI is installed before initialisation.
Args
vault
:str
- string representation of which vault the class has to be initialised with. Default is "Private"
Expand source code
class OnePassword: """ Entrypoint class for all 1Password related activities. There are no credentials to be passed to this class as it will use native integration with 1Password CLI https://developer.1password.com/docs/cli/get-started/ """ def __init__(self, vault: str = "Private") -> None: """ Initialise the class with a vault, that by default is set to "Private". The class also grabs the 1Password CLI version and this is used as a catch to ensure that the CLI is installed before initialisation. Args: vault (str): string representation of which vault the class has to be initialised with. Default is "Private" """ self.op_cli_version = get_op_cli_version() self.vault = vault def get_item(self, item: str, fields: List = None) -> Dict | List[Dict]: """ Returns either a string or dictionary response from 1Password Args: item (str): Can be either the name of the resource or its ID fields (list): (optional) This is to narrow down any field values for your return criteria. e.g. receiving a list containing: ['username', 'password'] Returns: Dict | List[Dict]: either a single item as a dictionary or multiple items as a list of dictionaries Raises: OnePasswordJSONError: if the response cannot be JSON loaded due to a JSONDecodeError exception """ cmd = ['op', 'item', 'get', item, "--format", "json", "--vault", f"{self.vault}"] if fields: _fields = [] for field in fields: _fields.append(f"label={field}") cmd += ["--fields", ",".join(_fields)] r = _run_cmd(cmd) try: return json.loads(r.stdout) except json.JSONDecodeError as e: raise opex.OnePasswordJSONError(f"Cannot JSON load response from 1Password. Got {e}") def get_value(self, item: str, field: str) -> str: """ Retrieve an artefact from 1password and attempt to parse the field's value from it Args: item (str): name or UUID of item in Vault field (str): string of field name to use as label Returns: str: a string representation of item's `field` value Raises: OnePasswordValueNotFound: if `value` has not been found in the dictionary """ try: return self.get_item(item, fields=[field])['value'] except KeyError as e: raise opex.OnePasswordValueNotFound(f"Value not found. Got error: {e}") def get_username(self, item: str) -> str: """ Wrapper around `get_value` to get a username value from an item Args: item (str): name or UUID of item in Vault Returns: str: a string representation of username """ return self.get_value(item, "username") def get_password(self, item: str) -> str: """ Wrapper around `get_value` to get a password value from an item Args: item (str): name or UUID of item in Vault Returns: str: string representation of password """ return self.get_value(item, "password") def get_uuid(self, item: str) -> str: """ Retrieve the UUID of an item Args: item (str): name of the item Returns: str: a string representation of an item's UUID Raises: OnePasswordValueNotFound: if `id` has not been found in the dictionary """ try: return self.get_item(item)['id'] except KeyError as e: raise opex.OnePasswordValueNotFound(f"Value not found. Got error: {e}") def get_document(self, item: str) -> bytes: """ Retrieve's a document from 1Password in bytes format for later use Args: item (str): name or UUID of item in Vault Returns: bytes: a document in bytes format """ cmd = ['op', 'document', 'get', item, '--vault', self.vault] return _run_cmd(cmd).stdout def list_items(self, categories: List = None, tags: List = None) -> Dict | List[Dict]: """ List all available items within the instantiated vault. Entries can be filtered with `categories` and `tags`. By default, these are None. Args: categories (list): (optional) A list of categories to filter the list with tags (list): (optional) A list of tags to filter the list with Returns: Dict | List[Dict]: either a single item as a dictionary or multiple items as a list of dictionaries """ cmd = ['op', 'items', 'list', '--vault', self.vault, '--format', 'json'] if categories: cmd += ['--categories', ",".join(categories)] if tags: cmd += ['--tags', ",".join(tags)] return json.loads(_run_cmd(cmd).stdout)
Methods
def get_document(self, item: str) ‑> bytes
-
Retrieve's a document from 1Password in bytes format for later use
Args
item
:str
- name or UUID of item in Vault
Returns
bytes
- a document in bytes format
Expand source code
def get_document(self, item: str) -> bytes: """ Retrieve's a document from 1Password in bytes format for later use Args: item (str): name or UUID of item in Vault Returns: bytes: a document in bytes format """ cmd = ['op', 'document', 'get', item, '--vault', self.vault] return _run_cmd(cmd).stdout
def get_item(self, item: str, fields: List = None) ‑> Union[Dict, List[Dict]]
-
Returns either a string or dictionary response from 1Password
Args
item
:str
- Can be either the name of the resource or its ID
fields
:list
- (optional) This is to narrow down any field values for your return criteria. e.g. receiving a list containing: ['username', 'password']
Returns
Dict | List[Dict]: either a single item as a dictionary or multiple items as a list of dictionaries
Raises
OnePasswordJSONError
- if the response cannot be JSON loaded due to a JSONDecodeError exception
Expand source code
def get_item(self, item: str, fields: List = None) -> Dict | List[Dict]: """ Returns either a string or dictionary response from 1Password Args: item (str): Can be either the name of the resource or its ID fields (list): (optional) This is to narrow down any field values for your return criteria. e.g. receiving a list containing: ['username', 'password'] Returns: Dict | List[Dict]: either a single item as a dictionary or multiple items as a list of dictionaries Raises: OnePasswordJSONError: if the response cannot be JSON loaded due to a JSONDecodeError exception """ cmd = ['op', 'item', 'get', item, "--format", "json", "--vault", f"{self.vault}"] if fields: _fields = [] for field in fields: _fields.append(f"label={field}") cmd += ["--fields", ",".join(_fields)] r = _run_cmd(cmd) try: return json.loads(r.stdout) except json.JSONDecodeError as e: raise opex.OnePasswordJSONError(f"Cannot JSON load response from 1Password. Got {e}")
def get_password(self, item: str) ‑> str
-
Wrapper around
get_value
to get a password value from an itemArgs
item
:str
- name or UUID of item in Vault
Returns
str
- string representation of password
Expand source code
def get_password(self, item: str) -> str: """ Wrapper around `get_value` to get a password value from an item Args: item (str): name or UUID of item in Vault Returns: str: string representation of password """ return self.get_value(item, "password")
def get_username(self, item: str) ‑> str
-
Wrapper around
get_value
to get a username value from an itemArgs
item
:str
- name or UUID of item in Vault
Returns
str
- a string representation of username
Expand source code
def get_username(self, item: str) -> str: """ Wrapper around `get_value` to get a username value from an item Args: item (str): name or UUID of item in Vault Returns: str: a string representation of username """ return self.get_value(item, "username")
def get_uuid(self, item: str) ‑> str
-
Retrieve the UUID of an item
Args
item
:str
- name of the item
Returns
str
- a string representation of an item's UUID
Raises
OnePasswordValueNotFound
- if
id
has not been found in the dictionary
Expand source code
def get_uuid(self, item: str) -> str: """ Retrieve the UUID of an item Args: item (str): name of the item Returns: str: a string representation of an item's UUID Raises: OnePasswordValueNotFound: if `id` has not been found in the dictionary """ try: return self.get_item(item)['id'] except KeyError as e: raise opex.OnePasswordValueNotFound(f"Value not found. Got error: {e}")
def get_value(self, item: str, field: str) ‑> str
-
Retrieve an artefact from 1password and attempt to parse the field's value from it
Args
item
:str
- name or UUID of item in Vault
field
:str
- string of field name to use as label
Returns
str
- a string representation of item's
field
value
Raises
OnePasswordValueNotFound
- if
value
has not been found in the dictionary
Expand source code
def get_value(self, item: str, field: str) -> str: """ Retrieve an artefact from 1password and attempt to parse the field's value from it Args: item (str): name or UUID of item in Vault field (str): string of field name to use as label Returns: str: a string representation of item's `field` value Raises: OnePasswordValueNotFound: if `value` has not been found in the dictionary """ try: return self.get_item(item, fields=[field])['value'] except KeyError as e: raise opex.OnePasswordValueNotFound(f"Value not found. Got error: {e}")
def list_items(self, categories: List = None, tags: List = None) ‑> Union[Dict, List[Dict]]
-
List all available items within the instantiated vault. Entries can be filtered with
categories
andtags
. By default, these are None.Args
categories
:list
- (optional) A list of categories to filter the list with
tags
:list
- (optional) A list of tags to filter the list with
Returns
Dict | List[Dict]: either a single item as a dictionary or multiple items as a list of dictionaries
Expand source code
def list_items(self, categories: List = None, tags: List = None) -> Dict | List[Dict]: """ List all available items within the instantiated vault. Entries can be filtered with `categories` and `tags`. By default, these are None. Args: categories (list): (optional) A list of categories to filter the list with tags (list): (optional) A list of tags to filter the list with Returns: Dict | List[Dict]: either a single item as a dictionary or multiple items as a list of dictionaries """ cmd = ['op', 'items', 'list', '--vault', self.vault, '--format', 'json'] if categories: cmd += ['--categories', ",".join(categories)] if tags: cmd += ['--tags', ",".join(tags)] return json.loads(_run_cmd(cmd).stdout)