Verifying Sub-Package Releases

This guide covers how to validate the apache-hamilton-sdk, apache-hamilton-ui, apache-hamilton-lsp, and apache-hamilton-contrib packages before voting on a release.

For the core apache-hamilton package verification, see scripts/verification-script.sh.

Quick Start

# Set the versions being released
export SDK_VERSION=0.9.0
export UI_VERSION=0.0.18
export LSP_VERSION=0.2.0
export CONTRIB_VERSION=0.0.9
export HAMILTON_VERSION=1.90.0

apache-hamilton-sdk

Install and verify version

uv venv /tmp/verify-sdk --python 3.12
source /tmp/verify-sdk/bin/activate
uv pip install apache-hamilton apache-hamilton-sdk==${SDK_VERSION}

python -c "import hamilton_sdk; print(hamilton_sdk.__version__)"
# Expected: (0, 9, 0)

Run unit tests (from source)

cd ui/sdk
uv sync --group test
uv run pytest tests/ -q

Acceptance test: SDK tracks a run to UI server

Prerequisite: UI server running with a project created (see apache-hamilton-ui section below — run the “UI accepts data from SDK” test which creates a project and executes the full flow).

cd examples/hamilton_ui
uv pip install -r requirements.txt
uv run python run.py --username voter --project-id 1

This exercises the full SDK → UI pipeline: DAG template registration, node-level tracking, attribute collection, and run completion.

Example to run

See examples/hamilton_ui/ — the same example above.


apache-hamilton-ui

Building from source (requires Node.js + npm)

The UI package includes compiled frontend assets. When building from source, you must build the frontend first:

cd ui/frontend
npm install
npm run build

# Copy built assets to the backend package
rm -rf ../backend/hamilton_ui/build
cp -r dist/ ../backend/hamilton_ui/build/

# Now build the wheel
cd ../backend
uvx flit build --no-use-vcs

The release script (scripts/apache_release_helper.py --package ui) handles this automatically.

Install and verify

uv venv /tmp/verify-ui --python 3.12
source /tmp/verify-ui/bin/activate
uv pip install apache-hamilton-ui==${UI_VERSION}

Start server in mini mode (SQLite, no PostgreSQL needed)

export HAMILTON_BASE_DIR=/tmp/verify-hamilton-ui
mkdir -p $HAMILTON_BASE_DIR/blobs $HAMILTON_BASE_DIR/db

# Start the UI (opens browser, creates project via UI)
hamilton ui
# Or without opening browser:
# hamilton ui --no-open --port 8241

Health check

python -c "import urllib.request; print(urllib.request.urlopen('http://localhost:8241/api/ping').read())"
# Expected: b'ok'

Run build verification tests (from source)

cd ui/backend
uv run pytest tests/test_build.py -v

Acceptance test: UI serves frontend

python -c "
import urllib.request
resp = urllib.request.urlopen('http://localhost:8241/')
html = resp.read().decode()
assert '<div id=\"root\"' in html, 'Expected React root element in HTML'
print('UI frontend served successfully')
"

Acceptance test: UI accepts data from SDK

This is the key integration test — verifies the UI server can receive and store DAG tracking data sent by the SDK.

# Install SDK in the same venv
uv pip install apache-hamilton apache-hamilton-sdk==${SDK_VERSION} pandas

# Step 1: Open the UI in your browser and create a project.
# The `hamilton ui` command opens http://localhost:8241 automatically.
# Create a project and note its ID (shown in the URL, e.g. /dashboard/project/1).

# Step 2: Run the hamilton_ui example against the server
cd examples/hamilton_ui
uv pip install -r requirements.txt
python run.py --username <your_username> --project-id <project_id>
# Expected: "Captured execution run. Results can be found at ..."

# Step 3: Verify in the UI
# Navigate to http://localhost:8241/dashboard/project/<id>/runs
# You should see the DAG run with node-level details, attributes, etc.

This exercises the full SDK → UI pipeline: DAG template registration, node-level tracking, attribute collection, and run completion.


apache-hamilton-lsp

Install and verify version

uv venv /tmp/verify-lsp --python 3.12
source /tmp/verify-lsp/bin/activate
uv pip install "apache-hamilton[visualization]" apache-hamilton-lsp==${LSP_VERSION}

