Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-01 09:34:30

0001 from dataclasses import dataclass, field
0002 from types import MappingProxyType
0003 from typing import Any, Iterable, Mapping
0004 
0005 
0006 @dataclass(frozen=True, order=True)
0007 class Site:
0008     """PanDA site and dataset suffix used by the decision box."""
0009 
0010     name: str
0011 
0012     def __post_init__(self) -> None:
0013         if not self.name:
0014             raise ValueError("site name cannot be empty")
0015 
0016 
0017 @dataclass(frozen=True)
0018 class FileDID:
0019     """Rucio file DID in scope:name form."""
0020 
0021     scope: str
0022     name: str
0023 
0024     @classmethod
0025     def parse(cls, value: str, default_scope: str | None = None) -> "FileDID":
0026         if ":" in value:
0027             scope, name = value.split(":", 1)
0028         elif default_scope:
0029             scope, name = default_scope, value
0030         else:
0031             raise ValueError(f"file DID must be scope:name, got {value!r}")
0032         if not scope or not name:
0033             raise ValueError(f"invalid file DID {value!r}")
0034         return cls(scope=scope, name=name)
0035 
0036     def __str__(self) -> str:
0037         return f"{self.scope}:{self.name}"
0038 
0039 
0040 @dataclass(frozen=True)
0041 class DecisionContext:
0042     """Inputs available to policy evaluation for one STF file."""
0043 
0044     run_dataset: str
0045     file_did: FileDID
0046     available_sites: tuple[Site, ...]
0047     sequence: int
0048     run_number: str | None = None
0049     message: Mapping[str, Any] = field(default_factory=lambda: MappingProxyType({}))
0050     run_conditions: Mapping[str, Any] = field(default_factory=lambda: MappingProxyType({}))
0051     metadata: Mapping[str, Any] = field(default_factory=lambda: MappingProxyType({}))
0052 
0053 
0054 @dataclass(frozen=True)
0055 class SiteAssignment:
0056     """Decision result for one STF file."""
0057 
0058     file_did: FileDID
0059     sites: tuple[Site, ...]
0060     reason: str
0061 
0062     @classmethod
0063     def from_sites(cls, file_did: FileDID, sites: Iterable[Site], reason: str) -> "SiteAssignment":
0064         unique_sites = tuple(sorted(set(sites), key=lambda site: site.name))
0065         return cls(file_did=file_did, sites=unique_sites, reason=reason)
0066 
0067 
0068 @dataclass(frozen=True)
0069 class Decision:
0070     """Applied decision, including the datasets that were mutated."""
0071 
0072     run_dataset: str
0073     full_dataset: str
0074     file_did: FileDID
0075     site_datasets: tuple[str, ...]
0076     reason: str