Skip to content
Draft
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: 6 additions & 2 deletions logfire/experimental/api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,15 +84,19 @@ class MyOutput:
"""Sentinel to distinguish 'not provided' from explicit None."""


_DATASET_NAME_RE = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9._-]*$')
# Mirrors the platform's `DatasetName` Pydantic type. Allows `/` as a namespace separator
# (e.g. `team-a/support-routing`) so datasets can be grouped by prefix in the Logfire UI; each
# `/`-delimited segment must start with a letter or digit (no leading, trailing, or repeated slashes).
_DATASET_NAME_RE = re.compile(r'^[a-zA-Z0-9][a-zA-Z0-9._-]*(/[a-zA-Z0-9][a-zA-Z0-9._-]*)*$')


def _validate_dataset_name(name: str) -> None:
"""Validate that a dataset name is URL-safe."""
if not _DATASET_NAME_RE.match(name):
raise ValueError(
f'Invalid dataset name {name!r}. '
'Names must start with a letter or digit and contain only letters, digits, dots, hyphens, and underscores.'
'Names must start with a letter or digit and contain only letters, digits, dots, hyphens, '
'underscores, and `/` (as a namespace separator, e.g. team-a/support-routing).'
)


Expand Down
10 changes: 9 additions & 1 deletion tests/test_datasets_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ def test_valid_names(self):
_validate_dataset_name('a')
_validate_dataset_name('123')
_validate_dataset_name('test_dataset-1.0')
# `/` is allowed as a namespace separator between well-formed segments.
_validate_dataset_name('team-a/support-routing')
_validate_dataset_name('team-a/rag/retrieval')

def test_invalid_names(self):
with pytest.raises(ValueError, match='Invalid dataset name'):
Expand All @@ -417,8 +420,13 @@ def test_invalid_names(self):
_validate_dataset_name('-starts-with-dash')
with pytest.raises(ValueError, match='Invalid dataset name'):
_validate_dataset_name('has spaces')
# A `/` must separate two well-formed segments: no leading, trailing, or repeated slashes.
with pytest.raises(ValueError, match='Invalid dataset name'):
_validate_dataset_name('special/chars')
_validate_dataset_name('/leading-slash')
with pytest.raises(ValueError, match='Invalid dataset name'):
_validate_dataset_name('trailing-slash/')
with pytest.raises(ValueError, match='Invalid dataset name'):
_validate_dataset_name('double//slash')


class TestPushDatasetHelpers:
Expand Down
Loading