Python library for converting between HEN and SGF formats.
HEN (Hemme Notation) is a lightweight, text-based format designed for efficiently encoding and sharing Go board positions.
The formal grammar is defined in hen-spec (EBNF, MIT license).
SGF (Smart Game Format) is the established standard supported by most Go software. This library bridges the two formats, letting you integrate HEN into existing SGF-based workflows.
You can install the package via pip:
pip install git+https://github.com/hemme/hen-python.gitRequires Python 3.7 or later. No external dependencies.
from hen.hen import sgf2hen
sgf = "(;GM[1]FF[4]SZ[19];B[pd];W[dd];B[qp];W[dp])"
# Converts the SGF string directly to HEN
hen_string = sgf2hen(sgf)
print(hen_string)from hen.hen import Hen
hen_string = ".9x9_7Dw_6Gb_5Eb_4Eb_3Dw2.D7w.b"
hen_obj = Hen()
hen_obj.parse(hen_string)
sgf = hen_obj.to_sgf()
print(sgf)The Hen object can also be constructed by reading HEN metadata embedded within a PNG file's tEXt chunk:
import urllib.request
from hen.hen import Hen
url = "https://wrk.goshawk.cc/c/hen.9x9_7Dwb_6Gb_5Eb_4Eb_3Dw2.E7b.w/position.png"
opener = urllib.request.build_opener()
opener.addheaders = [("User-Agent", "Mozilla/5.0")]
urllib.request.install_opener(opener)
path, _ = urllib.request.urlretrieve(url)
hen_obj = Hen.from_png(path)
print(hen_obj.to_hen()) # .9x9_7Dwb_6Gb_5Eb_4Eb_3Dw2.E7b.wUse embed to write the current board state as a tEXt chunk into a PNG:
from io import BytesIO
from hen.hen import Hen
hen_obj = Hen()
hen_obj.parse(".9x9_7Dwb_6Gb_5Eb_4Eb_3Dw2.E7b.w")
with open("board.png", "rb") as f:
png_data = BytesIO(f.read())
output = BytesIO()
hen_obj.embed(png_data, output)
output.seek(0)
with open("board_with_hen.png", "wb") as f:
f.write(output.read())The core class representing a HEN game position / board state.
-
parse(self, hen_string: str)Parses a HEN string and populates the board state. -
to_sgf(self) -> strConverts the current board state to an SGF string. -
to_hen(self) -> strConverts the current board state to a HEN string. -
from_sgf(self, sgf_string: str, move_num: int = -1)Parses an SGF string and populates the board state up tomove_num. Ifmove_numis-1, it parses the entire main branch. -
from_png(cls, source: Union[str, BytesIO, BufferedReader]) -> 'Hen'Class method that reads a PNG file (from a path,BytesIO, or file object) and returns aHenobject from its embeddedHENmetadata text chunk. -
embed(self, source: Union[str, BytesIO, BufferedReader], output: Union[str, BytesIO])Reads a PNG, inserts or replaces thetEXtchunk with keywordHENcontaining the current board state, and writes the result tooutput(a file path orBytesIO).
A helper function that converts a complete SGF string to its HEN representation.
| Parameter | Type | Description |
|---|---|---|
sgf_string |
str |
Valid SGF content |
move_num |
int |
The specific move number to stop at (default: -1 for end of main branch) |
Returns a str containing the HEN output.
This library targets the HEN grammar as defined in hen-spec. Currently, only black (b) and white (w) stones are supported; multi-color stones (r, g, l, y, p) are not yet implemented. The conformance test suite from that repository is run on every release.
SGF versions FF[3] and FF[4] are supported for Go (GM[1]). Other game types and SGF properties not directly related to the board position (e.g., comments, game info, side variations) are currently not preserved during conversion.
Bug reports and pull requests are welcome. Before opening a PR:
- Run the test suite:
python3 -m unittest discover -s tests -p '*_tests.py' - Check that your changes pass all existing tests
- Follow the existing code style.
| Project | Description |
|---|---|
| hen-spec | Formal grammar (EBNF) |
MIT — see LICENSE.