Twine: How to disable keyring

Created on 8 Apr 2018  路  14Comments  路  Source: pypa/twine

Twine supports keyring, but it's not clear to me how to use twine without this support. Is this implemented or do we just miss documentation?

documentation

Most helpful comment

I figured it out.

Have a keyring configured that causes an error retrieving the password (will emit a warning with twine but still prompt).

Here's how to do it:

$ mkdir -p $(python -c 'import keyring.util.platform_; print(keyring.util.platform_.config_root())')
$ echo '[backend]\ndefault-keyring=keyring.backends.fail.Keyring' > $(python -c 'import keyring.util.platform_; print(keyring.util.platform_.config_root())')/keyringrc.cfg

Test that it's working with keyring get system user, which should emit something like:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/bin/keyring", line 11, in <module>
    sys.exit(main())
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/keyring/cli.py", line 120, in main
    return cli.run(argv)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/keyring/cli.py", line 62, in run
    password = get_password(service, username)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/keyring/core.py", line 41, in get_password
    return _keyring_backend.get_password(service_name, username)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/keyring/backends/fail.py", line 23, in get_password
    raise RuntimeError(msg)
RuntimeError: No recommended backend was available. Install the keyrings.alt package if you want to use the non-recommended backends. See README.rst for details.

All 14 comments

Code is here. You have a few options.

  1. Don't have keyring installed in your environment.
  2. Don't have a password defined in the preferred keyring for the relevant URL and username.
  3. Have a keyring configured that causes an error retrieving the password (will emit a warning with twine but still prompt).

In that scenario, it will prompt for a password.

Let's find someplace to add this to the documentation.

I stumbled upon this again, but now I don't recall how information from https://github.com/pypa/twine/issues/338#issuecomment-380283801 helped me, as I don't have an option to uninstall neither kwallet (I still would like to have some kde tools installed, even when I don't use it as desktop) nor python-keyring package (because that would try to uninstall twine as well).

When I delete the kwalled database file and run twine again, I get window asking for setting up new wallet, and when I cancel it, twine still doesn't ask for a password:

$ twine upload dist/*
Uploading distributions to https://upload.pypi.org/legacy/
KeyringLocked: Failed to unlock the keyring!
$ rpm -q twine
twine-1.9.1-5.fc28.noarch

@jaraco any tips?

cannot uninstall python-keyring package (because that would try to uninstall twine as well).

Well, that's annoying. In the Python ecosystem, this isn't a problem because keyring is an optional, "extra" dependency on twine. My intention was that only users that planned to use keyring and have it configured would actually be interested in installing it to their environment. It sounds like you have a system package manager that doesn't have that nuance and unconditionally requires keyring.

So it does seem that perhaps this project or keyring should provide some way to disable keyring even when it's present and viable.

And then I have to wonder - should the Python ecosystem assume the same, and make keyring an unconditional dependency of twine, and rely on the additional functionality to suppress the use of keyring for environments where it's not wanted?

I figured it out.

Have a keyring configured that causes an error retrieving the password (will emit a warning with twine but still prompt).

Here's how to do it:

$ mkdir -p $(python -c 'import keyring.util.platform_; print(keyring.util.platform_.config_root())')
$ echo '[backend]\ndefault-keyring=keyring.backends.fail.Keyring' > $(python -c 'import keyring.util.platform_; print(keyring.util.platform_.config_root())')/keyringrc.cfg

Test that it's working with keyring get system user, which should emit something like:

Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.7/bin/keyring", line 11, in <module>
    sys.exit(main())
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/keyring/cli.py", line 120, in main
    return cli.run(argv)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/keyring/cli.py", line 62, in run
    password = get_password(service, username)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/keyring/core.py", line 41, in get_password
    return _keyring_backend.get_password(service_name, username)
  File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/keyring/backends/fail.py", line 23, in get_password
    raise RuntimeError(msg)
RuntimeError: No recommended backend was available. Install the keyrings.alt package if you want to use the non-recommended backends. See README.rst for details.

Keyring 15.1.0 provides an easier way to achieve what you're after, either through a command-line option that configures the environment or an environment variable you can set. See the above referenced issue for details.

Note, if you don't have keyring 15.1.0 in your main environment, you can still download keyring 15.1.0 to invoke the configuration behavior. Here's an example using rwt:

# don't do this
rwt -q keyring==15.1.0 -- -m keyring --disable

I just realized the above recommendation to disable keyring on earlier versions wouldn't work at all... because under the hood, it's configuring a keyring that only exists on this latest release.

So the best recommendation I have for older versions of keyring is in the previous comment.

Thinking about the lingering documentation issue, I'm kinda torn. The best recommendation, to use keyring --disable, isn't all that helpful unless you have the latest keyring. Maybe it makes sense to link in the documentation to this issue until keyring 15.1 has been out for some time and at that point just put that recommendation inline in the docs?

Thanks for looking into this and --disable option.

I tried you suggestion from https://github.com/pypa/twine/issues/338#issuecomment-421380861:

$ twine upload dist/*
Uploading distributions to https://upload.pypi.org/legacy/
RuntimeError: No recommended backend was available. Install the keyrings.alt package if you want to use the non-recommended backends. See README.rst for details.
$ 

but it still doesn't make twine to ask for password.

That said, I noticed that when I specify password via command line argument, it works (and keyring is not involved):

$ twine upload --password PASSWORD123 dist/*

But one one needs to be more careful as this is prone to leaking the secrets ...

but it still doesn't make twine to ask for password.

I don't understand why that would be. get_password uses password_from_keyring_or_prompt as the prompt_strategy, which uses this logic to suppress all exceptions (emitting the warning we do see) and ultimately calling getpass.getpass().

I think you'll need to trace the code to figure out why getpass.getpass isn't being called (or is being called and not doing anything).

I uninstalled keyring as recommended but now twine crashes with an error message that keyring is required.

Traceback (most recent call last):
  File "/usr/lib64/python3.9/runpy.py", line 197, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "/usr/lib64/python3.9/runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "/home/bloring/work/teca/py3k-teca4/lib64/python3.9/site-packages/twine/__main__.py", line 53, in <module>
    sys.exit(main())
  File "/home/bloring/work/teca/py3k-teca4/lib64/python3.9/site-packages/twine/__main__.py", line 28, in main
    result = cli.dispatch(sys.argv[1:])
  File "/home/bloring/work/teca/py3k-teca4/lib64/python3.9/site-packages/twine/cli.py", line 80, in dispatch
    main = registered_commands[args.command].load()
  File "/home/bloring/work/teca/py3k-teca4/lib64/python3.9/site-packages/pkg_resources/__init__.py", line 2460, in load
    self.require(*args, **kwargs)
  File "/home/bloring/work/teca/py3k-teca4/lib64/python3.9/site-packages/pkg_resources/__init__.py", line 2483, in require
    items = working_set.resolve(reqs, env, installer, extras=self.extras)
  File "/home/bloring/work/teca/py3k-teca4/lib64/python3.9/site-packages/pkg_resources/__init__.py", line 785, in resolve
    raise DistributionNotFound(req, requirers)
pkg_resources.DistributionNotFound: The 'keyring>=15.1' distribution was not found and is required by the application

would be far nicer if keyring were available via a command line option for those who like that sort of thing, and disabled by default so things just work for everyone.

Ugh. Sorry to hear that. It looks like you've stumbled onto a behavior in pkg_resources where pkg_resources does some packaging validation before loading metadata, a behavior that's superseded by importlib.metadata. Please file a new bug report for that.

I've started work on a patch that would avoid that undesirable behavior in #728.

Was this page helpful?
0 / 5 - 0 ratings