From e84cc4ac002e26f0839e819992f23f78cac15aa1 Mon Sep 17 00:00:00 2001 From: thatmattlove Date: Mon, 27 May 2024 14:41:04 -0400 Subject: [PATCH] remove deprecated pydantic `constr` usage --- hyperglass/execution/drivers/_construct.py | 6 +++--- hyperglass/models/api/query.py | 18 +++++++++--------- hyperglass/models/config/web.py | 20 +++++++++++--------- hyperglass/plugins/_input.py | 4 ++-- 4 files changed, 25 insertions(+), 23 deletions(-) diff --git a/hyperglass/execution/drivers/_construct.py b/hyperglass/execution/drivers/_construct.py index 066158d..86032bc 100644 --- a/hyperglass/execution/drivers/_construct.py +++ b/hyperglass/execution/drivers/_construct.py @@ -23,11 +23,11 @@ if t.TYPE_CHECKING: from loguru import Logger # Project - from hyperglass.models.api.query import Query, QueryTarget + from hyperglass.models.api.query import Query from hyperglass.models.directive import Directive from hyperglass.models.config.devices import Device -FormatterCallback = t.Callable[[str], "QueryTarget"] +FormatterCallback = t.Callable[[str], t.Union[t.List[str], str]] class Construct: @@ -61,7 +61,7 @@ class Construct: with Formatter(self.query) as formatter: self.target = formatter(self.prepare_target()) - def prepare_target(self) -> "QueryTarget": + def prepare_target(self) -> t.Union[t.List[str], str]: """Format the query target based on directive parameters.""" if isinstance(self.query.query_target, t.List): # Directive can accept multiple values in a single command. diff --git a/hyperglass/models/api/query.py b/hyperglass/models/api/query.py index 8fdf86b..806a9db 100644 --- a/hyperglass/models/api/query.py +++ b/hyperglass/models/api/query.py @@ -7,7 +7,7 @@ import secrets from datetime import datetime # Third Party -from pydantic import BaseModel, ConfigDict, constr, field_validator +from pydantic import BaseModel, ConfigDict, field_validator, Field # Project from hyperglass.log import log @@ -20,10 +20,6 @@ from hyperglass.exceptions.private import InputValidationError # Local from ..config.devices import Device -QueryLocation = constr(strip_whitespace=True, strict=True, min_length=1) -QueryTarget = constr(strip_whitespace=True, min_length=1) -QueryType = constr(strip_whitespace=True, strict=True, min_length=1) - class SimpleQuery(BaseModel): """A simple representation of a post-validated query.""" @@ -42,9 +38,13 @@ class Query(BaseModel): model_config = ConfigDict(extra="allow", alias_generator=snake_to_camel, populate_by_name=True) - query_location: QueryLocation # Device `name` field - query_target: t.Union[t.List[QueryTarget], QueryTarget] - query_type: QueryType # Directive `id` field + # Device `name` field + query_location: str = Field(strict=True, min_length=1, strip_whitespace=True) + + query_target: t.Union[t.List[str], str] = Field(min_length=1, strip_whitespace=True) + + # Directive `id` field + query_type: str = Field(strict=True, min_length=1, strip_whitespace=True) _kwargs: t.Dict[str, t.Any] def __init__(self, **data) -> None: @@ -106,7 +106,7 @@ class Query(BaseModel): self._input_plugin_manager.validate(query=self) log.bind(query=self.summary()).debug("Validation passed") - def transform_query_target(self) -> QueryTarget: + def transform_query_target(self) -> t.Union[t.List[str], str]: """Transform a query target based on defined plugins.""" return self._input_plugin_manager.transform(query=self) diff --git a/hyperglass/models/config/web.py b/hyperglass/models/config/web.py index fb0bda2..f2a8a35 100644 --- a/hyperglass/models/config/web.py +++ b/hyperglass/models/config/web.py @@ -5,7 +5,7 @@ import typing as t from pathlib import Path # Third Party -from pydantic import HttpUrl, FilePath, ValidationInfo, constr, field_validator, model_validator +from pydantic import Field, HttpUrl, FilePath, ValidationInfo, field_validator, model_validator from pydantic_extra_types.color import Color # Project @@ -17,12 +17,12 @@ from ..main import HyperglassModel from .opengraph import OpenGraph DEFAULT_IMAGES = Path(__file__).parent.parent.parent / "images" +DOH_PROVIDERS_PATTERN = "|".join(DNS_OVER_HTTPS.keys()) +PERCENTAGE_PATTERN = r"^([1-9][0-9]?|100)\%?$" -Percentage = constr(pattern=r"^([1-9][0-9]?|100)\%$") +Percentage = Field(pattern=r"^([1-9][0-9]?|100)\%$") TitleMode = t.Literal["logo_only", "text_only", "logo_subtitle", "all"] ColorMode = t.Literal["light", "dark"] -DOHProvider = constr(pattern="|".join(DNS_OVER_HTTPS.keys())) -Title = constr(max_length=32) Side = t.Literal["left", "right"] LocationDisplayMode = t.Literal["auto", "dropdown", "gallery"] @@ -86,8 +86,10 @@ class Logo(HyperglassModel): light: FilePath = DEFAULT_IMAGES / "hyperglass-light.svg" dark: FilePath = DEFAULT_IMAGES / "hyperglass-dark.svg" favicon: FilePath = DEFAULT_IMAGES / "hyperglass-icon.svg" - width: t.Optional[t.Union[int, Percentage]] = "100%" - height: t.Optional[t.Union[int, Percentage]] = None + width: str = Field(default="100%", pattern=PERCENTAGE_PATTERN) + # width: t.Optional[t.Union[int, Percentage]] = "100%" + height: t.Optional[str] = Field(default=None, pattern=PERCENTAGE_PATTERN) + # height: t.Optional[t.Union[int, Percentage]] = None class LogoPublic(Logo): @@ -101,8 +103,8 @@ class Text(HyperglassModel): """Validation model for params.branding.text.""" title_mode: TitleMode = "logo_only" - title: Title = "hyperglass" - subtitle: Title = "Network Looking Glass" + title: str = Field(default="hyperglass", max_length=32) + subtitle: str = Field(default="Network Looking Glass", max_length=32) query_location: str = "Location" query_type: str = "Query Type" query_target: str = "Target" @@ -184,7 +186,7 @@ class Theme(HyperglassModel): class DnsOverHttps(HyperglassModel): """Validation model for DNS over HTTPS resolution.""" - name: DOHProvider = "cloudflare" + name: str = Field(default="cloudflare", pattern=DOH_PROVIDERS_PATTERN) url: str = "" @model_validator(mode="before") diff --git a/hyperglass/plugins/_input.py b/hyperglass/plugins/_input.py index bb79889..e2316bf 100644 --- a/hyperglass/plugins/_input.py +++ b/hyperglass/plugins/_input.py @@ -8,11 +8,11 @@ from ._base import DirectivePlugin, HyperglassPlugin if t.TYPE_CHECKING: # Project - from hyperglass.models.api.query import Query, QueryTarget + from hyperglass.models.api.query import Query InputPluginValidationReturn = t.Union[None, bool] -InputPluginTransformReturn = t.Union[t.Sequence["QueryTarget"], "QueryTarget"] +InputPluginTransformReturn = t.Union[t.Sequence[str], str] class InputPlugin(HyperglassPlugin, DirectivePlugin):