Skip to content

decorative_secrets.onepassword

ApplyOnepasswordArgumentsOptions dataclass

This class contains options governing the behavior of the apply_onepassword_arguments decorator.

Attributes:

  • account (str | None) –

    A 1Password account URL. For example, individuals and families will use "my.1password.com", while teams and businesses will use a custom subdomain. If not provided, the OP_ACCOUNT environment variable will be used, if set. This is only necessary when using the 1Password CLI where multiple accounts are configured, and if no token is provided or inferred from an environment variable.

  • token (str | None) –

    A 1Password or 1Password connect service account token. If not provided, the OP_SERVICE_ACCOUNT_TOKEN or OP_CONNECT_TOKEN environment variables will be used, if set.

  • host (str | None) –

    A 1Password Connect host URL. If not provided, the OP_CONNECT_HOST environment variable will be used, if set. This is required when using a self-hosted 1Password Connect server.

Source code in src/decorative_secrets/onepassword.py
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
@dataclass(frozen=True)
class ApplyOnepasswordArgumentsOptions:
    """
    This class contains options governing the behavior of the
    [apply_onepassword_arguments
    ](./#decorative_secrets.onepassword.apply_onepassword_arguments) decorator.

    Attributes:
        account: A 1Password account URL. For example, individuals
            and families will use "my.1password.com", while teams and
            businesses will use a custom subdomain. If not provided, the
            `OP_ACCOUNT` environment variable will be used, if set. This is
            only necessary when using the 1Password CLI where multiple
            accounts are configured, and if no token is provided or inferred
            from an environment variable.
        token: A 1Password or 1Password connect service account
            token. If not provided, the `OP_SERVICE_ACCOUNT_TOKEN` or
            `OP_CONNECT_TOKEN` environment variables will be used, if set.
        host: A 1Password Connect host URL. If not
            provided, the `OP_CONNECT_HOST` environment variable will be used,
            if set. This is required when using a self-hosted 1Password
            Connect server.
    """

    account: str | None = None
    token: str | None = None
    host: str | None = None

apply_onepassword_arguments

apply_onepassword_arguments(
    *args: decorative_secrets.onepassword.ApplyOnepasswordArgumentsOptions,
    **kwargs: str
) -> collections.abc.Callable

This decorator maps parameter names to 1Password resources. Each key represents the name of a parameter in the decorated function which accepts an explicit input, and the corresponding mapped value is a parameter name accepting a resource path with which to lookup a secret to pass to the mapped parameter in lieu of an explicitly provided argument.

Parameters:

  • *args (decorative_secrets.onepassword.ApplyOnepasswordArgumentsOptions, default: () ) –

    An optional ApplyOnepasswordArgumentsOptions instance governing the behavior of this decorator. If not provided, a default instance of ApplyOnepasswordArgumentsOptions() will be used. If multiple instances are provided, only the first will be used.

  • **kwargs (str, default: {} ) –

    A mapping of static parameter names to the parameter names of arguments accepting 1Password resource paths from which to retrieve the value when the key argument is not explicitly provided.

Example
from functools import (
    cache,
)
from decorative_secrets.onepassword import (
    apply_onepassword_arguments,
)
from my_client_sdk import (
    Client,
)


@cache
@apply_onepassword_arguments(
    client_id="client_id_onepassword",
    client_secret="client_secret_onepassword",
)
def get_client(
    client_id: str | None = None,
    client_secret: str = None,
    client_id_onepassword: str | None = None,
    client_secret_onepassword: str | None = None,
) -> Client:
    return Client(
        oauth2_client_id=client_id,
        oauth2_client_secret=client_secret,
    )


