mirror of
https://github.com/aljazceru/mcp-python-sdk.git
synced 2025-12-18 14:34:27 +01:00
45 lines
1.3 KiB
Python
45 lines
1.3 KiB
Python
"""Base classes and interfaces for FastMCP resources."""
|
|
|
|
import abc
|
|
from typing import Annotated
|
|
|
|
from pydantic import (
|
|
AnyUrl,
|
|
BaseModel,
|
|
ConfigDict,
|
|
Field,
|
|
UrlConstraints,
|
|
ValidationInfo,
|
|
field_validator,
|
|
)
|
|
|
|
|
|
class Resource(BaseModel, abc.ABC):
|
|
"""Base class for all resources."""
|
|
|
|
model_config = ConfigDict(validate_default=True)
|
|
|
|
uri: Annotated[AnyUrl, UrlConstraints(host_required=False)] = 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)
|
|
mime_type: str = Field(
|
|
default="text/plain",
|
|
description="MIME type of the resource content",
|
|
pattern=r"^[a-zA-Z0-9]+/[a-zA-Z0-9\-+.]+$",
|
|
)
|
|
|
|
@field_validator("name", mode="before")
|
|
@classmethod
|
|
def set_default_name(cls, name: str | None, info: ValidationInfo) -> str:
|
|
"""Set default name from URI if not provided."""
|
|
if name:
|
|
return name
|
|
if uri := info.data.get("uri"):
|
|
return str(uri)
|
|
raise ValueError("Either name or uri must be provided")
|
|
|
|
@abc.abstractmethod
|
|
async def read(self) -> str | bytes:
|
|
"""Read the resource content."""
|
|
pass
|