Separating Credentials in Python

You gotta keep ’em separated

david marsh

2024-11-01

Here’s a way to keep your api credentials out of your Python code.

Creating a credentials file is a great way to avoid putting your credentials directly into your python code.

Here’s one way to do it:

#!/usr/bin/env python3
 
#https://docs.python.org/3/library/configparser.html
 
#create a config.ini like this:
#[credentials]
#ACCESS_ID = 12345678901234567890
#ACCESS_KEY = 1234567890123456789123456789012345678901
#ACCOUNT_NAME = example
 
import configparser
 
def main():
    config = configparser.ConfigParser()
    config.read('config.ini')
 
    ACCESS_ID = config.get('credentials', 'ACCESS_ID')
    ACCESS_KEY = config.get('credentials', 'ACCESS_KEY')
    ACCOUNT_NAME = config.get('credentials', 'ACCOUNT_NAME')
 
    #print(ACCESS_ID, ACCESS_KEY, ACCOUNT_NAME)
 
if __name__ == "__main__":
    main()

Here’s a heap of improvements made by ChatGPT, all of which seem very sensible:

#!/usr/bin/env python3

# Example config.ini:
# [credentials]
# ACCESS_ID = 12345678901234567890
# ACCESS_KEY = 1234567890123456789123456789012345678901
# ACCOUNT_NAME = example

import configparser
import sys

CONFIG_FILE = 'config.ini'

def load_config(file_path=CONFIG_FILE):
    """Load configuration from a file."""
    config = configparser.ConfigParser(interpolation=None)  # Disable interpolation eg for % symbols
    try:
        with open(file_path) as config_file:
            config.read_file(config_file)
    except FileNotFoundError:
        sys.exit(f"Error: Configuration file '{file_path}' not found.")
    except configparser.Error as e:
        sys.exit(f"Error: Failed to parse config file '{file_path}': {e}")

    # Retrieve credentials, with error handling
    try:
        access_id = config.get('credentials', 'ACCESS_ID')
        access_key = config.get('credentials', 'ACCESS_KEY')
        account_name = config.get('credentials', 'ACCOUNT_NAME')
    except configparser.NoSectionError:
        sys.exit("Error: 'credentials' section missing in configuration file.")
    except configparser.NoOptionError as e:
        sys.exit(f"Error: Missing configuration option in 'credentials': {e}")

    return access_id, access_key, account_name

def main():
    access_id, access_key, account_name = load_config()
    # Process or print credentials here as needed
    print(access_id, access_key, account_name)

if __name__ == "__main__":
    main()