client: Client = get_client(
    client_id_onepassword=(
        "op://Vault Name/Client ID Item Name/username",
    ),
    client_secret_onepassword=(
        "op://Vault Name/Client Secret Item Name/credential",
    ),
)
Source code in src/decorative_secrets/onepassword.py
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
def apply_onepassword_arguments(
    *args: ApplyOnepasswordArgumentsOptions,
    **kwargs: str,
) -> Callable:
    """
    This decorator maps parameter names to 1Password resources.
    Each key represents the name of a parameter in the decorated function
    which accepts an explicit input, and the corresponding mapped value is a
    parameter name accepting a resource path with which to lookup a secret
    to pass to the mapped parameter in lieu of an explicitly provided
    argument.

    Parameters:
        *args: An optional [ApplyOnepasswordArgumentsOptions
            ](./#decorative_secrets.onepassword.ApplyOnepasswordArgumentsOptions)
            instance governing the behavior of this decorator. If not provided,
            a default instance of [ApplyOnepasswordArgumentsOptions()
            ](./#decorative_secrets.onepassword.ApplyOnepasswordArgumentsOptions)
            will be used. If multiple instances are provided, only the first
            will be used.
        **kwargs:
            A mapping of static parameter names to the parameter names
            of arguments accepting 1Password resource paths from which to
            retrieve the value when the key argument is not explicitly
            provided.

    Example:
        ```python
        from functools import (
            cache,
        )
        from decorative_secrets.onepassword import (
            apply_onepassword_arguments,
        )
        from my_client_sdk import (
            Client,
        )


        @cache
        @apply_onepassword_arguments(
            client_id="client_id_onepassword",
            client_secret="client_secret_onepassword",
        )
        def get_client(
            client_id: str | None = None,
            client_secret: str = None,
            client_id_onepassword: str | None = None,
            client_secret_onepassword: str | None = None,
        ) -> Client:
            return Client(
                oauth2_client_id=client_id,
                oauth2_client_secret=client_secret,
            )


        client: Client = get_client(
            client_id_onepassword=(
                "op://Vault Name/Client ID Item Name/username",
            ),
            client_secret_onepassword=(
                "op://Vault Name/Client Secret Item Name/credential",
            ),
        )
        ```
    """
    options: ApplyOnepasswordArgumentsOptions
    args, options = _get_args_options(*args)
    read_onepassword_secret_: Callable[..., str] = read_onepassword_secret
    async_read_onepassword_secret_: Callable[
        [str, str | None, str | None, str | None], Coroutine[Any, Any, str]
    ] = async_read_onepassword_secret
    if (
        (options.account is not None)
        or (options.token is not None)
        or (options.host is not None)
    ):
        read_onepassword_secret_ = partial(
            read_onepassword_secret_,
            **({"account": options.account} if options.account else {}),
            **({"token": options.token} if options.token else {}),
            **({"host": options.host} if options.host else {}),
        )
        async_read_onepassword_secret_ = partial(
            async_read_onepassword_secret_,
            **({"account": options.account} if options.account else {}),
            **({"token": options.token} if options.token else {}),
            **({"host": options.host} if options.host else {}),
        )
    return apply_callback_arguments(
        read_onepassword_secret_,
        async_read_onepassword_secret_,
        **kwargs,
    )

which_op

which_op() -> str

Locate the 1Password CLI executable, or attempt to install it if not found.

Source code in src/decorative_secrets/onepassword.py
168
169
170
171
172
173
174
175
176
177
178
179
def which_op() -> str:
    """
    Locate the 1Password CLI executable, or attempt
    to install it if not found.
    """
    op: str = which("op") or "op"
    try:
        check_output((op, "--version"))
    except (CalledProcessError, FileNotFoundError):
        _install_op()
        op = which("op") or "op"
    return op

iter_op_account_list

iter_op_account_list() -> collections.abc.Iterable[str]

Yield all 1password account names.

Source code in src/decorative_secrets/onepassword.py
194
195
196
197
198
199
200
201
def iter_op_account_list() -> Iterable[str]:
    """
    Yield all 1password account names.
    """
    op: str = which_op()
    line: str
    for line in check_output((op, "account", "list")).strip().split("\n")[1:]:
        yield line.partition(" ")[0]

op_signin

op_signin(account: str | None = None) -> str

Sign in to 1Password using the CLI if not already signed in.

Source code in src/decorative_secrets/onepassword.py
204
205
206
207
208
209
210
211
212
213
214
def op_signin(account: str | None = None) -> str:
    """
    Sign in to 1Password using the CLI if not already signed in.
    """
    account = account or os.getenv("OP_ACCOUNT")
    if account:
        return _op_signin(account)
    op: str | None = None
    for account in iter_op_account_list():
        op = _op_signin(account)
    return op or which_op()

async_read_onepassword_secret async

async_read_onepassword_secret(
    resource: str,
    account: str | None = None,
    token: str | None = None,
    host: str | None = None,
) -> str

Asynchronously read a secret from 1Password using either the onepassword-sdk or onepasswordconnectsdk libraries, or the op executable (1password CLI), depending on the provided arguments and environment variables.

Parameters:

  • resource (str) –

    A 1Password secret resource path. For example: "op://Vault Name/Client Secret Item Name/credential"

  • account (str | None, default: None ) –

    A 1Password account URL. For example, individuals and families will use "my.1password.com", while teams and businesses will use a custom subdomain. This is only necessary when using the 1Password CLI where multiple accounts are configured.

  • token (str | None, default: None ) –

    A 1Password or 1Password connect service account token.

  • host (str | None, default: None ) –

    A 1Password Connect host URL. This is required when using self-hosted 1Password Connect.

Returns:

  • str

    The resolved secret value.

