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, Generic, Literal, TypeVar
from pydantic import BaseModel as PydanticBaseModel
from pydantic import ConfigDict, Field, field_validator, model_validator
from pydantic_core.core_schema import FieldValidationInfo
from ..core.constants import ArtifactType
log = logging.getLogger(__name__)
[docs]
class BaseModel(PydanticBaseModel):
model_config = ConfigDict(from_attributes=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 = 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] = []
excluded_applications: list[str] = []
severities: list[str] = []
topic: str | None = None
my_actions: bool = False
[docs]
@model_validator(mode="before")
def convert_from_orm(cls, data):
if isinstance(data, list):
return {f.name: f.params for f in data}
return data
[docs]
class GenerationRule(BaseModel):
id: int | None = None
destinations: list[Destination]
filters: Filters
[docs]
class User(BaseModel):
id: int | None = 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(BaseModel, Generic[T]):
label: str
value: T
[docs]
class Artifact(BaseModel):
type: ArtifactType
name: str
[docs]
class ArtifactOptionsGroup(BaseModel):
label: str
options: list[Option[Artifact]]