Python client library for the SAP Commerce HAC (Hybris Administration Console) HTTP API
Project description
hac-client-core
Python client library for the SAP Commerce HAC (Hybris Administration Console) HTTP API.
Execute Groovy scripts, run FlexibleSearch queries, import Impex data, and trigger system updates — all from Python, with automatic session management and CSRF handling.
Features
- Groovy script execution — run arbitrary Groovy in commit or rollback mode
- FlexibleSearch queries — execute queries with typed result objects
- Impex import — import Impex content with configurable validation
- System update — trigger updates, select patches/parameters, poll logs
- Session management — automatic login, CSRF tokens, session caching across runs
- Pluggable authentication — ships with Basic Auth; extend
AuthHandlerfor OAuth, JWT, API keys, etc. - Fully typed — complete type annotations with a
py.typedmarker (PEP 561)
Requirements
- Python ≥ 3.12
- A running SAP Commerce instance with HAC enabled
Installation
Install from PyPI (once published):
pip install hac-client-core
Or install directly from the repository:
pip install git+https://github.com/SapCommerceTools/ha-client-core.git
For development:
git clone https://github.com/SapCommerceTools/ha-client-core.git
cd hac-client-core
pip install -e ".[dev]"
Quick start
from hac_client_core import HacClient, BasicAuthHandler
# 1. Create an auth handler
auth = BasicAuthHandler("admin", "nimda")
# 2. Create the client
client = HacClient(
base_url="https://localhost:9002",
auth_handler=auth,
ignore_ssl=True, # skip certificate verification (dev only)
session_persistence=True, # cache sessions between runs
)
# 3. Login (or let it happen automatically on the first call)
client.login()
# 4. Execute a Groovy script
result = client.execute_groovy("return 'Hello from HAC'")
print(result.execution_result) # "Hello from HAC"
Usage
Groovy script execution
result = client.execute_groovy(
script="return de.hybris.platform.core.Registry.applicationContext",
commit=False, # rollback mode (default)
)
if result.success:
print(result.output_text) # stdout output
print(result.execution_result) # return value
else:
print(result.stacktrace_text) # error details
Set commit=True to execute in commit mode — changes will be persisted to the database.
FlexibleSearch queries
result = client.execute_flexiblesearch(
query="SELECT {pk}, {code} FROM {Product} WHERE {code} LIKE '%camera%'",
max_count=50,
locale="en",
)
if result.success:
print(f"Columns: {result.headers}")
print(f"Rows returned: {result.result_count}")
for row in result.rows:
print(row)
else:
print(f"Query error: {result.exception}")
Impex import
impex = """
INSERT_UPDATE Product; code[unique=true]; name[lang=en]
; testProduct001 ; Test Product
"""
result = client.import_impex(impex, validation_mode="import_strict")
if result.success:
print("Import completed")
else:
print(f"Import failed: {result.error}")
System update
# Fetch available extensions and their parameters
update_data = client.get_update_data()
for ext in update_data.extensions_with_parameters:
print(f"{ext.name}: {[p.name for p in ext.parameters]}")
# Execute an update with specific patches
result = client.execute_update(
patches={"Patch_MVP": "yes"},
create_essential_data=True,
create_project_data=True,
)
print(f"Success: {result.success}")
print(result.log_text)
Poll the update log while a long-running update is in progress:
import time
while True:
log = client.get_update_log()
print(log.log_text)
if log.is_complete:
break
time.sleep(5)
Session management
Sessions are cached to ~/.cache/hac-client/ by default so subsequent runs skip authentication:
# Sessions are cached per (base_url, username, environment) tuple
client = HacClient(
base_url="https://localhost:9002",
auth_handler=auth,
environment="local", # tag sessions by environment
session_persistence=True, # enable caching (default)
)
Manage the session cache directly:
from hac_client_core import SessionManager
mgr = SessionManager()
# List all cached sessions
for s in mgr.list_sessions():
print(f"{s.environment} {s.base_url} created={s.created_at_formatted}")
# Clear all sessions
mgr.clear_all_sessions()
Custom authentication
Implement AuthHandler to support any authentication scheme:
from hac_client_core import AuthHandler
import requests
class BearerTokenAuth(AuthHandler):
def __init__(self, token: str, username: str):
self._token = token
self._username = username
def apply_auth(self, request: requests.PreparedRequest) -> requests.PreparedRequest:
request.headers["Authorization"] = f"Bearer {self._token}"
return request
def get_initial_credentials(self) -> dict[str, str]:
return {"j_username": self._username, "j_password": self._token}
API reference
HacClient
| Parameter | Type | Default | Description |
|---|---|---|---|
base_url |
str |
— | HAC base URL (e.g. https://localhost:9002) |
auth_handler |
AuthHandler |
— | Authentication handler |
environment |
str |
"local" |
Environment name for session caching |
timeout |
int |
30 |
HTTP timeout in seconds |
ignore_ssl |
bool |
False |
Skip SSL certificate verification |
session_persistence |
bool |
True |
Cache sessions to disk |
quiet |
bool |
False |
Suppress informational messages on stderr |
Methods:
| Method | Returns | Description |
|---|---|---|
login() |
None |
Authenticate and establish a session |
execute_groovy(script, commit=False) |
GroovyScriptResult |
Execute a Groovy script |
execute_flexiblesearch(query, max_count=200, locale="en") |
FlexibleSearchResult |
Run a FlexibleSearch query |
import_impex(impex_content, validation_mode="import_strict") |
ImpexResult |
Import Impex data |
get_update_data() |
UpdateData |
Fetch available update extensions and parameters |
execute_update(...) |
UpdateResult |
Trigger a system update |
get_pending_patches() |
dict |
Fetch pending system patches |
get_update_log() |
UpdateLog |
Poll the current update log |
Result models
All result dataclasses are importable from hac_client_core:
| Model | Key fields |
|---|---|
GroovyScriptResult |
output_text, execution_result, stacktrace_text, success |
FlexibleSearchResult |
headers, rows, result_count, exception, success |
ImpexResult |
success, output, error |
UpdateData |
is_initializing, project_datas, extensions_with_parameters |
UpdateResult |
success, log_text, is_finished |
UpdateLog |
log_text, is_complete, has_errors |
Exceptions
| Exception | Description |
|---|---|
HacClientError |
Base exception for all client errors |
HacAuthenticationError |
Authentication or session errors |
Security considerations
- Credentials in memory —
BasicAuthHandlerclears its password reference on garbage collection. For stronger guarantees, implement a customAuthHandlerbacked by a secrets manager. - CSRF protection — the client automatically extracts and sends CSRF tokens on every request.
- Session cache — cached sessions are stored as JSON files in
~/.cache/hac-client/with filesystem permissions of the current user. The cache contains session IDs and CSRF tokens — not passwords. - SSL verification —
ignore_ssl=Truedisables certificate checks. Use it only for local development with self-signed certificates.
Development
# Install in editable mode with dev dependencies
pip install -e ".[dev]"
# Run tests
pytest
# Type checking
mypy src/
# Lint
ruff check src/
License
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 hac_client_core-0.1.0.tar.gz.
File metadata
- Download URL: hac_client_core-0.1.0.tar.gz
- Upload date:
- Size: 19.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7005b797c999d977a645d7e1f6dab7a0b518d3729ae2075a13caf79b6f7f2f41
|
|
| MD5 |
6d5c1ee814cd90eef519bc7a36ef8242
|
|
| BLAKE2b-256 |
bf8c07feb4a59cf21d8604eedcfa89371ac788f2c0f33036b27a1723dba992ef
|
Provenance
The following attestation bundles were made for hac_client_core-0.1.0.tar.gz:
Publisher:
release.yml on SapCommerceTools/hac-client-core
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hac_client_core-0.1.0.tar.gz -
Subject digest:
7005b797c999d977a645d7e1f6dab7a0b518d3729ae2075a13caf79b6f7f2f41 - Sigstore transparency entry: 927279141
- Sigstore integration time:
-
Permalink:
SapCommerceTools/hac-client-core@81c5f83a8dcc56cf086fe6791e1d11f15cfecaf5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/SapCommerceTools
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@81c5f83a8dcc56cf086fe6791e1d11f15cfecaf5 -
Trigger Event:
release
-
Statement type:
File details
Details for the file hac_client_core-0.1.0-py3-none-any.whl.
File metadata
- Download URL: hac_client_core-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.6 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 |
d30358d9e91d9475ef606a6b3e4167695c95b22e5bf8e05661782babafa0c21f
|
|
| MD5 |
1d02343fb52c42f3aac2f28bb76c37fc
|
|
| BLAKE2b-256 |
1ea4cab398a1ecab780b2b6a8ba4ad9a2899ac364aea1fb7b851ca6d26d6d4e0
|
Provenance
The following attestation bundles were made for hac_client_core-0.1.0-py3-none-any.whl:
Publisher:
release.yml on SapCommerceTools/hac-client-core
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hac_client_core-0.1.0-py3-none-any.whl -
Subject digest:
d30358d9e91d9475ef606a6b3e4167695c95b22e5bf8e05661782babafa0c21f - Sigstore transparency entry: 927279144
- Sigstore integration time:
-
Permalink:
SapCommerceTools/hac-client-core@81c5f83a8dcc56cf086fe6791e1d11f15cfecaf5 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/SapCommerceTools
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@81c5f83a8dcc56cf086fe6791e1d11f15cfecaf5 -
Trigger Event:
release
-
Statement type: