Skip to content
Merged
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change Log

## Unreleased

- Added support for log level in events creation.

## [v2.4.1](https://github.com/simvue-io/python-api/releases/tag/v2.4.1) - 2026-03-31

- Moved to using `threading.Event` as termination trigger events and added deprecation notice for `multiprocessing.Event`.
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "simvue"
version = "2.4.1"
version = "2.5.0"
description = "Simulation tracking and monitoring"
authors = [{ name = "Simvue Development Team", email = "info@simvue.io" }]
license = "Apache v2"
Expand Down
15 changes: 13 additions & 2 deletions simvue/config/user.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,14 @@ class SimvueConfiguration(pydantic.BaseModel):
metrics: MetricsSpecifications = MetricsSpecifications()
eco: EcoConfig = EcoConfig()
current_profile: str | None = None
_server_version: semver.Version | None = None

@property
def server_version(self) -> semver.Version:
"""Retrieve current Server version."""
if not self._server_version:
raise RuntimeError("Expected server version to be defined")
return self._server_version

@classmethod
def _load_pyproject_configs(cls) -> dict | None:
Expand Down Expand Up @@ -103,7 +111,7 @@ def _load_pyproject_configs(cls) -> dict | None:
@functools.lru_cache
def _check_server(
cls, token: str, url: str, mode: typing.Literal["offline", "online", "disabled"]
) -> None:
) -> semver.Version:
if mode in ("offline", "disabled"):
return

Expand Down Expand Up @@ -143,6 +151,7 @@ def _check_server(
f"Python API v{_version_str} is not compatible with Simvue server versions "
f"< {SIMVUE_SERVER_LOWER_CONSTRAINT}"
)
return _version

@pydantic.validate_call
def write(self, out_directory: pydantic.DirectoryPath) -> None:
Expand All @@ -154,7 +163,9 @@ def check_valid_server(self) -> Self:
if os.environ.get("SIMVUE_NO_SERVER_CHECK"):
return self

self._check_server(self.server.token, self.server.url, self.run.mode)
self._server_version = self._check_server(
self.server.token, self.server.url, self.run.mode
)

return self

Expand Down
4 changes: 4 additions & 0 deletions simvue/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
str, pydantic.StringConstraints(pattern=METRIC_KEY_REGEX)
]
ObjectID = typing.Annotated[str, pydantic.StringConstraints(pattern=OBJECT_ID)]
LogLevel = typing.Literal["debug", "info", "warning", "error", "critical"]


def validate_timestamp(timestamp: str, raise_except: bool = True) -> bool:
Expand Down Expand Up @@ -114,4 +115,7 @@ def serialize_array(
class EventSet(pydantic.BaseModel):
model_config = pydantic.ConfigDict(extra="forbid")
message: str
log_level: (
typing.Literal["info", "warning", "debug", "error", "critical"] | None
) = None
timestamp: typing.Annotated[str | None, pydantic.BeforeValidator(simvue_timestamp)]
19 changes: 17 additions & 2 deletions simvue/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
MetricKeyString,
validate_timestamp,
simvue_timestamp,
LogLevel,
)
from .system import get_system
from .metadata import git_info, environment
Expand Down Expand Up @@ -1356,9 +1357,11 @@ def update_tags(self, tags: list[str]) -> bool:
def log_event(
self,
message: str,
*,
timestamp: typing.Annotated[
datetime.datetime | str | None, pydantic.BeforeValidator(simvue_timestamp)
] = None,
log_level: LogLevel = "info",
) -> bool:
"""Log event to the server

Expand All @@ -1369,6 +1372,9 @@ def log_event(
timestamp : datetime.datetime | str, optional
manually specify the time stamp for this log, by default None
if a string is provided, local time
log_level : str, optional
the logging level for this event, default is 'info',
requires server with version >=1.2.16

Returns
-------
Expand All @@ -1386,7 +1392,8 @@ def log_event(

run.log_event(
message="Good Night",
timestamp=datetime.datetime.now(datetime.UTC)
timestamp=datetime.datetime.now(datetime.UTC),
log_level="debug"
)
```
"""
Expand All @@ -1405,7 +1412,15 @@ def log_event(
self._error("Cannot log events when not in the running state")
return False

_data = {"message": message, "timestamp": timestamp}
# FIXME: Temporary, this will eventually be removed
import semver

_log_level_server_version = semver.parse("1.2.16")
if self._user_config.server_version < _log_level_server_version:
self._error("Log level is not supported on current server.")
return False

_data = {"message": message, "timestamp": timestamp, "log_level": log_level}
self._dispatcher.add_item(
_data, object_type="events", blocking=self._queue_blocking
)
Expand Down
4 changes: 2 additions & 2 deletions tests/unit/test_events.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def test_events_creation_online() -> None:
_events = Events.new(
run=_run.id,
events=[
{"message": "This is a test!", "timestamp": _timestamp}
{"message": "This is a test!", "timestamp": _timestamp, "log_level": "debug"}
],
)
assert _events.to_dict()
Expand All @@ -44,7 +44,7 @@ def test_events_creation_offline(offline_cache_setup) -> None:
_events = Events.new(
run=_run.id,
events=[
{"message": "This is a test!", "timestamp": _timestamp}
{"message": "This is a test!", "timestamp": _timestamp, "log_level": "debug"}
],
offline=True
)
Expand Down
Loading