Skip to main content

harborly

CI PyPI Python License

Port identity resolution, spatial search, and analytical sea routing.

harborly is a typed Python SDK and CLI. It resolves port identities, finds nearby ports, reviews ambiguous CSV matches, and calculates approximate sea-route distances in nautical miles.

[!IMPORTANT] Routes are analytical approximations on a maritime graph. They are not for navigation, voyage planning, or safety-critical use.

Features

  • Resolves registry IDs, UN/LOCODEs, and exact aliases.
  • Searches port names with exact, prefix, fuzzy, country, and proximity filters.
  • Matches CSV rows with human-review decision files.
  • Calculates sea routes and process-parallel distance matrices.
  • Streams large distance matrices without memory growth.
  • Serves port routing over a local FastAPI HTTP server.
  • Visualizes ports and routes in a terminal UI or standalone HTML maps.
  • Provides AsyncSeaRouter for async/await interface to route() and route_sequence().
  • Restricts passages like Suez, Panama, Kiel, Baban, and Northwest via PassageRestriction.
  • Computes multi-leg routes over a list of ports using route_sequence().
  • Calculates vessel speed and ETA directly on routes (speed_knots, duration_hours, duration_days).
  • Exports route data to KML format (--kml, --format kml).
  • Exports route data to GeoParquet format (--format geoparquet).

Installation

Install the core CLI with routing:

uv tool install 'harborly[routing]'

Install with all optional extras (routing, api, map, tui, fast, analysis):

uv tool install --force 'harborly[routing,api,map,tui,fast,analysis]'

For local development:

uv sync --dev --all-extras
uv run harborly info

Quick start

harborly search Mersin --country TR
harborly show TRMER
harborly near 39.87 26.16 --country TR --limit 5
harborly route TRMER GRPIR --geojson route.geojson --html-map route.html

Example output:

origin: Mersin (WPI:44860)
destination: Piraievs (WPI:42230)
distance_nmi: 594.46
great_circle_nmi: 528.19
detour_ratio: 1.125
quality_flag: ok
engine: searoute 1.6.0 (astar, networkx)

Python SDK

from harborly import PortRegistry, SeaRouter

registry = PortRegistry.bundled()
origin = registry.resolve("TRMER")
destination = registry.resolve("GRPIR")

router = SeaRouter(cache_path=".cache/harborly/routes.sqlite3")
route = router.route(origin, destination)
matrix = router.distance_matrix([origin, destination], max_workers=4)

print(f"Distance: {route.distance_nmi} nmi, status: {route.quality_flag}")
import asyncio
from harborly import AsyncSeaRouter, PassageRestriction, PortRegistry

async def async_example():
    registry = PortRegistry.bundled()
    mersin    = registry.resolve("TRMER")
    singapore = registry.resolve("SGSIN")
    jebel_ali = registry.resolve("AEJEA")

    # Restrictions are set on the router; route_sequence takes the port list
    router = AsyncSeaRouter(restrictions=[PassageRestriction.SUEZ])
    seq = await router.route_sequence([mersin, jebel_ali, singapore], speed_knots=15.0)
    print(f"Sequence distance: {seq.total_distance_nmi:.0f} nmi")
    print(f"Duration: {seq.duration_days:.1f} days ({seq.duration_hours:.0f} hours)")
    for i, leg in enumerate(seq.legs, 1):
        print(f"  Leg {i}: {leg.origin.name} → {leg.destination.name}: {leg.distance_nmi:.0f} nmi")

asyncio.run(async_example())

CLI Reference

Command Operation
info Inspect active registry statistics
search Search ports by name, country, or code
show Resolve a single port identity
near Find ports near coordinates
route Calculate a sea route between two ports
matrix Calculate a parallel distance matrix
cache Inspect, prune, or clear SQLite route cache
match Match CSV rows and generate review files
export Export port data as CSV, GeoJSON, KML, or GeoParquet
tui Launch terminal map interface
serve Run FastAPI HTTP service
data prepare Download and build local reference data

Exit codes

Exit code Meaning
0 Success
1 Data verification failed
2 Validation, resolution, or routing error
130 Interrupted (Ctrl-C)

HTTP Service

Run the local API server:

harborly serve --host 127.0.0.1 --port 8000
  • GET /v1/livez — liveness probe.
  • GET /v1/readyz — readiness probe.
  • GET /v1/route?origin=TRMER&destination=GRPIR — calculate route.

Documentation Index

License

MIT License. See LICENSE for details.

Metadata

Release files for harborly 1.1.4

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

Source distribution (sdist)

Source distribution for harborly 1.1.4
File Size Uploaded
harborly-1.1.4.tar.gz 2.0 MB Details

Built distribution (wheel)

Table of built distributions (wheels) for harborly 1.1.4
File Interpreter ABI Platform
harborly-1.1.4-py3-none-any.whl Python 3 none any Details

Total release size: 3.9 MB

Release files / harborly-1.1.4.tar.gz

Download URL harborly-1.1.4.tar.gz
Size 2.0 MB
Tags Source
SHA-256 checksum
How to use checksums
2b737bf6e7db5ae404ccf72dfe1285188727722d44c330be05551326a240f136
BLAKE2b-256 checksum
How to use checksums
a4f29b59b4a07d030ee1639b376c77d78ffc7ccebdb14aae7622a3b75df0dc87
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 Aug 9, 2026.

Transparency log

Release files / harborly-1.1.4-py3-none-any.whl

Download URL harborly-1.1.4-py3-none-any.whl
Size 1.9 MB
Tags Python 3
SHA-256 checksum
How to use checksums
3e3badb9f98118bbf7b11eb4d8593631e21f46c1773e45bb14b8ca275e9c9f64
BLAKE2b-256 checksum
How to use checksums
9d60bc5befa0a5a060073c82c0028febcc3367836dc94e72b24478da76759739
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 Aug 9, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.4 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