Source code in src/decorative_secrets/onepassword.py
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
@alru_cache(maxsize=None)
async def async_read_onepassword_secret(
    resource: str,
    account: str | None = None,
    token: str | None = None,
    host: str | None = None,
) -> str:
    """
    Asynchronously read a secret from 1Password using either the
    `onepassword-sdk` or `onepasswordconnectsdk` libraries, or the `op`
    executable (1password CLI), depending on the provided arguments and
    environment variables.

    Parameters:
        resource: A 1Password secret resource path. For example:
            "op://Vault Name/Client Secret Item Name/credential"
        account: A 1Password account URL. For example, individuals and families
            will use "my.1password.com", while teams and businesses will use
            a custom subdomain. This is only necessary when using
            the 1Password CLI where multiple accounts are configured.
        token: A 1Password or 1Password connect service account token.
        host: A 1Password Connect host URL. This is required when using
            self-hosted 1Password Connect.

    Returns:
        The resolved secret value.
    """
    account, token, host = _resolve_auth_arguments(account, token, host)
    if token:
        if host:
            return await _async_resolve_connect_resource(token, host, resource)
        return await _async_resolve_resource(token, resource)
    op: str | None = None
    with suppress(FileNotFoundError, CalledProcessError):
        op = op_signin(account)
    if not op:
        op = which_op() or "op"
    return check_output(
        (op, "read")
        + (("--account", account) if account else ())
        + (("--session", token) if token else ())
        + (resource,)
    )

get_onepassword_secret

get_onepassword_secret(
    resource: str,
    account: str | None = None,
    token: str | None = None,
    host: str | None = None,
) -> str

Read a secret from 1Password using either the onepassword-sdk or onepasswordconnectsdk libraries, or the op executable (1password CLI), depending on the provided arguments and environment variables.

Parameters:

  • resource (str) –

    A 1Password secret resource path. For example: "op://Vault Name/Client Secret Item Name/credential"

  • account (str | None, default: None ) –

    A 1Password account URL. For example, individuals and families will use "my.1password.com", while teams and businesses will use a custom subdomain. This is only necessary when using the 1Password CLI where multiple accounts are configured.

  • token (str | None, default: None ) –

    A 1Password or 1Password connect service account token.

  • host (str | None, default: None ) –

    A 1Password Connect host URL. This is required when using self-hosted 1Password Connect.

Returns:

  • str

    The resolved secret value.

Source code in src/decorative_secrets/onepassword.py
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
def get_onepassword_secret(
    resource: str,
    account: str | None = None,
    token: str | None = None,
    host: str | None = None,
) -> str:
    """
    Read a secret from 1Password using either the `onepassword-sdk` or
    `onepasswordconnectsdk` libraries, or the `op` executable (1password CLI),
    depending on the provided arguments and environment variables.

    Parameters:
        resource: A 1Password secret resource path. For example:
            "op://Vault Name/Client Secret Item Name/credential"
        account: A 1Password account URL. For example, individuals and families
            will use "my.1password.com", while teams and businesses will use
            a custom subdomain. This is only necessary when using
            the 1Password CLI where multiple accounts are configured.
        token: A 1Password or 1Password connect service account token.
        host: A 1Password Connect host URL. This is required when using
            self-hosted 1Password Connect.

    Returns:
        The resolved secret value.
    """
    return _read_onepassword_secret(
        resource, account=account, token=token, host=host, **os.environ
    )

main

main() -> None

Run a command: - install: Install the Databricks CLI if not already installed - get: Get a secret from Databricks and print it to stdout

Source code in src/decorative_secrets/onepassword.py
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
def main() -> None:
    """
    Run a command:
    -   install: Install the Databricks CLI if not already installed
    -   get: Get a secret from Databricks and print it to stdout
    """
    command = _get_command()
    if command in ("--help", "-h"):
        _print_help()
        return
    parser: argparse.ArgumentParser
    if command == "install":
        parser = argparse.ArgumentParser(
            prog="decorative-secrets onepassword install",
            description="Install the 1Password CLI",
        )
        parser.parse_args()
        _install_op()
    elif command == "get":
        parser = argparse.ArgumentParser(
            prog="decorative-secrets onepassword get",
            description="Get a secret from 1Password",
        )
        parser.add_argument(
            "reference",
            type=str,
        )
        parser.add_argument(
            "--account",
            default=None,
            type=str,
            help="Which 1Password account to use",
        )
        parser.add_argument(
            "-t",
            "--token",
            default=None,
            type=str,
            help="A 1Password Service Account Token",
        )
        parser.add_argument(
            "--host",
            default=None,
            type=str,
            help="A 1Password Connect Host URL",
        )
        namespace: argparse.Namespace = parser.parse_args()
        print(  # noqa: T201
            read_onepassword_secret(
                namespace.reference,
                host=namespace.host,
                account=namespace.account,
                token=namespace.token,
            )
        )