From ec74c0293d6cfb40d7f8ee37fdc16455bd68a0e1 Mon Sep 17 00:00:00 2001 From: Jeremiah Lowin <153965+jlowin@users.noreply.github.com> Date: Mon, 2 Dec 2024 12:47:36 -0500 Subject: [PATCH] Remove BaseURL reference and use AnyURL --- src/fastmcp/resources/base.py | 29 +++++++++-------------------- 1 file changed, 9 insertions(+), 20 deletions(-) diff --git a/src/fastmcp/resources/base.py b/src/fastmcp/resources/base.py index bde9b3820..11f9029cb 100644 --- a/src/fastmcp/resources/base.py +++ b/src/fastmcp/resources/base.py @@ -1,34 +1,16 @@ """Base classes and interfaces for FastMCP resources.""" import abc -from typing import Annotated, Union +from typing import Union from pydantic import ( AnyUrl, BaseModel, - BeforeValidator, ConfigDict, Field, - FileUrl, ValidationInfo, field_validator, ) -from pydantic.networks import _BaseUrl # TODO: remove this once pydantic is updated - - -def maybe_cast_str_to_any_url(x) -> AnyUrl: - if isinstance(x, FileUrl): - return x - elif isinstance(x, AnyUrl): - return x - elif isinstance(x, str): - if x.startswith("file://"): - return FileUrl(x) - return AnyUrl(x) - raise ValueError(f"Expected str or AnyUrl, got {type(x)}") - - -LaxAnyUrl = Annotated[_BaseUrl | str, BeforeValidator(maybe_cast_str_to_any_url)] class Resource(BaseModel, abc.ABC): @@ -36,7 +18,8 @@ class Resource(BaseModel, abc.ABC): model_config = ConfigDict(validate_default=True) - uri: LaxAnyUrl = Field(default=..., description="URI of the resource") + # uri: Annotated[AnyUrl, BeforeValidator(maybe_cast_str_to_any_url)] = Field( + uri: AnyUrl = Field(default=..., description="URI of the resource") name: str | None = Field(description="Name of the resource", default=None) description: str | None = Field( description="Description of the resource", default=None @@ -47,6 +30,12 @@ class Resource(BaseModel, abc.ABC): pattern=r"^[a-zA-Z0-9]+/[a-zA-Z0-9\-+.]+$", ) + @field_validator("uri", mode="before") + def validate_uri(cls, uri: AnyUrl | str) -> AnyUrl: + if isinstance(uri, str): + return AnyUrl(uri) + return uri + @field_validator("name", mode="before") @classmethod def set_default_name(cls, name: str | None, info: ValidationInfo) -> str: