From 8e1f662d93e04da47735ff7fae4ba1cb897644ee Mon Sep 17 00:00:00 2001 From: Bill Easton Date: Wed, 11 Feb 2026 09:03:45 -0600 Subject: [PATCH] Bump py-key-value-aio to >=0.4.0,<0.5.0 (#3143) Co-authored-by: Bill Easton Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: marvin-context-protocol[bot] <225465937+marvin-context-protocol[bot]@users.noreply.github.com> --- .../fastmcp-server-middleware-caching.mdx | 14 +++++------ pyproject.toml | 2 +- src/fastmcp/server/middleware/caching.py | 14 +++++------ uv.lock | 23 ++++--------------- 4 files changed, 19 insertions(+), 34 deletions(-) diff --git a/docs/python-sdk/fastmcp-server-middleware-caching.mdx b/docs/python-sdk/fastmcp-server-middleware-caching.mdx index 8a997b6df..8b3f691a1 100644 --- a/docs/python-sdk/fastmcp-server-middleware-caching.mdx +++ b/docs/python-sdk/fastmcp-server-middleware-caching.mdx @@ -151,7 +151,7 @@ Notes: **Methods:** -#### `on_list_tools` +#### `on_list_tools` ```python on_list_tools(self, context: MiddlewareContext[mcp.types.ListToolsRequest], call_next: CallNext[mcp.types.ListToolsRequest, Sequence[Tool]]) -> Sequence[Tool] @@ -161,7 +161,7 @@ List tools from the cache, if caching is enabled, and the result is in the cache otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `on_list_resources` +#### `on_list_resources` ```python on_list_resources(self, context: MiddlewareContext[mcp.types.ListResourcesRequest], call_next: CallNext[mcp.types.ListResourcesRequest, Sequence[Resource]]) -> Sequence[Resource] @@ -171,7 +171,7 @@ List resources from the cache, if caching is enabled, and the result is in the c otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `on_list_prompts` +#### `on_list_prompts` ```python on_list_prompts(self, context: MiddlewareContext[mcp.types.ListPromptsRequest], call_next: CallNext[mcp.types.ListPromptsRequest, Sequence[Prompt]]) -> Sequence[Prompt] @@ -181,7 +181,7 @@ List prompts from the cache, if caching is enabled, and the result is in the cac otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `on_call_tool` +#### `on_call_tool` ```python on_call_tool(self, context: MiddlewareContext[mcp.types.CallToolRequestParams], call_next: CallNext[mcp.types.CallToolRequestParams, ToolResult]) -> ToolResult @@ -191,7 +191,7 @@ Call a tool from the cache, if caching is enabled, and the result is in the cach otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `on_read_resource` +#### `on_read_resource` ```python on_read_resource(self, context: MiddlewareContext[mcp.types.ReadResourceRequestParams], call_next: CallNext[mcp.types.ReadResourceRequestParams, ResourceResult]) -> ResourceResult @@ -201,7 +201,7 @@ Read a resource from the cache, if caching is enabled, and the result is in the otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `on_get_prompt` +#### `on_get_prompt` ```python on_get_prompt(self, context: MiddlewareContext[mcp.types.GetPromptRequestParams], call_next: CallNext[mcp.types.GetPromptRequestParams, PromptResult]) -> PromptResult @@ -211,7 +211,7 @@ Get a prompt from the cache, if caching is enabled, and the result is in the cac otherwise call the next middleware and store the result in the cache if caching is enabled. -#### `statistics` +#### `statistics` ```python statistics(self) -> ResponseCachingStatistics diff --git a/pyproject.toml b/pyproject.toml index 4c0eb22f9..57954634e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,7 @@ dependencies = [ "pydantic[email]>=2.11.7", "pyyaml>=6.0,<7.0", "pyperclip>=1.9.0", - "py-key-value-aio[disk,keyring,memory]>=0.3.0,<0.4.0", + "py-key-value-aio[disk,keyring,memory]>=0.4.0,<0.5.0", "uvicorn>=0.35", "websockets>=15.0.1", "jsonschema-path>=0.3.4", diff --git a/src/fastmcp/server/middleware/caching.py b/src/fastmcp/server/middleware/caching.py index d4ac15929..670c30a44 100644 --- a/src/fastmcp/server/middleware/caching.py +++ b/src/fastmcp/server/middleware/caching.py @@ -243,43 +243,41 @@ class ResponseCachingMiddleware(Middleware): call_tool_settings or CallToolSettings() ) - # PydanticAdapter type signature will be fixed to accept generic aliases - # See: https://github.com/strawgate/py-key-value/pull/250 self._list_tools_cache: PydanticAdapter[list[Tool]] = PydanticAdapter( key_value=self._stats, - pydantic_model=list[Tool], # type: ignore[arg-type] + pydantic_model=list[Tool], default_collection="tools/list", ) self._list_resources_cache: PydanticAdapter[list[Resource]] = PydanticAdapter( key_value=self._stats, - pydantic_model=list[Resource], # type: ignore[arg-type] + pydantic_model=list[Resource], default_collection="resources/list", ) self._list_prompts_cache: PydanticAdapter[list[Prompt]] = PydanticAdapter( key_value=self._stats, - pydantic_model=list[Prompt], # type: ignore[arg-type] + pydantic_model=list[Prompt], default_collection="prompts/list", ) self._read_resource_cache: PydanticAdapter[CachableResourceResult] = ( PydanticAdapter( key_value=self._stats, - pydantic_model=CachableResourceResult, # type: ignore[arg-type] + pydantic_model=CachableResourceResult, default_collection="resources/read", ) ) self._get_prompt_cache: PydanticAdapter[CachablePromptResult] = PydanticAdapter( key_value=self._stats, - pydantic_model=CachablePromptResult, # type: ignore[arg-type] + pydantic_model=CachablePromptResult, default_collection="prompts/get", ) self._call_tool_cache: PydanticAdapter[CachableToolResult] = PydanticAdapter( key_value=self._stats, - pydantic_model=CachableToolResult, # type: ignore[arg-type] + pydantic_model=CachableToolResult, default_collection="tools/call", ) diff --git a/uv.lock b/uv.lock index 3f329e1f3..8571b60fd 100644 --- a/uv.lock +++ b/uv.lock @@ -792,7 +792,7 @@ requires-dist = [ { name = "opentelemetry-api", specifier = ">=1.20.0" }, { name = "packaging", specifier = ">=24.0" }, { name = "platformdirs", specifier = ">=4.0.0" }, - { name = "py-key-value-aio", extras = ["disk", "keyring", "memory"], specifier = ">=0.3.0,<0.4.0" }, + { name = "py-key-value-aio", extras = ["disk", "keyring", "memory"], specifier = ">=0.4.0,<0.5.0" }, { name = "pydantic", extras = ["email"], specifier = ">=2.11.7" }, { name = "pydocket", marker = "extra == 'tasks'", specifier = ">=0.17.2" }, { name = "pyperclip", specifier = ">=1.9.0" }, @@ -1772,15 +1772,15 @@ wheels = [ [[package]] name = "py-key-value-aio" -version = "0.3.0" +version = "0.4.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "beartype" }, - { name = "py-key-value-shared" }, + { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/93/ce/3136b771dddf5ac905cc193b461eb67967cf3979688c6696e1f2cdcde7ea/py_key_value_aio-0.3.0.tar.gz", hash = "sha256:858e852fcf6d696d231266da66042d3355a7f9871650415feef9fca7a6cd4155", size = 50801, upload-time = "2025-11-17T16:50:04.711Z" } +sdist = { url = "https://files.pythonhosted.org/packages/d5/42/4397b26c564a7428fbb424c353fc416c5954609c149b6d629255f65e6dc9/py_key_value_aio-0.4.0.tar.gz", hash = "sha256:55be4942bf5d5a40aa9d6eae443425096fe1bec6af7571502e54240ce3597189", size = 89104, upload-time = "2026-02-10T23:05:51.35Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/99/10/72f6f213b8f0bce36eff21fda0a13271834e9eeff7f9609b01afdc253c79/py_key_value_aio-0.3.0-py3-none-any.whl", hash = "sha256:1c781915766078bfd608daa769fefb97e65d1d73746a3dfb640460e322071b64", size = 96342, upload-time = "2025-11-17T16:50:03.801Z" }, + { url = "https://files.pythonhosted.org/packages/7c/34/83fb1612bfdd68ef6a47b036dd0f906f943dac10844b43242a5c39395013/py_key_value_aio-0.4.0-py3-none-any.whl", hash = "sha256:962fe40cb763b2853a8f7484e9271dcbd8bf41679f4c391e54bfee4a7ca89c84", size = 148756, upload-time = "2026-02-10T23:05:50.342Z" }, ] [package.optional-dependencies] @@ -1798,19 +1798,6 @@ redis = [ { name = "redis" }, ] -[[package]] -name = "py-key-value-shared" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "beartype" }, - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/7b/e4/1971dfc4620a3a15b4579fe99e024f5edd6e0967a71154771a059daff4db/py_key_value_shared-0.3.0.tar.gz", hash = "sha256:8fdd786cf96c3e900102945f92aa1473138ebe960ef49da1c833790160c28a4b", size = 11666, upload-time = "2025-11-17T16:50:06.849Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/51/e4/b8b0a03ece72f47dce2307d36e1c34725b7223d209fc679315ffe6a4e2c3/py_key_value_shared-0.3.0-py3-none-any.whl", hash = "sha256:5b0efba7ebca08bb158b1e93afc2f07d30b8f40c2fc12ce24a4c0d84f42f9298", size = 19560, upload-time = "2025-11-17T16:50:05.954Z" }, -] - [[package]] name = "pycparser" version = "3.0"