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()