Files
cantaloupe-downloader/cantaloupe/config.py
T
shawn 9c3d3ef7ed feat: Click CLI wrapper for cantaloupe export
- cantaloupe/ package with click CLI (python -m cantaloupe export)
- export command: --output, --headless/--visible, --scheduled, --email, --password
- configure command: saves credentials to ~/.cantaloupe.env (600 perms)
- cantaloupe/config.py: credential loading from env vars + env file
- Updated src/auth.py _get_credentials() to also check ~/.cantaloupe.env
- File size, row count (openpyxl), and elapsed time reporting
- 39 new CLI/config tests + 4 updated auth tests; 86/86 pass
2026-05-21 18:35:34 -04:00

94 lines
2.8 KiB
Python

"""
Credential management for cantaloupe CLI.
Reads credentials from:
1. CANTALOUPE_EMAIL / CANTALOUPE_PASSWORD environment variables
2. ~/.cantaloupe.env file (key=value format)
Saves credentials to ~/.cantaloupe.env with restrictive permissions (600).
"""
import os
from pathlib import Path
ENV_FILE = Path.home() / ".cantaloupe.env"
ENV_EMAIL_KEY = "CANTALOUPE_EMAIL"
ENV_PASSWORD_KEY = "CANTALOUPE_PASSWORD"
def load_credentials() -> tuple[str, str]:
"""Load credentials from env vars or ~/.cantaloupe.env.
Priority: environment variables override the env file.
Returns (email, password) — either or both may be empty strings.
"""
email = os.environ.get(ENV_EMAIL_KEY, "")
password = os.environ.get(ENV_PASSWORD_KEY, "")
# If both are set via env, use them
if email and password:
return email, password
# Check the env file
if ENV_FILE.exists():
for line in ENV_FILE.read_text().splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, _, value = line.partition("=")
key = key.strip()
value = value.strip().strip('"').strip("'")
if key == ENV_EMAIL_KEY and not email:
email = value
elif key == ENV_PASSWORD_KEY and not password:
password = value
return email, password
def save_credentials(email: str, password: str) -> Path:
"""Save credentials to ~/.cantaloupe.env.
Updates the email/password lines in-place, preserving any other
configuration lines that may be present. Sets file permissions to 600.
Returns the path to the env file.
"""
ENV_FILE.parent.mkdir(parents=True, exist_ok=True)
# Read existing lines, filtering out old credential entries
lines: list[str] = []
if ENV_FILE.exists():
for line in ENV_FILE.read_text().splitlines():
stripped = line.strip()
if stripped.startswith(f"{ENV_EMAIL_KEY}=") or stripped.startswith(
f"{ENV_PASSWORD_KEY}="
):
continue
lines.append(line)
# Append new credentials
lines.append(f"{ENV_EMAIL_KEY}={email}")
lines.append(f"{ENV_PASSWORD_KEY}={password}")
ENV_FILE.write_text("\n".join(lines) + "\n")
ENV_FILE.chmod(0o600)
return ENV_FILE
def prompt_credentials() -> tuple[str, str]:
"""Prompt interactively for credentials.
Uses input() for email and getpass() for password.
Returns (email, password) — empty strings if cancelled.
"""
try:
import getpass
email = input("Cantaloupe email: ").strip()
password = getpass.getpass("Cantaloupe password: ")
return email, password
except (EOFError, KeyboardInterrupt):
return "", ""