Skip to content

Commit 25d00b7

Browse files
authored
Fix tests, add CI workflow and lint/format/typecheck tasks (#4)
- Fix tests and workflow transport following #3 - Ignore type errors in `anyio` - Add CI workflow - Add lint/format/typecheck tasks
1 parent 04379e0 commit 25d00b7

File tree

8 files changed

+131
-18
lines changed

8 files changed

+131
-18
lines changed

.github/workflows/ci.yml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
name: CI
2+
3+
on:
4+
pull_request:
5+
push:
6+
branches: [ main ]
7+
8+
jobs:
9+
lint-test-docs:
10+
runs-on: ${{ matrix.os }}
11+
strategy:
12+
matrix:
13+
python-version: ['3.13']
14+
os: [ubuntu-latest]
15+
16+
steps:
17+
- name: Checkout repository
18+
uses: actions/checkout@v4
19+
20+
- name: Install uv
21+
uses: astral-sh/setup-uv@v6
22+
with:
23+
python-version: ${{ matrix.python-version }}
24+
25+
- name: Install dependencies
26+
run: |
27+
uv sync
28+
29+
- name: Lint and type check
30+
run: uv run poe lint
31+
32+
- name: Run tests
33+
run: |
34+
uv run pytest

nexusmcp/service_handler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
- Decorators for controlling which operations are exposed as MCP tools
1010
"""
1111

12+
import logging
13+
import re
1214
from collections.abc import Callable
1315
from dataclasses import dataclass
1416
from typing import Any
15-
import re
16-
import logging
1717

1818
import mcp.types
1919
import nexusrpc

nexusmcp/workflow_transport.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ async def connect(
3838
self,
3939
) -> AsyncGenerator[
4040
tuple[
41-
anyio.streams.memory.MemoryObjectReceiveStream[SessionMessage],
42-
anyio.streams.memory.MemoryObjectSendStream[SessionMessage],
41+
anyio.streams.memory.MemoryObjectReceiveStream[SessionMessage], # pyright: ignore[reportAttributeAccessIssue]
42+
anyio.streams.memory.MemoryObjectSendStream[SessionMessage], # pyright: ignore[reportAttributeAccessIssue]
4343
],
4444
None,
4545
]:
@@ -119,7 +119,7 @@ async def _handle_list_tools(self) -> types.ListToolsResult:
119119
return types.ListToolsResult(tools=tools)
120120

121121
async def _handle_call_tool(self, params: types.CallToolRequestParams) -> types.CallToolResult:
122-
service, _, operation = params.name.partition("/")
122+
service, _, operation = params.name.partition("_")
123123
nexus_client = workflow.create_nexus_client(
124124
endpoint=self.endpoint,
125125
service=service,

pyproject.toml

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ dependencies = [
1414

1515
[dependency-groups]
1616
dev = [
17-
"pytest>=8.4.1",
17+
"mypy>=1.13.0",
18+
"poethepoet>=0.35.0",
19+
"pyright>=1.1",
1820
"pytest-asyncio>=1.1.0",
21+
"pytest>=8.4.1",
1922
"ruff>=0.8.0",
20-
"mypy>=1.13.0",
2123
]
2224

2325
[tool.pytest.ini_options]
@@ -41,5 +43,17 @@ indent-style = "space"
4143
python_version = "3.13"
4244
strict = true
4345

46+
[tool.poe.tasks]
47+
lint = [
48+
{cmd = "uv run pyright"},
49+
{cmd = "uv run mypy --check-untyped-defs ."},
50+
{cmd = "uv run ruff check --select I"},
51+
{cmd = "uv run ruff format --check"},
52+
]
53+
format = [
54+
{cmd = "uv run ruff check --select I --fix"},
55+
{cmd = "uv run ruff format"},
56+
]
57+
4458
[tool.uv.sources]
4559
temporalio = { git = "https://github.com/temporalio/sdk-python" }

tests/test_inbound_gateway.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ async def test_inbound_gateway() -> None:
6666

6767

6868
async def call_tool(
69-
read_stream: anyio.streams.memory.MemoryObjectReceiveStream[SessionMessage],
70-
write_stream: anyio.streams.memory.MemoryObjectSendStream[SessionMessage],
69+
read_stream: anyio.streams.memory.MemoryObjectReceiveStream[SessionMessage], # pyright: ignore[reportAttributeAccessIssue]
70+
write_stream: anyio.streams.memory.MemoryObjectSendStream[SessionMessage], # pyright: ignore[reportAttributeAccessIssue]
7171
) -> None:
7272
"""Test MCP client connecting via memory streams and calling tools."""
7373
async with ClientSession(read_stream, write_stream) as session:
@@ -79,8 +79,8 @@ async def call_tool(
7979
print(f"Available tools: {[tool.name for tool in list_tools_result.tools]}")
8080

8181
assert len(list_tools_result.tools) == 2
82-
assert list_tools_result.tools[0].name == "modified-service-name/modified-op-name"
83-
assert list_tools_result.tools[1].name == "modified-service-name/op2"
82+
assert list_tools_result.tools[0].name == "modified-service-name_modified-op-name"
83+
assert list_tools_result.tools[1].name == "modified-service-name_op2"
8484

85-
call_result = await session.call_tool("modified-service-name/modified-op-name", {"name": "World"})
85+
call_result = await session.call_tool("modified-service-name_modified-op-name", {"name": "World"})
8686
assert call_result.structuredContent == {"message": "Hello, World"}

tests/test_service.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import pytest
2-
32
from nexusrpc.handler import StartOperationContext
3+
44
from .service import MyInput, TestServiceHandler, mcp_service
55

66

@@ -27,8 +27,8 @@ async def test_list_tools() -> None:
2727
None,
2828
)
2929
assert len(tools) == 2
30-
assert tools[0].name == "modified-service-name/modified-op-name"
31-
assert tools[1].name == "modified-service-name/op2"
30+
assert tools[0].name == "modified-service-name_modified-op-name"
31+
assert tools[1].name == "modified-service-name_op2"
3232
assert tools[0].description == "This is a test operation."
3333
assert tools[1].description == "This is also a test operation."
3434
assert tools[0].inputSchema == MyInput.model_json_schema()

tests/test_workflow_caller.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ async def run(self, input: MCPCallerWorkflowInput) -> None:
3333

3434
list_tools_result = await session.list_tools()
3535
assert len(list_tools_result.tools) == 2
36-
assert list_tools_result.tools[0].name == "modified-service-name/modified-op-name"
37-
assert list_tools_result.tools[1].name == "modified-service-name/op2"
36+
assert list_tools_result.tools[0].name == "modified-service-name_modified-op-name"
37+
assert list_tools_result.tools[1].name == "modified-service-name_op2"
3838

39-
call_result = await session.call_tool("modified-service-name/modified-op-name", {"name": "World"})
39+
call_result = await session.call_tool("modified-service-name_modified-op-name", {"name": "World"})
4040
assert call_result.structuredContent == {"message": "Hello, World"}
4141

4242

uv.lock

Lines changed: 65 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)