Skip to content

Spello Consulting Utility Library Getting Started

Installing the library

The library is available from PyPi, so to add it to your Python project use pip:

pip install sc_utility

Or better yet, use UV:

uv add sc_utility

Configuration File

The library uses a YAML file for configuration. An example config file (config.yaml.example) is available on Github. Copy this to [your_app_name].yaml before using the library.

Here's the example file - the library expects to find the Files and Email sections in the file:

# Just an example section to show how to set up a section
AmberAPI:
    APIKey: somerandomkey342
    BaseUrl: https://api.amber.com.au/v1
    Timeout: 15

Files:
    LogfileName: logfile.log
    LogfileMaxLines: 500
    LogfileVerbosity: detailed
    ConsoleVerbosity: detailed

Email:
    EnableEmail: True
    SMTPServer: smtp.gmail.com
    SMTPPort: 587
    SMTPUsername: me@gmail.com
    SMTPPassword: <Your SMTP password>
    SubjectPrefix: "[Bob Portfolio]: "

Configuration Parameters

Section: Files

Parameter Description
LogfileName The name of the log file, can be a relative or absolute path.
LogfileMaxLines Maximum number of lines to keep in the log file. If zero, file will never be truncated.
LogfileVerbosity The level of detail captured in the log file. One of: none; error; warning; summary; detailed; debug; all
ConsoleVerbosity Controls the amount of information written to the console. One of: error; warning; summary; detailed; debug; all. Errors are written to stderr all other messages are written to stdout

Section: Email

Parameter Description
EnableEmail Set to True if you want to allow the app to send emails. If True, the remaining settings in this section must be configured correctly.
SMTPServer The SMTP host name that supports TLS encryption. If using a Google account, set to smtp.gmail.com
SMTPPort The port number to use to connect to the SMTP server. If using a Google account, set to 587
SMTPUsername Your username used to login to the SMTP server. If using a Google account, set to your Google email address.
SMTPPassword The password used to login to the SMTP server. If using a Google account, create an app password for the app at https://myaccount.google.com/apppasswords
SubjectPrefix Optional. If set, the app will add this text to the start of any email subject line for emails it sends.

Example code

Here's an example module that shows how to use the library classes. Use the API Reference navigation to view the API methods for each class. The code example and the companion config and Excel files is available in the examples/ folder in the Github repo.

import platform
import pprint
import sys

from example_config_schemas import ConfigSchema
from sc_utility import DateHelper, ExcelReader, SCConfigManager, SCLogger

CONFIG_FILE = "example_config.yaml"
EXCEL_FILE = "sample_excel.xlsx"


def main():
    """Main function to run the example code."""
    print(f"Hello from sc-utility running on {platform.system()}")

    # Get our default schema, validation schema, and placeholders
    schemas = ConfigSchema()

    # Initialize the SC_ConfigManager class
    try:
        config = SCConfigManager(
            config_file=CONFIG_FILE,
            default_config=schemas.default,
            validation_schema=schemas.validation,
            placeholders=schemas.placeholders
        )
    except RuntimeError as e:
        print(f"Configuration file error: {e}", file=sys.stderr)
        return

    # Print a value from the sample config file
    print(f"API key = {config.get('AmberAPI', 'APIKey')}")

    # Initialize the SC_Logger class
    try:
        logger = SCLogger(config.get_logger_settings())
    except RuntimeError as e:
        print(f"Logger initialisation error: {e}", file=sys.stderr)
        return

    logger.log_message("This is a test message at the summary level.", "summary")

    # Setup email
    email_settings = config.get_email_settings()

    if email_settings is not None:
        logger.register_email_settings(email_settings)

        text_msg = "Hello world from sc-utility example code."
        if logger.send_email("Hello world", text_msg):
            logger.log_message("Email sent OK.", "detailed")

    # Use DateHelper to get the current date and time
    prior_date = DateHelper.today_add_days(-7)
    print(f"Prior date (7 days ago): {prior_date}")

    # Create an instance of ExcelReader
    print("Testing ExcelReader...")
    excel_reader = ExcelReader(EXCEL_FILE)

    # Extract a table
    try:
        table_data = excel_reader.extract_data(source_name="Table1", source_type="table")
    except ImportError as e:
        print(f"Error extracting table: {e}")
        sys.exit(1)
    else:
        print("Table data extracted successfully:\n")
        pprint.pprint(table_data)

    # See if we have a fatal error from a previous run
    if logger.get_fatal_error():
        print("Prior fatal error detected.")
        logger.clear_fatal_error()


if __name__ == "__main__":
    main()