hub-core/hub_core/utils/slugs.py
tegwick 118d4fdcfe
Some checks failed
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / pytest-smoke (push) Failing after 2s
feat(ecosystem): hub-core library lane for three-repo stack (HUB-WP-0003)
Add slugify_or_default for core-hub parity, bump to 0.2.0, document ecosystem
position in INTENT/SCOPE/README, wire capability relations to state-hub and
core-hub, and extend utils tests. Part of CUST-WP-0057 consolidation.
2026-07-11 01:26:47 +02:00

30 lines
811 B
Python

import re
_NON_SLUG = re.compile(r"[^a-z0-9]+")
_DASHES = re.compile(r"-+")
def slugify(value: str, *, max_length: int = 100) -> str:
slug = _NON_SLUG.sub("-", value.strip().lower())
slug = _DASHES.sub("-", slug).strip("-")
if not slug:
raise ValueError("slug cannot be empty")
if max_length < 1:
raise ValueError("max_length must be >= 1")
return slug[:max_length].strip("-")
def slugify_or_default(
value: str,
*,
default: str = "resource",
max_length: int = 100,
) -> str:
"""Like slugify but returns default when input yields no slug characters.
Matches core-hub bootstrap semantics where API consumers need a fallback slug.
"""
try:
return slugify(value, max_length=max_length)
except ValueError:
return default