Skip to content

Commit 27c6ca2

Browse files
committed
no extra type file
fix pyproject groups fix lockfile add pre-commit ci actually run ruff and fix things
1 parent 67de515 commit 27c6ca2

File tree

8 files changed

+819
-43
lines changed

8 files changed

+819
-43
lines changed

Diff for: .github/workflows/lint.yml

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: Run Pre-commits
2+
3+
env:
4+
# enable colored output
5+
# https://github.com/pytest-dev/pytest/issues/7443
6+
PY_COLORS: 1
7+
8+
on:
9+
push:
10+
branches: ["main"]
11+
pull_request:
12+
workflow_dispatch:
13+
14+
permissions:
15+
contents: read
16+
17+
jobs:
18+
static_analysis:
19+
timeout-minutes: 1
20+
21+
runs-on: ubuntu-latest
22+
23+
steps:
24+
- uses: actions/checkout@v4
25+
- name: Set up Python
26+
uses: actions/setup-python@v5
27+
with:
28+
python-version: "3.12"
29+
- name: Run pre-commit
30+
uses: pre-commit/[email protected]

Diff for: pyproject.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@ build-backend = "setuptools.build_meta"
2424
[tool.setuptools_scm]
2525
write_to = "src/fastmcp/_version.py"
2626

27-
[dependency-groups]
27+
[project.optional-dependencies]
2828
dev = [
2929
"copychat>=0.5.2",
3030
"ipython>=8.12.3",
3131
"pdbpp>=0.10.3",
32-
"pre-commit>=3.10.1",
32+
"pre-commit",
3333
"pytest-xdist>=3.6.1",
3434
"pytest>=8.3.3",
3535
"pytest-asyncio>=0.23.5",
36+
"ruff",
3637
]
3738

3839
[tool.pytest.ini_options]

Diff for: src/fastmcp/resources/base.py

+25-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,33 @@
11
"""Base classes and interfaces for FastMCP resources."""
22

33
import abc
4-
from typing import Union
4+
from typing import Annotated, Union
55

6-
from pydantic import BaseModel, ConfigDict, Field, ValidationInfo, field_validator
6+
from pydantic import (
7+
AnyUrl,
8+
BaseModel,
9+
BeforeValidator,
10+
ConfigDict,
11+
Field,
12+
FileUrl,
13+
ValidationInfo,
14+
field_validator,
15+
)
716

8-
from fastmcp.types import LaxAnyUrl
17+
18+
def maybe_cast_str_to_any_url(x) -> AnyUrl:
19+
if isinstance(x, FileUrl):
20+
return x
21+
elif isinstance(x, AnyUrl):
22+
return x
23+
elif isinstance(x, str):
24+
if x.startswith("file://"):
25+
return FileUrl(x)
26+
return AnyUrl(x)
27+
raise ValueError(f"Expected str or AnyUrl, got {type(x)}")
28+
29+
30+
LaxAnyUrl = Annotated[AnyUrl, BeforeValidator(maybe_cast_str_to_any_url)]
931

1032

1133
class Resource(BaseModel, abc.ABC):

Diff for: src/fastmcp/resources/types.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
"""Concrete resource implementations."""
22

3-
import pydantic_core
43
import asyncio
54
import json
65
from pathlib import Path
76
from typing import Any, Callable, Union
87

98
import httpx
109
import pydantic.json
10+
import pydantic_core
1111
from pydantic import Field
1212

1313
from fastmcp.resources.base import Resource

Diff for: src/fastmcp/types.py

-18
This file was deleted.

Diff for: tests/test_server.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,18 @@
1+
import base64
2+
from pathlib import Path
3+
from typing import TYPE_CHECKING, Union
4+
5+
import pytest
6+
from mcp.shared.exceptions import McpError
17
from mcp.shared.memory import (
28
create_connected_server_and_client_session as client_session,
39
)
4-
from mcp.shared.exceptions import McpError
5-
from fastmcp import FastMCP, Context
10+
from mcp.types import ImageContent, TextContent
11+
12+
from fastmcp import Context, FastMCP
13+
from fastmcp.prompts.base import EmbeddedResource, Message, UserMessage
614
from fastmcp.resources import FileResource, FunctionResource
715
from fastmcp.utilities.types import Image
8-
from mcp.types import TextContent, ImageContent
9-
from fastmcp.prompts.base import Message, UserMessage, TextContent, EmbeddedResource
10-
import pytest
11-
from pathlib import Path
12-
import base64
13-
from typing import Union, TYPE_CHECKING
1416

1517
if TYPE_CHECKING:
1618
from fastmcp import Context

Diff for: tests/test_tool_manager.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import logging
2+
from typing import Optional
3+
24
import pytest
35
from pydantic import BaseModel
4-
from typing import Optional
56

67
from fastmcp.exceptions import ToolError
78
from fastmcp.tools import ToolManager
@@ -69,7 +70,7 @@ def create_user(user: UserInput, flag: bool) -> dict:
6970
def test_add_invalid_tool(self):
7071
manager = ToolManager()
7172
with pytest.raises(AttributeError):
72-
manager.add_tool(1)
73+
manager.add_tool(1) # type: ignore
7374

7475
def test_add_lambda(self):
7576
manager = ToolManager()
@@ -185,7 +186,7 @@ def tool_with_context(x: int, ctx: Context) -> str:
185186
return str(x)
186187

187188
manager = ToolManager()
188-
tool = manager.add_tool(tool_with_context)
189+
manager.add_tool(tool_with_context)
189190

190191
mcp = FastMCP()
191192
ctx = mcp.get_context()
@@ -201,7 +202,7 @@ async def async_tool(x: int, ctx: Context) -> str:
201202
return str(x)
202203

203204
manager = ToolManager()
204-
tool = manager.add_tool(async_tool)
205+
manager.add_tool(async_tool)
205206

206207
mcp = FastMCP()
207208
ctx = mcp.get_context()
@@ -216,7 +217,7 @@ def tool_with_context(x: int, ctx: Optional[Context] = None) -> str:
216217
return str(x)
217218

218219
manager = ToolManager()
219-
tool = manager.add_tool(tool_with_context)
220+
manager.add_tool(tool_with_context)
220221
# Should not raise an error when context is not provided
221222
result = await manager.call_tool("tool_with_context", {"x": 42})
222223
assert result == "42"
@@ -229,7 +230,7 @@ def tool_with_context(x: int, ctx: Context) -> str:
229230
raise ValueError("Test error")
230231

231232
manager = ToolManager()
232-
tool = manager.add_tool(tool_with_context)
233+
manager.add_tool(tool_with_context)
233234

234235
mcp = FastMCP()
235236
ctx = mcp.get_context()

0 commit comments

Comments
 (0)