Typing Stubs for Channels
types-channels is a stub package providing type hints for the `channels` library, which enables asynchronous communication for Django. It allows static type checkers like MyPy to understand the types used within `channels` code, improving code quality and maintainability. It is part of the `typeshed` project and is currently at version 4.3.0.20260408, with releases frequently updated to track upstream `channels` and `typeshed` changes.
Common errors
-
ModuleNotFoundError: No module named 'types_channels'
cause Attempting to import from the stub package `types_channels` directly, which only contains stub files and no runtime modules.fixImport symbols from the actual `channels` library instead (e.g., `from channels.layers import get_channel_layer`). -
error: Library "channels" has no type information available
cause MyPy cannot find type stubs for the `channels` library.fixInstall the `types-channels` package in the environment MyPy is using (`pip install types-channels`). Also, ensure MyPy is configured to check that environment. -
error: Incompatible types in assignment (expression has type "str", variable has type "int")
cause A type error reported by MyPy, often due to mismatched expectations between your code and the stubs, or incompatible versions of `channels` and `types-channels`.fixReview the specific type error message carefully. It might indicate an actual bug in your code, or a version incompatibility where the API signature in `channels` has changed, and the stubs are outdated (or vice versa). Update `channels` or `types-channels` to compatible versions, or adjust your code.
Warnings
- gotcha `types-channels` provides only type stub files (`.pyi`) for static analysis by tools like MyPy. It does not contain any executable Python code for runtime and should never be imported directly.
- gotcha Stub package versions (like `types-channels`) are typically designed for specific versions of their corresponding runtime library (`channels`). Using significantly mismatched versions can lead to incorrect type checking results or MyPy errors.
- gotcha For MyPy to effectively use `types-channels`, ensure your MyPy configuration allows it to follow imports. Default settings usually work, but issues might arise with custom `mypy.ini` configurations.
Install
-
pip install types-channels -
pip install 'channels<5'
Imports
- ProtocolTypeRouter
from channels.routing import ProtocolTypeRouter
Quickstart
import asyncio
from channels.generic.websocket import AsyncWebsocketConsumer
from typing import Dict, Any, Union
# Example consumer, save as `my_consumer.py`
class MyConsumer(AsyncWebsocketConsumer):
async def connect(self) -> None:
await self.accept()
print("WebSocket connected!")
async def disconnect(self, close_code: int) -> None:
print(f"WebSocket disconnected with code: {close_code}")
async def receive(self, text_data: Union[str, None] = None, bytes_data: Union[bytes, None] = None) -> None:
if text_data:
response: Dict[str, Any] = {"message": f"Received: {text_data}"}
await self.send(text_data=str(response))
print("Received data.")
async def main():
# This part is just to make the example runnable for demonstration of type hints.
# In a real application, connect and disconnect would be called by the ASGI server.
consumer = MyConsumer()
await consumer.connect()
# Simulate a received message for type checking
await consumer.receive(text_data="Hello from client!")
await consumer.disconnect(1000)
if __name__ == '__main__':
asyncio.run(main())