Source code for fmn.api.api_models
# SPDX-FileCopyrightText: Contributors to the Fedora Project
#
# SPDX-License-Identifier: MIT
import logging
import re
from typing import Annotated, Any, Generic, Literal, TypeVar
from pydantic import BaseModel as PydanticBaseModel
from pydantic import Field, validator
from pydantic.generics import GenericModel
from pydantic.utils import GetterDict
from ..core.constants import ArtifactType
log = logging.getLogger(__name__)
[docs]class BaseModel(PydanticBaseModel):
[docs] class Config:
orm_mode = True
# Tracking rules with specific types for params
[docs]class ListParamTrackingRule(BaseModel):
name: Literal["artifacts-owned", "artifacts-group-owned", "users-followed"]
params: list[str]
[docs]class NoParamTrackingRule(BaseModel):
name: Literal["related-events"]
params: str | None
[docs]class ArtifactsFollowedTrackingRule(BaseModel):
name: Literal["artifacts-followed"]
params: list[dict[Literal["name", "type"], str]]
TrackingRule = Annotated[
ListParamTrackingRule | NoParamTrackingRule | ArtifactsFollowedTrackingRule,
Field(discriminator="name"),
]
# DB models
EMAIL_ADDRESS_RE = re.compile(r"[\w_.-]+@[\w.-]+")
MATRIX_ADDRESS_RE = re.compile(r"@[\w_-]+:[\w.-]+")
[docs]class Destination(BaseModel):
protocol: str
address: str
[docs]class Filters(BaseModel):
applications: list[str] = []
severities: list[str] = []
topic: str | None = None
my_actions: bool = False
[docs]class GRGetterDict(GetterDict):
[docs] def get(self, key: str, default: Any) -> Any:
if key == "filters":
return {f.name: f.params for f in self._obj.filters}
return super().get(key, default)
[docs]class GenerationRule(BaseModel):
id: int | None
destinations: list[Destination]
filters: Filters
[docs] class Config:
getter_dict = GRGetterDict
[docs]class User(BaseModel):
id: int | None
name: str
is_admin: bool = False
[docs]class NewRule(BaseModel):
name: str | None = None
disabled: bool = False
tracking_rule: TrackingRule
generation_rules: list[GenerationRule]
[docs]class Rule(NewRule):
id: int
user: User
generated_last_week: int = 0
[docs]class RulePatch(BaseModel):
disabled: bool | None = None
# Dropdown options
T = TypeVar("T")
[docs]class Option(GenericModel, Generic[T]):
label: str
value: T
[docs]class Artifact(BaseModel):
type: ArtifactType
name: str
[docs]class ArtifactOptionsGroup(BaseModel):
label: str
options: list[Option[Artifact]]