Skip to content

Commit 4fe89f6

Browse files
authored
Phase 5: Add comprehensive Google-style doctests to all transport modules, ensure flake8 and pre-commit compliance (#450)
1 parent 9ffd085 commit 4fe89f6

File tree

6 files changed

+898
-15
lines changed

6 files changed

+898
-15
lines changed

mcpgateway/transports/__init__.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,45 @@
99
- stdio: Communication over standard input/output
1010
- SSE: Server-Sent Events for server-to-client streaming
1111
- WebSocket: Full-duplex communication
12+
13+
Examples:
14+
>>> # Import all available transport classes
15+
>>> from mcpgateway.transports import Transport, StdioTransport, SSETransport, WebSocketTransport
16+
>>>
17+
>>> # Verify all classes are imported correctly
18+
>>> Transport.__name__
19+
'Transport'
20+
>>> StdioTransport.__name__
21+
'StdioTransport'
22+
>>> SSETransport.__name__
23+
'SSETransport'
24+
>>> WebSocketTransport.__name__
25+
'WebSocketTransport'
26+
27+
>>> # Check that all transports inherit from base Transport
28+
>>> from mcpgateway.transports.base import Transport
29+
>>> issubclass(StdioTransport, Transport)
30+
True
31+
>>> issubclass(SSETransport, Transport)
32+
True
33+
>>> issubclass(WebSocketTransport, Transport)
34+
True
35+
36+
>>> # Verify __all__ exports all expected classes
37+
>>> from mcpgateway.transports import __all__
38+
>>> sorted(__all__)
39+
['SSETransport', 'StdioTransport', 'Transport', 'WebSocketTransport']
40+
41+
>>> # Test that we can instantiate transport classes
42+
>>> stdio = StdioTransport()
43+
>>> isinstance(stdio, Transport)
44+
True
45+
>>> sse = SSETransport("http://localhost:8000")
46+
>>> isinstance(sse, Transport)
47+
True
48+
>>> ws = WebSocketTransport("ws://localhost:8000")
49+
>>> isinstance(ws, Transport)
50+
True
1251
"""
1352

1453
from mcpgateway.transports.base import Transport

mcpgateway/transports/base.py

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,84 @@
1414

1515

1616
class Transport(ABC):
17-
"""Base class for MCP transport implementations."""
17+
"""Base class for MCP transport implementations.
18+
19+
This abstract base class defines the interface that all MCP transport
20+
implementations must follow. It provides the core methods for connection
21+
management and message exchange.
22+
23+
Examples:
24+
>>> # Transport is abstract and cannot be instantiated directly
25+
>>> try:
26+
... Transport()
27+
... except TypeError as e:
28+
... print("Cannot instantiate abstract class")
29+
Cannot instantiate abstract class
30+
31+
>>> # Check if Transport is an abstract base class
32+
>>> from abc import ABC
33+
>>> issubclass(Transport, ABC)
34+
True
35+
36+
>>> # Verify abstract methods are defined
37+
>>> hasattr(Transport, 'connect')
38+
True
39+
>>> hasattr(Transport, 'disconnect')
40+
True
41+
>>> hasattr(Transport, 'send_message')
42+
True
43+
>>> hasattr(Transport, 'receive_message')
44+
True
45+
>>> hasattr(Transport, 'is_connected')
46+
True
47+
"""
1848

1949
@abstractmethod
2050
async def connect(self) -> None:
21-
"""Initialize transport connection."""
51+
"""Initialize transport connection.
52+
53+
This method should establish the underlying connection for the transport.
54+
It must be called before sending or receiving messages.
55+
56+
Examples:
57+
>>> # This is an abstract method - implementation required in subclasses
58+
>>> import inspect
59+
>>> inspect.ismethod(Transport.connect)
60+
False
61+
>>> hasattr(Transport, 'connect')
62+
True
63+
"""
2264

2365
@abstractmethod
2466
async def disconnect(self) -> None:
25-
"""Close transport connection."""
67+
"""Close transport connection.
68+
69+
This method should clean up the underlying connection and any associated
70+
resources. It should be called when the transport is no longer needed.
71+
72+
Examples:
73+
>>> # This is an abstract method - implementation required in subclasses
74+
>>> import inspect
75+
>>> inspect.ismethod(Transport.disconnect)
76+
False
77+
>>> hasattr(Transport, 'disconnect')
78+
True
79+
"""
2680

2781
@abstractmethod
2882
async def send_message(self, message: Dict[str, Any]) -> None:
2983
"""Send a message over the transport.
3084
3185
Args:
3286
message: Message to send
87+
88+
Examples:
89+
>>> # This is an abstract method - implementation required in subclasses
90+
>>> import inspect
91+
>>> inspect.ismethod(Transport.send_message)
92+
False
93+
>>> hasattr(Transport, 'send_message')
94+
True
3395
"""
3496

3597
@abstractmethod
@@ -38,6 +100,14 @@ async def receive_message(self) -> AsyncGenerator[Dict[str, Any], None]:
38100
39101
Yields:
40102
Received messages
103+
104+
Examples:
105+
>>> # This is an abstract method - implementation required in subclasses
106+
>>> import inspect
107+
>>> inspect.ismethod(Transport.receive_message)
108+
False
109+
>>> hasattr(Transport, 'receive_message')
110+
True
41111
"""
42112

43113
@abstractmethod
@@ -46,4 +116,12 @@ async def is_connected(self) -> bool:
46116
47117
Returns:
48118
True if connected
119+
120+
Examples:
121+
>>> # This is an abstract method - implementation required in subclasses
122+
>>> import inspect
123+
>>> inspect.ismethod(Transport.is_connected)
124+
False
125+
>>> hasattr(Transport, 'is_connected')
126+
True
49127
"""

0 commit comments

Comments
 (0)