Skip to content

Commit 2ef7086

Browse files
authored
hotfix: Live run/task errors (#108)
* Error to warnings conversions to avoid exceptions when calls are made outside tasks/runs * Version to 1.11.1
1 parent bc01b8e commit 2ef7086

4 files changed

Lines changed: 107 additions & 37 deletions

File tree

docs/sdk/main.mdx

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,11 @@ def link_objects(
559559
attributes: Additional attributes to attach to the link.
560560
"""
561561
if (run := current_run_span.get()) is None:
562-
raise RuntimeError("link() must be called within a run")
562+
warn_at_user_stacklevel(
563+
"link_objects() was called outside of a run.",
564+
category=DreadnodeUsageWarning,
565+
)
566+
return
563567

564568
origin_hash = run.log_object(origin)
565569
link_hash = run.log_object(link)
@@ -652,7 +656,11 @@ def log_artifact(
652656
local_uri: The local path to the file to upload.
653657
"""
654658
if (run := current_run_span.get()) is None:
655-
raise RuntimeError("log_artifact() must be called within a run")
659+
warn_at_user_stacklevel(
660+
"log_artifact() was called outside of a run.",
661+
category=DreadnodeUsageWarning,
662+
)
663+
return
656664

657665
run.log_artifact(local_uri=local_uri)
658666
```
@@ -729,7 +737,11 @@ def log_input(
729737

730738
target = (task or run) if to == "task-or-run" else run
731739
if target is None:
732-
raise RuntimeError("log_inputs() must be called within a run")
740+
warn_at_user_stacklevel(
741+
"log_input() was called outside of a task or run.",
742+
category=DreadnodeUsageWarning,
743+
)
744+
return
733745

734746
target.log_input(name, value, label=label, attributes=attributes)
735747
```
@@ -946,13 +958,6 @@ def log_metric(
946958
Returns:
947959
The logged metric object.
948960
"""
949-
task = current_task_span.get()
950-
run = current_run_span.get()
951-
952-
target = (task or run) if to == "task-or-run" else run
953-
if target is None:
954-
raise RuntimeError("log_metric() must be called within a run")
955-
956961
metric = (
957962
value
958963
if isinstance(value, Metric)
@@ -963,6 +968,18 @@ def log_metric(
963968
attributes or {},
964969
)
965970
)
971+
972+
task = current_task_span.get()
973+
run = current_run_span.get()
974+
975+
target = (task or run) if to == "task-or-run" else run
976+
if target is None:
977+
warn_at_user_stacklevel(
978+
"log_metric() was called outside of a task or run.",
979+
category=DreadnodeUsageWarning,
980+
)
981+
return metric
982+
966983
return target.log_metric(name, metric, origin=origin, mode=mode)
967984
```
968985

@@ -1133,7 +1150,11 @@ def log_metrics(
11331150

11341151
target = (task or run) if to == "task-or-run" else run
11351152
if target is None:
1136-
raise RuntimeError("log_metrics() must be called within a run")
1153+
warn_at_user_stacklevel(
1154+
"log_metrics() was called outside of a task or run.",
1155+
category=DreadnodeUsageWarning,
1156+
)
1157+
return []
11371158

11381159
logged_metrics: list[Metric] = []
11391160

@@ -1276,9 +1297,11 @@ def log_output(
12761297

12771298
target = (task or run) if to == "task-or-run" else run
12781299
if target is None:
1279-
raise RuntimeError(
1280-
"log_output() must be called within a run or a task",
1300+
warn_at_user_stacklevel(
1301+
"log_output() was called outside of a task or run.",
1302+
category=DreadnodeUsageWarning,
12811303
)
1304+
return
12821305

12831306
target.log_output(name, value, label=label, attributes=attributes)
12841307
```
@@ -1431,7 +1454,12 @@ def log_params(self, **params: JsonValue) -> None:
14311454
**params: The parameters to log. Each parameter is a key-value pair.
14321455
"""
14331456
if (run := current_run_span.get()) is None:
1434-
raise RuntimeError("Parameters must be logged within a run")
1457+
warn_at_user_stacklevel(
1458+
"log_params() was called outside of a run.",
1459+
category=DreadnodeUsageWarning,
1460+
)
1461+
return
1462+
14351463
run.log_params(**params)
14361464
```
14371465

@@ -1484,7 +1512,11 @@ def push_update(self) -> None:
14841512
# do more work
14851513
"""
14861514
if (run := current_run_span.get()) is None:
1487-
raise RuntimeError("Run updates must be pushed within a run")
1515+
warn_at_user_stacklevel(
1516+
"push_update() was called outside of a run.",
1517+
category=DreadnodeUsageWarning,
1518+
)
1519+
return
14881520

14891521
run.push_update(force=True)
14901522
```
@@ -1910,7 +1942,11 @@ def tag(self, *tag: str, to: ToObject = "task-or-run") -> None:
19101942

19111943
target = (task or run) if to == "task-or-run" else run
19121944
if target is None:
1913-
raise RuntimeError("Tagging must be done within a run")
1945+
warn_at_user_stacklevel(
1946+
"tag() was called outside of a task or run.",
1947+
category=DreadnodeUsageWarning,
1948+
)
1949+
return
19141950

19151951
target.add_tags(tag)
19161952
```

dreadnode/main.py

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,11 @@ def tag(self, *tag: str, to: ToObject = "task-or-run") -> None:
860860

861861
target = (task or run) if to == "task-or-run" else run
862862
if target is None:
863-
raise RuntimeError("Tagging must be done within a run")
863+
warn_at_user_stacklevel(
864+
"tag() was called outside of a task or run.",
865+
category=DreadnodeUsageWarning,
866+
)
867+
return
864868

865869
target.add_tags(tag)
866870

@@ -883,7 +887,11 @@ def push_update(self) -> None:
883887
# do more work
884888
"""
885889
if (run := current_run_span.get()) is None:
886-
raise RuntimeError("Run updates must be pushed within a run")
890+
warn_at_user_stacklevel(
891+
"push_update() was called outside of a run.",
892+
category=DreadnodeUsageWarning,
893+
)
894+
return
887895

888896
run.push_update(force=True)
889897

@@ -934,7 +942,12 @@ def log_params(self, **params: JsonValue) -> None:
934942
**params: The parameters to log. Each parameter is a key-value pair.
935943
"""
936944
if (run := current_run_span.get()) is None:
937-
raise RuntimeError("Parameters must be logged within a run")
945+
warn_at_user_stacklevel(
946+
"log_params() was called outside of a run.",
947+
category=DreadnodeUsageWarning,
948+
)
949+
return
950+
938951
run.log_params(**params)
939952

940953
@t.overload
@@ -1085,13 +1098,6 @@ def log_metric(
10851098
Returns:
10861099
The logged metric object.
10871100
"""
1088-
task = current_task_span.get()
1089-
run = current_run_span.get()
1090-
1091-
target = (task or run) if to == "task-or-run" else run
1092-
if target is None:
1093-
raise RuntimeError("log_metric() must be called within a run")
1094-
10951101
metric = (
10961102
value
10971103
if isinstance(value, Metric)
@@ -1102,6 +1108,18 @@ def log_metric(
11021108
attributes or {},
11031109
)
11041110
)
1111+
1112+
task = current_task_span.get()
1113+
run = current_run_span.get()
1114+
1115+
target = (task or run) if to == "task-or-run" else run
1116+
if target is None:
1117+
warn_at_user_stacklevel(
1118+
"log_metric() was called outside of a task or run.",
1119+
category=DreadnodeUsageWarning,
1120+
)
1121+
return metric
1122+
11051123
return target.log_metric(name, metric, origin=origin, mode=mode)
11061124

11071125
@t.overload
@@ -1240,7 +1258,11 @@ def log_metrics(
12401258

12411259
target = (task or run) if to == "task-or-run" else run
12421260
if target is None:
1243-
raise RuntimeError("log_metrics() must be called within a run")
1261+
warn_at_user_stacklevel(
1262+
"log_metrics() was called outside of a task or run.",
1263+
category=DreadnodeUsageWarning,
1264+
)
1265+
return []
12441266

12451267
logged_metrics: list[Metric] = []
12461268

@@ -1312,7 +1334,11 @@ def log_artifact(
13121334
local_uri: The local path to the file to upload.
13131335
"""
13141336
if (run := current_run_span.get()) is None:
1315-
raise RuntimeError("log_artifact() must be called within a run")
1337+
warn_at_user_stacklevel(
1338+
"log_artifact() was called outside of a run.",
1339+
category=DreadnodeUsageWarning,
1340+
)
1341+
return
13161342

13171343
run.log_artifact(local_uri=local_uri)
13181344

@@ -1350,7 +1376,11 @@ async def my_task(x: int) -> int:
13501376

13511377
target = (task or run) if to == "task-or-run" else run
13521378
if target is None:
1353-
raise RuntimeError("log_inputs() must be called within a run")
1379+
warn_at_user_stacklevel(
1380+
"log_input() was called outside of a task or run.",
1381+
category=DreadnodeUsageWarning,
1382+
)
1383+
return
13541384

13551385
target.log_input(name, value, label=label, attributes=attributes)
13561386

@@ -1412,9 +1442,11 @@ async def my_task(x: int) -> int:
14121442

14131443
target = (task or run) if to == "task-or-run" else run
14141444
if target is None:
1415-
raise RuntimeError(
1416-
"log_output() must be called within a run or a task",
1445+
warn_at_user_stacklevel(
1446+
"log_output() was called outside of a task or run.",
1447+
category=DreadnodeUsageWarning,
14171448
)
1449+
return
14181450

14191451
target.log_output(name, value, label=label, attributes=attributes)
14201452

@@ -1461,7 +1493,11 @@ def link_objects(
14611493
attributes: Additional attributes to attach to the link.
14621494
"""
14631495
if (run := current_run_span.get()) is None:
1464-
raise RuntimeError("link() must be called within a run")
1496+
warn_at_user_stacklevel(
1497+
"link_objects() was called outside of a run.",
1498+
category=DreadnodeUsageWarning,
1499+
)
1500+
return
14651501

14661502
origin_hash = run.log_object(origin)
14671503
link_hash = run.log_object(link)

dreadnode/tracing/span.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -879,14 +879,12 @@ def __init__(
879879

880880
def __enter__(self) -> te.Self:
881881
self._run = current_run_span.get()
882-
if self._run is None:
883-
raise RuntimeError("You cannot start a task span without a run")
884882

885883
self._parent_task = current_task_span.get()
886884
if self._parent_task is not None:
887885
self.set_attribute(SPAN_ATTRIBUTE_PARENT_TASK_ID, self._parent_task.span_id)
888886
self._parent_task._tasks.append(self) # noqa: SLF001
889-
else:
887+
elif self._run:
890888
self._run._tasks.append(self) # noqa: SLF001
891889

892890
self._context_token = current_task_span.set(self)

pyproject.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
[project]
22
name = "dreadnode"
3-
version = "1.11.0"
3+
version = "1.11.1"
44
description = "Dreadnode SDK"
55
requires-python = ">=3.10,<3.14"
66

77
[tool.poetry]
88
name = "dreadnode"
9-
version = "1.11.0"
9+
version = "1.11.1"
1010
description = "Dreadnode SDK"
1111
authors = ["Nick Landers <monoxgas@gmail.com>"]
1212
repository = "https://github.com/dreadnode/sdk"

0 commit comments

Comments
 (0)