A Python package for automating LMG processes
Project description
hcautomation
A Windows-focused automation toolkit for Enterprise Reporting downloads, Excel refresh/macro workflows, Outlook email automation, and DataFrame/file utilities.
Features
- Automates Enterprise Reporting exports with Selenium + Edge
- Supports direct export and filter-based export flows
- Includes typed filter configuration via
FilterSpec - Refreshes Excel workbooks and runs VBA macros through COM
- Sends Outlook emails with attachments
- Cleans and transforms pandas DataFrames
- Loads and validates Product List (PL) files
- Provides small file/date utility helpers
Installation
pip install hcautomation
Requirements
This package depends on both Python packages and local Windows applications.
Python dependencies
seleniumrsapandasnumpypywin32
System requirements
- Windows
- Microsoft Edge
- Compatible Edge WebDriver / Selenium setup
- Microsoft Excel
- Microsoft Outlook
Quick Start
Download a report directly
from hcautomation import ERDownloader
downloader = ERDownloader(download_dir=r"C:\Temp")
downloader.er(
bookmark_name="Daily Sales",
save_path=r"C:\Reports\daily_sales.csv"
)
Download a report with filters
from hcautomation import ERDownloader, FilterSpec
downloader = ERDownloader()
date_filter = FilterSpec(
filter_name="Date",
start_date="01/03/2026",
end_date="31/03/2026"
)
downloader.er(
bookmark_name="Daily Sales",
save_path=r"C:\Reports\daily_sales.xlsx",
filter_spec=date_filter
)
Use helper utilities
from hcautomation import Helpers
helpers = Helpers()
Exceptions
The package defines the following custom exceptions for Enterprise Reporting flows:
ERDownloaderErrorLoginTimeoutErrorBookmarkNotFoundErrorFilterNotFoundErrorDownloadTimeoutErrorConfirmationTimeoutError
API Reference
FilterSpec
Dataclass used to define filter inputs before applying them in Enterprise Reporting.
Signature
FilterSpec(
filter_name: str,
start_date: str | None = None,
end_date: str | None = None,
single_value_filter: str | None = None
)
Purpose
- Use
filter_name="Date"with bothstart_dateandend_date - Use
single_value_filterfor supported single-value filters such asTerritoryorLocation Code
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
filter_name |
Yes | str |
— | Name of the filter |
start_date |
Conditional | str | None |
None |
Required when filter_name == "Date" |
end_date |
Conditional | str | None |
None |
Required when filter_name == "Date" |
single_value_filter |
Conditional | str | None |
None |
Required for non-date single-value filters |
Example
date_filter = FilterSpec(
filter_name="Date",
start_date="01/03/2026",
end_date="31/03/2026"
)
territory_filter = FilterSpec(
filter_name="Territory",
single_value_filter="UAE"
)
ERDownloader
Automates Enterprise Reporting login, bookmark navigation, filtering, export, download detection, and final file movement.
ERDownloader(download_dir=None)
Initializes the downloader and loads encrypted credentials.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
download_dir |
No | str | Path | None |
User Downloads folder | Temporary download directory |
Example
downloader = ERDownloader(download_dir=r"C:\Reports\Temp")
er(bookmark_name, save_path, filter_spec=None, num_filters=10, user="Omkar", timeout=60)
Main public method that runs the full Enterprise Reporting export workflow.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
bookmark_name |
Yes | str |
— | Name of the bookmark/report |
save_path |
Yes | str | Path |
— | Final output path ending in .csv or .xlsx |
filter_spec |
No | FilterSpec | None |
None |
Filter Dictionary` |
num_filters |
No | int |
10 |
Number of filter rows to scan |
user |
No | str |
"Omkar" |
User folder name |
Example
from hcautomation import ERDownloader, FilterSpec
downloader = ERDownloader(download_dir=r"C:\Temp")
date_filter = FilterSpec(
filter_name="Date",
start_date="01/03/2026",
end_date="31/03/2026"
)
downloader.er(
bookmark_name="Daily Sales Report",
save_path=r"C:\Reports\daily_sales.csv",
filter_spec=date_filter,
num_filters=10,
user="Omkar",
timeout=60
)
Helpers
Collection of utility methods for dataframe cleanup, Excel COM automation, Outlook mail generation, PL file loading, and file/date checks.
Helpers()
Creates a helper instance.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
| None | — | — | — | No constructor parameters |
strip_chars_v3(df, column_names)
Removes non-numeric characters except - and . from selected columns, then converts them to float.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
df |
Yes | pd.DataFrame |
— | DataFrame to modify |
column_names |
Yes | iterable | — | Columns to clean |
Returns
- Cleaned
pd.DataFrame - Original dataframe copy if conversion fails
Example
helpers = Helpers()
df = helpers.strip_chars_v3(df, ["Sales", "Margin"])
call_macro(excel_file_path, macro_name)
Opens an Excel workbook, runs one or more VBA macros, saves, and closes it.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
excel_file_path |
Yes | str |
— | Workbook path |
macro_name |
Yes | iterable | — | Macro names to execute |
Returns
0if the workbook cannot be opened- Otherwise no explicit return value
Notes
This method references self.logger, so it expects a logger attribute to exist on the instance before use.
refresh_excel(excel_file_path)
Refreshes all workbook connections/queries and saves the workbook.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
excel_file_path |
Yes | str |
— | Workbook path |
Returns
0if the workbook cannot be opened- Otherwise no explicit return value
Notes
This method references self.logger, so it expects a logger attribute to exist on the instance before use.
refresh_excel_safe(excel_file_path)
Safer Excel refresh helper with explicit COM initialization and cleanup.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
excel_file_path |
Yes | str |
— | Workbook path |
send_mail(to_list, cc_list, subject, attachments=[], html_body='', body='', send_flag=False)
Creates an Outlook email, optionally attaches files, and either displays or sends it.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
to_list |
Yes | str |
— | To recipients |
cc_list |
Yes | str |
— | CC recipients |
subject |
Yes | str |
— | Email subject |
attachments |
No | list |
[] |
Attachment paths |
html_body |
No | str |
'' |
HTML body |
body |
No | str |
'' |
Plain text body |
send_flag |
No | bool |
False |
Send immediately if True, otherwise display draft |
Example
helpers.send_mail(
to_list="user@example.com",
cc_list="manager@example.com",
subject="Daily Report",
attachments=[r"C:\Reports\daily_sales.xlsx"],
body="Please find the report attached.",
send_flag=True
)
process_semantic_dumps(path, col_rename_map=None, sheet_name=None, skiprows=2, date_cols=(), numeric_cols=(), errors='raise')
Reads a semantic dump Excel file, normalizes columns, renames them, and applies optional date/numeric conversion.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
path |
Yes | str | pd.ExcelFile |
— | Excel file path or pd.ExcelFile object |
col_rename_map |
Yes | Mapping[str, str] | None |
None |
Column rename mapping |
sheet_name |
No | str | int | None |
None |
Sheet name or index |
skiprows |
No | int |
2 |
Number of rows to skip |
date_cols |
No | sequence | () |
Columns to convert to datetime |
numeric_cols |
No | sequence | () |
Columns to convert to numeric |
errors |
No | str |
'raise' |
Conversion error handling behavior |
Returns
- Processed
pd.DataFrame Noneif opening fails withPermissionError
Raises
ValueErrorKeyError
clean_exit(message="\nPress Ctrl+C to exit...")
Prints a message and blocks until the user stops the process with Ctrl+C.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
message |
No | str |
"\nPress Ctrl+C to exit..." |
Message shown before waiting |
fetch_pl_files(terr, omni_letter='O', pl_columns=('skuCode','concept'), col_rename_map=None, marketplace=False, dtype_dict=None, fetch_last_month=False)
Fetches the latest Product List file for a territory, with fallback to the previous month when needed.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
terr |
Yes | str |
— | Territory code: QAT, UAE, KWT, KSA, OMN, BAH, or EGP |
omni_letter |
No | str |
'O' |
Drive letter prefix |
pl_columns |
No | Sequence[str] |
('skuCode', 'concept') |
Columns to read from the CSV |
col_rename_map |
No | Mapping[str, str] | None |
None |
Optional rename mapping |
marketplace |
No | bool |
False |
Use marketplace PL path if True |
dtype_dict |
No | Mapping[str, str] | None |
None |
Optional dtype mapping for read_csv |
fetch_last_month |
No | bool |
False |
Force previous-month lookup |
Returns
(df, latest_pl_file)
Raises
ValueErrorFileNotFoundError
Example
df, file_path = helpers.fetch_pl_files(
terr="UAE",
marketplace=False,
pl_columns=("skuCode", "concept", "createdTime")
)
is_file_updated_today(file_path, raise_on_fail=True)
Checks whether a file exists and whether it was modified today.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
file_path |
Yes | str |
— | File path to check |
raise_on_fail |
No | bool |
True |
Raise instead of returning False on failure |
Returns
Trueif updated todayFalseif not updated today andraise_on_fail=False
Raises
FileNotFoundError
define_cust_type(df, cust_id='Customer ID')
Classifies each customer as New or Repeat by comparing transaction date and first transaction date.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
df |
Yes | pd.DataFrame |
— | Input dataframe |
cust_id |
No | str |
'Customer ID' |
Customer ID column name |
Returns
pd.DataFramewith anew_repeatcolumn
Raises
KeyErrorAssertionError
get_latest_file(path, typ='c')
Returns the latest file matching a glob pattern based on creation or modification time.
Arguments
| Argument | Required | Type | Default | Description |
|---|---|---|---|---|
path |
Yes | str | Path |
— | Glob pattern |
typ |
No | str |
'c' |
'c' for creation time, 'm' for modification time |
Returns
- Latest matching file path
Raises
ValueError
Example
latest = helpers.get_latest_file(r"C:\Reports\*.xlsx", typ="m")
Notes
- This package is Windows-specific for COM-based Excel and Outlook automation.
- Enterprise Reporting automation depends on the current ER UI structure and labels.
call_macro()andrefresh_excel()referenceself.logger, butHelpersdoes not create one internally.- Several helper methods are defined without a
selfparameter in the current code, which means they behave more like static utilities unless adjusted in the package implementation.
License
Add your project license here, for example:
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hcautomation-1.1.3.tar.gz.
File metadata
- Download URL: hcautomation-1.1.3.tar.gz
- Upload date:
- Size: 18.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
53364701bcce7f6b11a02674f80033ccd63b9ece5fb0e0daef1c6f886eb39b55
|
|
| MD5 |
b1966fb02ab2f729269d225f99b3a561
|
|
| BLAKE2b-256 |
52597028fbfc6a6a017068a58b21ca775f7829c157448761df283410a6451291
|
Provenance
The following attestation bundles were made for hcautomation-1.1.3.tar.gz:
Publisher:
release.yml on hsarode/hcautomation
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hcautomation-1.1.3.tar.gz -
Subject digest:
53364701bcce7f6b11a02674f80033ccd63b9ece5fb0e0daef1c6f886eb39b55 - Sigstore transparency entry: 1242589276
- Sigstore integration time:
-
Permalink:
hsarode/hcautomation@c12c444216cb9d8feac4243b1a3b71ab878f67c1 -
Branch / Tag:
refs/tags/v1.1.3 - Owner: https://github.com/hsarode
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c12c444216cb9d8feac4243b1a3b71ab878f67c1 -
Trigger Event:
push
-
Statement type:
File details
Details for the file hcautomation-1.1.3-py3-none-any.whl.
File metadata
- Download URL: hcautomation-1.1.3-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06fb1ab0c6e2d840818b055e1a38cef3d24a338a842b2ecf411f0122f96d71b7
|
|
| MD5 |
cadcd00418e5aa54bf0f748789d180a5
|
|
| BLAKE2b-256 |
1dc5cd413df9723e1fb93d40a36c91c83ad5692aa0bf7247ae9ad1733084b89e
|
Provenance
The following attestation bundles were made for hcautomation-1.1.3-py3-none-any.whl:
Publisher:
release.yml on hsarode/hcautomation
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hcautomation-1.1.3-py3-none-any.whl -
Subject digest:
06fb1ab0c6e2d840818b055e1a38cef3d24a338a842b2ecf411f0122f96d71b7 - Sigstore transparency entry: 1242589314
- Sigstore integration time:
-
Permalink:
hsarode/hcautomation@c12c444216cb9d8feac4243b1a3b71ab878f67c1 -
Branch / Tag:
refs/tags/v1.1.3 - Owner: https://github.com/hsarode
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@c12c444216cb9d8feac4243b1a3b71ab878f67c1 -
Trigger Event:
push
-
Statement type: