Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 1 addition & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,12 @@
<img src="https://static.pepy.tech/badge/sf-hamilton/month" alt="Total Monthly Downloads"/>
</a>
<br/>
<a target="_blank" href="https://linkedin.com/showcase/dagster" style="background:none">
<img src="https://img.shields.io/badge/DAGWorks-Follow-purple.svg?logo=linkedin" />
</a>
<a href="https://join.slack.com/t/hamilton-opensource/shared_invite/zt-2niepkra8-DGKGf_tTYhXuJWBTXtIs4g" target="_blank">
<img src="https://img.shields.io/badge/Apache Hamilton-Join-purple.svg?logo=slack" alt="Apache Hamilton Slack"/>
</a>
<a href="https://twitter.com/hamilton_os" target="_blank">
<img src="https://img.shields.io/badge/HamiltonOS-Follow-purple.svg?logo=X"/>
</a>
<a href="https://twitter.com/dagworks" target="_blank">
<img src="https://img.shields.io/badge/DAGWorks-Follow-purple.svg?logo=X"/>
</a>
</div>
<br></br>

Expand Down Expand Up @@ -255,7 +249,7 @@ Apache Hamilton was started at Stitch Fix before the original creators founded D
* [wren.ai](https://wren.ai/)

## 🤝 Code Contributors
[![Contributors](https://contrib.rocks/image?repo=dagworks-inc/hamilton)](https://github.com/apache/hamilton/graphs/contributors)
[![Contributors](https://contrib.rocks/image?repo=apache/hamilton)](https://github.com/apache/hamilton/graphs/contributors)


## 🙌 Special Mentions & 🦟 Bug Hunters
Expand Down
57 changes: 57 additions & 0 deletions docs/asf/downloads.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
================
Downloads
================

Official Apache Hamilton releases are available at the Apache Software Foundation distribution site.

Release Downloads
-----------------

All releases can be found at: `https://downloads.apache.org/incubator/hamilton/ <https://downloads.apache.org/incubator/hamilton/>`_

Each release includes:

- Source distributions (.tar.gz, .zip)
- Checksums (SHA512)
- Digital signatures (.asc)

Verifying Releases
------------------

To verify the integrity of downloaded files, you can:

1. Verify the checksum matches the published SHA512 sum
2. Verify the GPG signature using the KEYS file available at the downloads site

Release History
---------------

Visit the `downloads directory <https://downloads.apache.org/incubator/hamilton/>`_ to see all available releases.

Installation
------------

After downloading and verifying a release, you can install it using pip:

.. code-block:: bash

pip install apache-hamilton-<version>.tar.gz

Or install directly from PyPI:

.. code-block:: bash

pip install apache-hamilton

For more information about installation options, see the :doc:`Get Started guide </get-started/index>`.

Official Releases
-----------------

The following are the official Apache Hamilton releases:

- **1.89.0** (2025-10-11) - First Apache Hamilton release

- `Source (tar.gz) <https://downloads.apache.org/incubator/hamilton/1.89.0/apache-hamilton-1.89.0-incubating.tar.gz>`_
- `Checksums <https://downloads.apache.org/incubator/hamilton/1.89.0/apache-hamilton-1.89.0-incubating.tar.gz.sha512>`_
- `Signature <https://downloads.apache.org/incubator/hamilton/1.89.0/apache-hamilton-1.89.0-incubating.tar.gz.asc>`_
2 changes: 2 additions & 0 deletions docs/asf/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Apache Software Foundation links.
:glob:
:hidden:

downloads
Apache Software Foundation <https://www.apache.org/>
License <https://www.apache.org/licenses/>
Events <https://www.apache.org/events/current-event.html>
Expand All @@ -19,6 +20,7 @@ Apache Software Foundation links.
Thanks <https://www.apache.org/foundation/thanks.html>
Code of Conduct <https://www.apache.org/foundation/policies/conduct.html>

- :doc:`Downloads <downloads>`
- `Foundation <https://www.apache.org/>`_
- `License <https://www.apache.org/licenses/>`_
- `Events <https://www.apache.org/events/current-event.html>`_
Expand Down
7 changes: 7 additions & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ integrations/index
code-comparisons/index
```

```{toctree}
:hidden: True
:caption: DOWNLOADS

asf/downloads
```

```{toctree}
:hidden: True
:caption: PDF
Expand Down
20 changes: 18 additions & 2 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,27 @@ requires = ["flit_core >=3.11,<4"]
build-backend = "flit_core.buildapi"

[project]
name = "sf-hamilton"
name = "apache-hamilton"
version = "1.89.0" # NOTE: keep this in sync with hamilton/version.py
# TODO: flip back to dynamic once hamilton version is a string. Flit doesn't handle tuples.
# dynamic = ["version"]
description = "Hamilton, the micro-framework for creating dataframes."
description = """Apache Hamilton (incubating) is a lightweight Python library for directed acyclic graphs (DAGs)
of transformations. Your DAG is **portable**; it runs anywhere Python runs, whether it's a script,
notebook, Airflow pipeline, FastAPI server, etc. Your DAG is **expressive**; Apache Hamilton has extensive
features to define and modify the execution of a DAG (e.g., data validation, experiment tracking, remote
execution).

Apache Hamilton (incubating) is an effort undergoing incubation at the Apache
Software Foundation (ASF), sponsored by the Apache Incubator PMC.

Incubation is required of all newly accepted projects until a further review
indicates that the infrastructure, communications, and decision making process
have stabilized in a manner consistent with other successful ASF projects.

While incubation status is not necessarily a reflection of the completeness
or stability of the code, it does indicate that the project has yet to be
fully endorsed by the ASF.
"""
readme = "README.md"
requires-python = ">=3.8.1, <4"
license = {text = "Apache-2.0"}
Expand Down
113 changes: 97 additions & 16 deletions scripts/apache_release_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@
import shutil
import subprocess
import sys
import tarfile
import tempfile
import zipfile
from typing import Optional

# --- Configuration ---
Expand Down Expand Up @@ -139,10 +142,96 @@ def sign_artifacts(archive_name: str) -> Optional[list[str]]:
return files


def _modify_wheel_for_apache_release(original_wheel: str, new_wheel_path: str):
"""Helper to modify the wheel for apache release.

# Flit somehow builds something incorrectly.
# 1. change PKG-INFO's first line to be `Metadata-Version: 2.4`
# 2. make sure the second line is `Name: apache-hamilton`
# 3. remove the `Import-Name: hamilton` line from PKG-INFO.

:param original_wheel: Path to the original wheel.
:param new_wheel_path: Path to the new wheel to create.
"""
with tempfile.TemporaryDirectory() as tmpdir:
# Unzip the wheel
with zipfile.ZipFile(original_wheel, "r") as zip_ref:
zip_ref.extractall(tmpdir)

# Find the .dist-info directory
dist_info_dirs = glob.glob(os.path.join(tmpdir, "*.dist-info"))
if not dist_info_dirs:
raise ValueError(f"Could not find .dist-info directory in {original_wheel}")
dist_info_dir = dist_info_dirs[0]
pkg_info = os.path.join(dist_info_dir, "PKG-INFO")

_modify_pkg_info_file(pkg_info)

# Create the new wheel
with zipfile.ZipFile(new_wheel_path, "w", zipfile.ZIP_DEFLATED) as zip_ref:
for root, _, files in os.walk(tmpdir):
for file in files:
zip_ref.write(
os.path.join(root, file), os.path.relpath(os.path.join(root, file), tmpdir)
)


def _modify_pkg_info_file(pkg_info_path: str):
"""
Flit somehow builds something incorrectly.
1. change PKG-INFO's first line to be `Metadata-Version: 2.4`
2. make sure the second line is `Name: apache-hamilton`
3. remove the `Import-Name: hamilton` line from PKG-INFO.
"""
with open(pkg_info_path, "r") as f:
lines = f.readlines()

new_lines = []
for i, line in enumerate(lines):
if i == 0:
new_lines.append("Metadata-Version: 2.4\n")
elif i == 1:
new_lines.append("Name: apache-hamilton\n")
elif line.strip() == "Import-Name: hamilton":
continue # Skip this line
else:
new_lines.append(line)

with open(pkg_info_path, "w") as f:
f.writelines(new_lines)


def _modify_tarball_for_apache_release(original_tarball: str, new_tarball_path: str):
"""Helper to modify the tarball for apache release.

# Flit somehow builds something incorrectly.
# 1. change PKG-INFO's first line to be `Metadata-Version: 2.4`
# 2. make sure the second line is `Name: apache-hamilton`
# 3. remove the `Import-Name: hamilton` line from PKG-INFO.

:param original_tarball: Path to the original tarball.
:param new_tarball_path: Path to the new tarball to create.
"""
with tempfile.TemporaryDirectory() as tmpdir:
# Extract the tarball
with tarfile.open(original_tarball, "r:gz") as tar:
tar.extractall(path=tmpdir)

# Modify the PKG-INFO file
# The extracted tarball has a single directory inside.
extracted_dir = os.path.join(tmpdir, os.listdir(tmpdir)[0])
pkg_info_path = os.path.join(extracted_dir, "PKG-INFO")

_modify_pkg_info_file(pkg_info_path)

# Create the new tarball
with tarfile.open(new_tarball_path, "w:gz") as tar:
tar.add(extracted_dir, arcname=os.path.basename(extracted_dir))


def create_release_artifacts(version) -> list[str]:
"""Creates the source tarball, GPG signature, and checksums using `python -m build`."""
print("Creating release artifacts with 'python -m build'...")
files_to_upload = []
print("Creating release artifacts with 'flit build'...")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we remove the print and use echo in the .sh script instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤷

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is closer to the code -- so no difference?

# Clean the dist directory before building.
if os.path.exists("dist"):
shutil.rmtree("dist")
Expand All @@ -162,8 +251,7 @@ def create_release_artifacts(version) -> list[str]:
return None

# Find the created tarball in the dist directory.
expected_tar_ball = f"dist/sf_hamilton-{version.lower()}.tar.gz"
files_to_upload.append(expected_tar_ball)
expected_tar_ball = f"dist/apache-hamilton-{version.lower()}.tar.gz"
tarball_path = glob.glob(expected_tar_ball)

if not tarball_path:
Expand All @@ -180,29 +268,22 @@ def create_release_artifacts(version) -> list[str]:

# copy the tarball to be apache-hamilton-{version.lower()}-incubating.tar.gz
new_tar_ball = f"dist/apache-hamilton-{version.lower()}-incubating.tar.gz"
shutil.copy(tarball_path[0], new_tar_ball)
_modify_tarball_for_apache_release(tarball_path[0], new_tar_ball)
archive_name = new_tar_ball
print(f"Found source tarball: {archive_name}")
main_signed_files = sign_artifacts(archive_name)
if main_signed_files is None:
new_tar_ball_singed = sign_artifacts(archive_name)
if new_tar_ball_singed is None:
raise ValueError("Could not sign the main release artifacts.")
# create sf-hamilton release artifacts
sf_hamilton_signed_files = sign_artifacts(expected_tar_ball)
# create wheel release artifacts
expected_wheel = f"dist/sf_hamilton-{version.lower()}-py3-none-any.whl"
expected_wheel = f"dist/apache-hamilton-{version.lower()}-py3-none-any.whl"
wheel_path = glob.glob(expected_wheel)
wheel_signed_files = sign_artifacts(wheel_path[0])
# create incubator wheel release artifacts
expected_incubator_wheel = f"dist/apache-hamilton-{version.lower()}-incubating-py3-none-any.whl"
shutil.copy(wheel_path[0], expected_incubator_wheel)
incubator_wheel_signed_files = sign_artifacts(expected_incubator_wheel)
files_to_upload = (
[new_tar_ball]
+ main_signed_files
+ [expected_tar_ball]
+ sf_hamilton_signed_files
+ [expected_wheel]
+ wheel_signed_files
+ new_tar_ball_singed
+ [expected_incubator_wheel]
+ incubator_wheel_signed_files
)
Expand Down
Loading
Loading