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:
AmberAPI:
APIKey: somerandomkey342
BaseUrl: https://api.amber.com.au/v1
Timeout: 15
Files:
LogfileName: logfile.log
LogfileMaxLines: 500
LogProcessID: False
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.
"""Example code using the sc_utility libraries. Should not be included in the distrbution."""
import datetime as dt
import platform
import pprint
import sys
from example_config_schemas import ConfigSchema
from sc_utility import CSVReader, DateHelper, ExcelReader, SCConfigManager, SCLogger
CONFIG_FILE = "examples/example_config.yaml"
EXCEL_FILE = "examples/example_excel.xlsx"
CSV_FILE = "examples/example_csv.csv"
def update_csv():
header_config = [
{
"name": "Symbol",
"type": "str",
"match": True,
"sort": 2,
},
{
"name": "Date",
"type": "date",
"format": "%Y-%m-%d",
"match": True,
"sort": 1,
"minimum": None,
},
{
"name": "Name",
"type": "str",
},
{
"name": "Currency",
"type": "str",
},
{
"name": "Price",
"type": "float",
"format": ".2f",
},
]
extra_data = [
{
"Symbol": "AAPL",
"Date": dt.date(2023, 10, 1),
"Name": "Apple Inc.",
"Currency": "USD",
"Price": 150.00,
},
]
# Create an instance of the CSVReader class
try:
csv_reader = CSVReader(CSV_FILE, header_config)
except (ImportError, TypeError, ValueError) as e:
print(e, file=sys.stderr)
return
csv_reader.update_csv_file(extra_data)
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)
# Update a CSV file
update_csv()
# 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()