python -c "from hamilton_lsp import __version__; print(__version__)"
# Expected: 0.2.0

Run unit tests (from source)

cd dev_tools/language_server
uv pip install -e . pytest
uv run pytest tests/ -v

Acceptance test: LSP responds to initialize request

The LSP communicates over stdin/stdout using JSON-RPC. Send an initialize request and verify it responds with server capabilities:

python -c "
import subprocess, json, os

proc = subprocess.Popen(
    ['hamilton-lsp'],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
)

request = json.dumps({
    'jsonrpc': '2.0', 'id': 1, 'method': 'initialize',
    'params': {'capabilities': {}, 'rootUri': 'file:///tmp', 'processId': os.getpid()}
})
msg = f'Content-Length: {len(request)}\r\n\r\n{request}'
proc.stdin.write(msg.encode())
proc.stdin.flush()

# Read response headers until blank line
while True:
    line = proc.stdout.readline()
    if line.strip() == b'':
        break
    if b'Content-Length' in line:
        content_length = int(line.split(b':')[1].strip())

body = proc.stdout.read(content_length)
proc.kill()
proc.wait()

resp = json.loads(body)
caps = resp.get('result', {}).get('capabilities', {})
assert 'textDocumentSync' in caps, f'Missing capabilities, got: {list(caps.keys())}'
print(f'Capabilities: {list(caps.keys())}')
print('LSP responded to initialize request: PASSED')
"

apache-hamilton-contrib

Install and verify version

uv venv /tmp/verify-contrib --python 3.12
source /tmp/verify-contrib/bin/activate
uv pip install apache-hamilton apache-hamilton-contrib==${CONTRIB_VERSION}

python -c "import importlib.metadata; print(importlib.metadata.version('apache-hamilton-contrib'))"
# Expected: 0.0.9

Verify dataflow imports work

python -c "
from hamilton.contrib.user.zilto import xgboost_optuna
from hamilton import driver
import inspect

# Verify module has Hamilton functions
funcs = [n for n, f in inspect.getmembers(xgboost_optuna, inspect.isfunction)
         if not n.startswith('_')]
print(f'xgboost_optuna has {len(funcs)} functions')
assert len(funcs) > 0
print('Contrib dataflow import: OK')
"

Example to run

cd examples/contrib
uv pip install -r requirements.txt
uv run python run.py

This runs the xgboost_optuna contrib dataflow end-to-end (trains a model, tunes hyperparameters, saves results).


All packages together

Verify all 4 sub-packages install alongside core hamilton without conflicts:

uv venv /tmp/verify-all --python 3.12
source /tmp/verify-all/bin/activate
uv pip install apache-hamilton==${HAMILTON_VERSION} \
  apache-hamilton-sdk==${SDK_VERSION} \
  apache-hamilton-ui==${UI_VERSION} \
  apache-hamilton-lsp==${LSP_VERSION} \
  apache-hamilton-contrib==${CONTRIB_VERSION}

python -c "
import hamilton
import hamilton_sdk
import hamilton_ui
import hamilton_lsp
import importlib.metadata

print(f'hamilton:       {hamilton.version.VERSION}')
print(f'hamilton-sdk:   {hamilton_sdk.__version__}')
print(f'hamilton-lsp:   {hamilton_lsp.__version__}')
print(f'hamilton-contrib: {importlib.metadata.version(\"apache-hamilton-contrib\")}')
print('All packages coexist without conflicts')
"

Extras chain verification

Verify the apache-hamilton[sdk] extra correctly pulls in apache-hamilton-sdk:

uv venv /tmp/verify-extras --python 3.12
source /tmp/verify-extras/bin/activate
uv pip install "apache-hamilton[sdk,lsp]"

python -c "
import hamilton_sdk
import hamilton_lsp
print('Extras resolution: OK')
"

Redirect package verification (after upload)

Verify that old sf-hamilton-* package names redirect to the new names:

uv venv /tmp/verify-redirects --python 3.12
source /tmp/verify-redirects/bin/activate
uv pip install sf-hamilton-sdk sf-hamilton-ui sf-hamilton-lsp sf-hamilton-contrib

uv pip show apache-hamilton-sdk | grep Version
uv pip show apache-hamilton-ui | grep Version
uv pip show apache-hamilton-lsp | grep Version
uv pip show apache-hamilton-contrib | grep Version