Log in to Charmhub with Ubuntu One

This guide shows you how to log in to Charmhub using your Ubuntu One credentials and how to save those credentials securely in your system keyring. This allows you to retrieve them in future sessions without re-entering your password.

Prerequisites

Before you begin, ensure you have:

  • An Ubuntu One account.

  • The craft-store library installed.

  • A functional system keyring, such as GNOME Keyring or KWallet.

Authenticate and save credentials

To authenticate, use the login_with() method. This method requests a macaroon from Charmhub, discharges it using your Ubuntu One credentials, and saves the resulting root/discharge macaroon pair in your system keyring.

from craft_store.login import UbuntuOneLogin

UbuntuOneLogin.login_with(
    email="<email>",
    password="<password>",
    base_url="https://api.charmhub.io",
    permissions=["account-view-packages", "account-register-package"],
)

Replace <email> and <password> with your actual credentials.

Authenticate with OTP

If your account has two-factor authentication enabled, the first call will raise UbuntuOneOtpRequiredError. Retry with your one-time password using the otp argument:

from craft_store.login import UbuntuOneLogin, UbuntuOneOtpRequiredError

try:
    UbuntuOneLogin.login_with(
        email="<email>",
        password="<password>",
        base_url="https://api.charmhub.io",
        permissions=["account-view-packages", "account-register-package"],
    )
except UbuntuOneOtpRequiredError:
    UbuntuOneLogin.login_with(
        email="<email>",
        password="<password>",
        base_url="https://api.charmhub.io",
        permissions=["account-view-packages", "account-register-package"],
        otp="<otp>",
    )

Use the credentials with a store client

To create a gateway that reads your saved credentials from the keyring, use the with_ubuntu_one() method.

from craft_store.publisher import PublisherGateway

gateway = PublisherGateway.with_ubuntu_one(
    base_url="https://api.charmhub.io",
    namespace="charm",
)

# List your registered charms
for charm in gateway.list_registered_names(include_collaborations=True):
    print(f"{charm.name} [{charm.status}]")

Verify your login

Use the whoami() method to verify that you’re logged in and to retrieve information about your account.

user_info = gateway.whoami()
print(f"Logged in as: {user_info['account']['display-name']}")

Handle login errors

The login_with method raises specific errors if the authentication fails.

from craft_store.login import (
    UbuntuOneLogin,
    UbuntuOneCredentialsError,
    UbuntuOneOtpRequiredError,
)

try:
    UbuntuOneLogin.login_with(
        email="<email>",
        password="<password>",
        base_url="https://api.charmhub.io",
        permissions=["account-view-packages", "account-register-package"],
    )
except UbuntuOneOtpRequiredError:
    print("Your account requires two-factor authentication. Please provide an OTP.")
except UbuntuOneCredentialsError:
    print("Invalid email, password, or OTP.")

Handle missing credentials

If you try to use the gateway but no credentials are found in the keyring, the first API call will raise CredentialsUnavailable. Catch this error to prompt the user to log in.

from craft_store import errors

try:
    names = gateway.list_registered_names()
except errors.CredentialsUnavailable:
    print("No credentials found. Run the login step first.")