load_profile.py•4.53 kB
#!/usr/bin/env python3
"""Load API profile from YAML and export as environment variables."""
import os
import re
import sys
from pathlib import Path
try:
import yaml
except ImportError:
print("Error: pyyaml is required. Install with: pip install pyyaml", file=sys.stderr)
sys.exit(1)
def resolve_env_vars(value: str) -> str:
"""Resolve environment variable references in string values.
Supports ${VAR_NAME} syntax.
Args:
value: String that may contain ${VAR_NAME} references
Returns:
String with environment variables resolved
"""
if not isinstance(value, str):
return value
pattern = re.compile(r'\$\{([^}]+)\}')
def replacer(match):
var_name = match.group(1)
env_value = os.environ.get(var_name)
if env_value is None:
print(f"Warning: Environment variable {var_name} is not set", file=sys.stderr)
return ""
return env_value
return pattern.sub(replacer, value)
def load_profile(profile_path: Path) -> dict:
"""Load and parse YAML profile file.
Args:
profile_path: Path to YAML profile file
Returns:
Dictionary with profile configuration
Raises:
FileNotFoundError: If profile file doesn't exist
yaml.YAMLError: If YAML parsing fails
"""
if not profile_path.exists():
raise FileNotFoundError(f"Profile not found: {profile_path}")
with open(profile_path) as f:
data = yaml.safe_load(f)
if not data:
raise ValueError(f"Empty profile: {profile_path}")
resolved = {}
for key, value in data.items():
if isinstance(value, str):
resolved[key] = resolve_env_vars(value)
else:
resolved[key] = value
return resolved
def export_as_env(profile: dict) -> None:
"""Export profile values as environment variables.
Prints export statements that can be sourced by shell.
Args:
profile: Profile configuration dictionary
"""
env_mapping = {
'api_name': 'API_NAME',
'api_base_url': 'API_BASE_URL',
'api_spec_url': 'API_SPEC_URL',
'auth_type': 'AUTH_TYPE',
'auth_token': 'AUTH_TOKEN',
'auth_username': 'AUTH_USERNAME',
'auth_password': 'AUTH_PASSWORD',
'auth_api_key': 'AUTH_API_KEY',
'auth_api_key_name': 'AUTH_API_KEY_NAME',
'auth_api_key_in': 'AUTH_API_KEY_IN',
'auth_cognito_user_pool_id': 'AUTH_COGNITO_USER_POOL_ID',
'auth_cognito_client_id': 'AUTH_COGNITO_CLIENT_ID',
'auth_cognito_username': 'AUTH_COGNITO_USERNAME',
'auth_cognito_password': 'AUTH_COGNITO_PASSWORD',
'local_port': 'LOCAL_PORT',
}
for yaml_key, env_var in env_mapping.items():
if yaml_key in profile and profile[yaml_key]:
value = str(profile[yaml_key])
escaped_value = value.replace("'", "'\\''")
print(f"export {env_var}='{escaped_value}'")
def main():
"""Main entry point."""
if len(sys.argv) < 2:
print("Usage: load_profile.py <profile-name-or-path>", file=sys.stderr)
print("\nExamples:", file=sys.stderr)
print(" load_profile.py zoho-crm", file=sys.stderr)
print(" load_profile.py petstore", file=sys.stderr)
print(" load_profile.py profiles/custom.yaml", file=sys.stderr)
sys.exit(1)
profile_input = sys.argv[1]
project_root = Path(__file__).parent.parent
if profile_input.endswith('.yaml') or profile_input.endswith('.yml'):
profile_path = Path(profile_input)
if not profile_path.is_absolute():
profile_path = project_root / profile_path
else:
profile_path = project_root / 'profiles' / f'{profile_input}.yaml'
try:
profile = load_profile(profile_path)
required_fields = ['api_name', 'api_base_url', 'api_spec_url', 'auth_type']
missing = [f for f in required_fields if f not in profile or not profile[f]]
if missing:
print(f"Error: Missing required fields in profile: {', '.join(missing)}", file=sys.stderr)
sys.exit(1)
export_as_env(profile)
except FileNotFoundError as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
except yaml.YAMLError as e:
print(f"Error parsing YAML: {e}", file=sys.stderr)
sys.exit(1)
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
sys.exit(1)
if __name__ == '__main__':
main()