Source code for embodichain.learning.rl.policy_evaluation.report

# ----------------------------------------------------------------------------
# Copyright (c) 2021-2026 DexForce Technology Co., Ltd.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------

"""Write timestamped policy evaluation reports."""

from __future__ import annotations

import json
import math
from collections.abc import Mapping, Sequence
from datetime import datetime, timezone
from pathlib import Path
from typing import Any

__all__ = ["write_evaluation_report"]


[docs] def write_evaluation_report( parent: str | Path, payload: Mapping[str, Any], ) -> Path: """Write ``evaluation.json`` under a new timestamped directory. Args: parent: Output parent directory. payload: Evaluation inputs and results. Returns: Written report path. """ output = Path(parent).expanduser().resolve() output.mkdir(parents=True, exist_ok=True) stamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S.%fZ") directory = output / f"{stamp}-policy" directory.mkdir() report = { "schema_version": 1, "created_at": datetime.now(timezone.utc).isoformat(), **dict(payload), } path = directory / "evaluation.json" path.write_text( json.dumps( _json_value(report), indent=2, sort_keys=True, ensure_ascii=False, allow_nan=False, ) + "\n", encoding="utf-8", ) return path
def _json_value(value: Any) -> Any: if isinstance(value, Path): return str(value) if isinstance(value, float): return value if math.isfinite(value) else None if isinstance(value, Mapping): return {str(name): _json_value(item) for name, item in value.items()} if isinstance(value, Sequence) and not isinstance(value, (str, bytes)): return [_json_value(item) for item in value] return value