feat: add safe BLE discovery and network baseline tools
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import tempfile
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
|
||||
def utc_now_iso() -> str:
|
||||
"""Return a stable UTC timestamp for manifests and capture artifacts."""
|
||||
return datetime.now(UTC).isoformat(timespec="milliseconds").replace("+00:00", "Z")
|
||||
|
||||
|
||||
def write_json_atomic(path: Path, payload: Any) -> None:
|
||||
"""Write JSON without exposing a partially written artifact."""
|
||||
path = path.expanduser()
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
serialized = json.dumps(payload, ensure_ascii=False, indent=2) + "\n"
|
||||
|
||||
temp_name: str | None = None
|
||||
try:
|
||||
with tempfile.NamedTemporaryFile(
|
||||
mode="w",
|
||||
encoding="utf-8",
|
||||
dir=path.parent,
|
||||
prefix=f".{path.name}.",
|
||||
suffix=".tmp",
|
||||
delete=False,
|
||||
) as stream:
|
||||
temp_name = stream.name
|
||||
stream.write(serialized)
|
||||
stream.flush()
|
||||
os.fsync(stream.fileno())
|
||||
Path(temp_name).replace(path)
|
||||
finally:
|
||||
if temp_name is not None:
|
||||
Path(temp_name).unlink(missing_ok=True)
|
||||
Reference in New Issue
Block a user