Skip to content
Open
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
46 changes: 43 additions & 3 deletions nodescraper/models/taskresult.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@
import os
from typing import Any, Optional

from pydantic import BaseModel, Field, field_serializer, field_validator
from pydantic import (
BaseModel,
Field,
field_serializer,
field_validator,
model_validator,
)

from nodescraper.enums import EventPriority, ExecutionStatus
from nodescraper.utils import get_unique_filename, pascal_to_snake
Expand All @@ -54,6 +60,20 @@ class TaskResult(BaseModel):
task: Optional[str] = None
parent: Optional[str] = None
artifacts: list[BaseModel] = Field(default_factory=list)
details: dict = Field(default_factory=dict)

@model_validator(mode="before")
@classmethod
def _source_source_type_aliases(cls, data: Any) -> Any:
"""Accept source/source_type."""
if isinstance(data, dict):
data = dict(data)
if "source" in data and "task" not in data:
data["task"] = data.pop("source")
if "source_type" in data and "parent" not in data:
data["parent"] = data.pop("source_type")
return data

events: list[Event] = Field(default_factory=list)
start_time: datetime.datetime = Field(default_factory=datetime.datetime.now)
end_time: datetime.datetime = Field(default_factory=datetime.datetime.now)
Expand Down Expand Up @@ -107,14 +127,24 @@ def duration(self) -> Optional[str]:

@property
def source(self) -> str:
"""Task/source name (alias for task for error-scraper compatibility)."""
"""Task/source name."""
return self.task or ""

@source.setter
def source(self, value: str) -> None:
"""Set task from source."""
self.task = value if value else None

@property
def source_type(self) -> str:
"""Task/source type (alias for parent for error-scraper compatibility)."""
"""Task/source type."""
return self.parent or ""

@source_type.setter
def source_type(self, value: str) -> None:
"""Set parent from source_type."""
self.parent = value if value else None

@property
def summary_dict(self) -> dict:
"""Summary dict for logging/display (task_name, task_type, task_result, event_count, duration)."""
Expand Down Expand Up @@ -208,6 +238,16 @@ def _get_event_summary(self) -> str:

return "; ".join(summary_parts)

def _get_event_priorities(self) -> str:
warnings = sum(1 for e in self.events if e.priority == EventPriority.WARNING)
errors = sum(1 for e in self.events if e.priority >= EventPriority.ERROR)
parts = []
if warnings:
parts.append(f"{warnings} warnings")
if errors:
parts.append(f"{errors} errors")
return "|".join(parts)

def _update_status(self) -> None:
"""Update overall status based on event priority"""
self.status = ExecutionStatus.OK
Expand Down