Artifacts Keyring
Artifacts Keyring (artifacts-keyring) is a Python library that automatically retrieves credentials for Azure Artifacts feeds. It functions as a backend for the `keyring` library, enabling tools like pip, twine, and other package managers to seamlessly authenticate with Azure DevOps, GitHub Packages, and Azure Container Registry (ACR) feeds. The current version is 1.0.0, and releases are tied to bug fixes or feature additions for Azure Artifacts integration.
Warnings
- gotcha This library functions as a `keyring` backend, transparently providing credentials for Azure Artifacts. Users interact with the `keyring` library's API (e.g., `keyring.get_password`), not a direct API from `artifacts-keyring` itself.
- gotcha For `artifacts-keyring` to successfully retrieve credentials, an active Azure Artifacts session or login (e.g., via Azure CLI, Visual Studio, or browser) is often required for initial token acquisition. It does not perform independent authentication.
- gotcha If multiple `keyring` backends are installed, `artifacts-keyring` might not be the default or highest priority for Azure Artifacts URLs, leading to unexpected credential retrieval failures.
- gotcha By default, `artifacts-keyring` might trigger interactive login prompts when credentials are needed. To prevent this in automated environments (e.g., CI/CD pipelines), set the `ARTIFACTS_KEYRING_DISABLE_PROMPT` environment variable to `1`.
Install
-
pip install artifacts-keyring
Imports
- No direct user-facing symbols for core functionality
Functionality is automatically registered with `keyring` upon installation.
Quickstart
import os
import subprocess
import sys
import keyring
print("--- Verifying artifacts-keyring installation and backend ---")
try:
# Run keyring's CLI to list backends and verify registration
print("Listing available keyring backends...")
result = subprocess.run(
[sys.executable, "-m", "keyring", "--list-backends"],
capture_output=True, text=True, check=True, encoding="utf-8"
)
print("Available Keyring Backends:")
print(result.stdout)
if "Azure Artifacts Keyring Backend" in result.stdout:
print("SUCCESS: Azure Artifacts Keyring Backend found in the list!")
else:
print("WARNING: Azure Artifacts Keyring Backend NOT found in the listed backends.")
print("\n--- Demonstrating keyring interaction (requires Azure Artifacts setup) ---")
# Example of how keyring *would* be used to retrieve a password for an Azure Artifacts service.
# Note: This will likely prompt for credentials or return None if no Azure Artifacts
# feed is configured in your environment that matches the service_name.
# It demonstrates the interaction point, not necessarily a successful auth without setup.
# Use an example Azure Artifacts service name (replace with your actual feed if testing)
# The exact service name format might vary slightly depending on the tool/context,
# but generally involves the feed URL or identifier.
service_name = "https://pkgs.dev.azure.com/your_org/_packaging/your_feed/nuget/v3/index.json"
username = "artifact_username" # artifacts-keyring often handles username automatically or it's 'token'
# Set ARTIFACTS_KEYRING_DISABLE_PROMPT to avoid interactive prompts in automated tests
os.environ['ARTIFACTS_KEYRING_DISABLE_PROMPT'] = '1'
print(f"Attempting to retrieve password for service: {service_name}")
password = keyring.get_password(service_name, username)
if password:
print(f"Successfully retrieved password for '{service_name}' (first 5 chars): {password[:5]}...")
else:
print(f"No password retrieved for '{service_name}'.")
print("This is expected if you are not currently logged into Azure Artifacts")
print("or if this specific service name is not configured for automatic credential retrieval.")
print("To test further, ensure you have an active Azure login (e.g., `az login`) ")
print("and try to access an Azure Artifacts feed via a tool that uses keyring (e.g., pip, twine).")
except ImportError:
print("ERROR: 'keyring' not found. Please ensure 'artifacts-keyring' (which depends on 'keyring') is installed.")
except subprocess.CalledProcessError as e:
print(f"ERROR: Failed to run keyring CLI. Return code: {e.returncode}\nStdout: {e.stdout}\nStderr: {e.stderr}")
except Exception as e:
print(f"An unexpected error occurred: {e}")