Skip to main content

hank-format

Shared string formatting functions for standardizing names, dates, and times across the Hank AI stack.

pip install hank-format

Usage

from hank_format import as_name, as_date, as_date_str, as_datetime_str, as_time_str

as_name("Primary: John Doe")                       # 'DOE, JOHN'
as_name("Steven Hardman, APRN - CRNA")             # 'HARDMAN, STEVEN, APRN, CRNA'
as_date("12/31/2020 (age 30 yrs)")                 # datetime.date(2020, 12, 31)
as_date_str("01012024")                            # '2024-01-01'
as_datetime_str("2020-12-31T23:59")                # '2020-12-31 23:59:00'
as_datetime_str("23:59", precision="minute", default_date="2020-12-31")  # '2020-12-31 23:59'
as_time_str("11:30 pm")                            # '23:30'

API

Function Returns Notes
as_name(value) str LAST, FIRST MIDDLE, SUFFIX, upper case. Strips Label: prefixes, [notes], (notes), *, and text after ;.
is_date(value) bool True when a year, month, and day are present.
has_time(value) bool True when an hour and minute are present.
as_date(value) date | None Calendar date only.
as_date_str(value) str YYYY-MM-DD or "".
as_datetime(value, *, default_date=None) datetime | None Midnight when no time is present. Time-only input needs default_date.
as_datetime_str(value, *, precision="second", default_date=None) str YYYY-MM-DD HH:MM:SS, or YYYY-MM-DD HH:MM with precision="minute".
as_time(value) time | None Clock time only.
as_time_str(value, *, precision="minute") str HH:MM, or HH:MM:SS with precision="second".

Conventions:

  • Inputs may be strings, date, datetime, time, or None. Other types raise TypeError.
  • Object variants return None and string variants return "" when no usable value exists.
  • Returned values are timezone-naive and have no microseconds. precision truncates, never rounds.
  • Any parsed date more than two days in the future rolls back 100 years, including four-digit years and year-less MM/DD (12/31/45 is 1945; 12/26 without a time is 1926 when today is 2026-10-08). This is a two-digit-year heuristic inherited from pdf-extractor; strip or validate far-future dates before calling if you need them intact.
  • Year-less MM/DD HH:MM strings take the current year, or the previous year if that would be in the future.

Migrating from pdf-extractor utils

Legacy hank-format
as_name(s) as_name(s) (lists and vStr handling stay in pdf-extractor)
as_date(v, date_only=True, as_dt=True) as_date(v) (returns date)
as_date(v, date_only=True) as_date_str(v)
as_date(v, as_dt=True) as_datetime(v)
as_date(v) as_datetime_str(v)
as_time(v, with_date=False) as_time_str(v)
as_time(v, strict=True) as_datetime_str(v, precision="minute") if has_time(v) else ""
as_time(v, default_date=d) as_datetime_str(v, precision="minute", default_date=d) if has_time(v) else ""
as_time(v) as_datetime_str(v, precision="minute") if is_date(v) and has_time(v) else as_time_str(v)

Legacy as_time returned "" for anything without a time; the new datetime functions format a date-only value as midnight, hence the has_time guards.

Development

Requires uv.

uv sync                      # create .venv with Python 3.12 and the dev group
uv run pytest                # tests with 100% coverage enforced
uv run ruff check . && uv run ruff format --check .
uv run pyright
uv build                     # sdist + wheel into dist/

Releasing

  1. Open a PR against main and add exactly one label: release:patch, release:minor, or release:major.
  2. On merge, the Release workflow bumps __version__ in hank_format/__init__.py, runs the tests, builds, commits Release vX.Y.Z, tags it, and pushes. A separate publish job then uploads the built artifacts to PyPI.
  3. If only the publish job fails (for example, trusted publishing is not configured yet), fix the cause and re-run that failed job. Do not re-run the whole workflow: the version is already bumped and tagged, so a full re-run would bump it again.

One-time setup:

  • On pypi.org, under the hank-format project (or as a pending publisher), add a trusted publisher with owner hank-ai, repository hank-format, workflow release.yml, environment pypi.
  • In the GitHub repo settings, create an environment named pypi.
  • The workflow pushes the version-bump commit to main with the default GITHUB_TOKEN. If main is protected, allow the token to bypass the rule or supply a PAT in a RELEASE_TOKEN secret and use it in the checkout step.

Metadata

Release files for hank-format 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hank-format 0.1.0
File Size Uploaded
hank_format-0.1.0.tar.gz 8.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hank-format 0.1.0
File Interpreter ABI Platform
hank_format-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 17.7 kB

Release files / hank_format-0.1.0.tar.gz

Download URL hank_format-0.1.0.tar.gz
Size 8.3 kB
Tags Source
SHA-256 checksum
How to use checksums
1da86a1b56a0304249445f81236e695c24578d68a93387a32819daa2d4ed306d
BLAKE2b-256 checksum
How to use checksums
ef82609ee6d8cf9270e2dfbf46e294209a843fb2967f61e41780bbb2faac3f05
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release files / hank_format-0.1.0-py3-none-any.whl

Download URL hank_format-0.1.0-py3-none-any.whl
Size 9.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
47c74d0c52732edd503b05e900bb9dc2f48450781f45db51679cc0595cd219de
BLAKE2b-256 checksum
How to use checksums
20e2abea921c72095c0e0d80d27b6cd4e7c11f59e29133193fef49d5b65f4ffd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 9, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page