Skip to content

Commit 1c8ee62

Browse files
committed
[simple-websocket]: add stubs for simple-websocket
1 parent 7765087 commit 1c8ee62

File tree

6 files changed

+323
-0
lines changed

6 files changed

+323
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
version = "1.1.*"
2+
upstream_repository = "https://github.com/miguelgrinberg/simple-websocket"
3+
requires = ["wsproto"]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from .aiows import AioClient as AioClient, AioServer as AioServer
2+
from .errors import ConnectionClosed as ConnectionClosed, ConnectionError as ConnectionError
3+
from .ws import Client as Client, Server as Server
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
import asyncio
2+
import socket
3+
from _typeshed import Incomplete, Unused
4+
from _typeshed.wsgi import WSGIEnvironment
5+
from collections.abc import Awaitable, Callable
6+
from ssl import SSLContext
7+
from typing import Any, Literal, TypedDict, type_check_only
8+
9+
from wsproto import ConnectionType, WSConnection
10+
from wsproto.events import Request
11+
from wsproto.frame_protocol import CloseReason
12+
13+
from .asgi import WebSocketASGI, _SocketDataBase, _SocketDataBytes, _SocketDataProtocol, _SocketDataStr
14+
15+
class AioBase:
16+
subprotocol: str | None
17+
connection_type: ConnectionType
18+
receive_bytes: int
19+
ping_interval: float | None
20+
max_message_size: int | None
21+
pong_received: bool
22+
input_buffer: list[bytes | str]
23+
incoming_message: bytes | str | None
24+
incoming_message_len: int
25+
connected: bool
26+
is_server: bool
27+
close_reason: CloseReason
28+
close_message: str
29+
rsock: asyncio.StreamReader
30+
wsock: asyncio.StreamWriter
31+
event: asyncio.Event
32+
ws: WSConnection | None
33+
task: asyncio.Task[None]
34+
def __init__(
35+
self,
36+
connection_type: ConnectionType | None = None,
37+
receive_bytes: int = 4096,
38+
ping_interval: float | None = None,
39+
max_message_size: int | None = None,
40+
) -> None: ...
41+
async def connect(self) -> None: ...
42+
async def handshake(self) -> None: ...
43+
async def send(self, data: bytes | Any) -> None: ...
44+
async def receive(self, timeout: float | None = None): ...
45+
async def close(self, reason: CloseReason | None = None, message: str | None = None) -> None: ...
46+
def choose_subprotocol(self, request: Request) -> str | None: ...
47+
48+
@type_check_only
49+
class _AioServerRequest(TypedDict):
50+
# this is `aiohttp.web.Request`
51+
aiohttp: Incomplete
52+
sock: None
53+
headers: None
54+
55+
class AioServer(AioBase):
56+
request: _AioServerRequest
57+
headers: dict[str, Any]
58+
subprotocols: list[str]
59+
is_server: Literal[True]
60+
mode: str
61+
connected: bool
62+
def __init__(
63+
self,
64+
request: _AioServerRequest,
65+
subprotocols: list[str] | None = None,
66+
receive_bytes: int = 4096,
67+
ping_interval: float | None = None,
68+
max_message_size: int | None = None,
69+
) -> None: ...
70+
@classmethod
71+
async def accept(
72+
cls,
73+
# this is `aiohttp.web.Request`
74+
aiohttp=None,
75+
asgi: (
76+
tuple[
77+
WSGIEnvironment,
78+
Callable[[], Awaitable[_SocketDataBytes | _SocketDataStr]],
79+
Callable[[_SocketDataBase | _SocketDataProtocol | _SocketDataBytes | _SocketDataStr], Awaitable[None]],
80+
]
81+
| None
82+
) = None,
83+
sock: socket.socket | None = None,
84+
headers: dict[str, Any] | None = None,
85+
subprotocols: list[str] | None = None,
86+
receive_bytes: int = 4096,
87+
ping_interval: float | None = None,
88+
max_message_size: int | None = None,
89+
) -> WebSocketASGI | AioServer: ...
90+
async def handshake(self) -> None: ...
91+
def choose_subprotocol(self, request: Request) -> str | None: ...
92+
93+
class AioClient(AioBase):
94+
url: str
95+
ssl_context: SSLContext | None
96+
is_secure: bool
97+
host: str
98+
port: int
99+
path: str
100+
subprotocols: list[str]
101+
extra_headeers: list[tuple[bytes, bytes]]
102+
subprotocol: str | None
103+
connected: bool
104+
def __init__(
105+
self,
106+
url: str,
107+
subprotocols: list[str] | None = None,
108+
headers: dict[str, Any] | None = None,
109+
receive_bytes: int = 4096,
110+
ping_interval: float | None = None,
111+
max_message_size: int | None = None,
112+
ssl_context: SSLContext | None = None,
113+
) -> None: ...
114+
# the source code itself has this override
115+
@classmethod
116+
async def connect( # type: ignore[override]
117+
cls,
118+
url: str,
119+
subprotocols: list[str] | None = None,
120+
headers: dict[str, Any] | None = None,
121+
receive_bytes: int = 4096,
122+
ping_interval: float | None = None,
123+
max_message_size: int | None = None,
124+
ssl_context: SSLContext | None = None,
125+
thread_class: Unused = None,
126+
event_class: Unused = None,
127+
) -> AioClient: ...
128+
async def handshake(self) -> None: ...
129+
async def close(self, reason: CloseReason | None = None, message: str | None = None) -> None: ...
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
from _typeshed.wsgi import WSGIEnvironment
2+
from collections.abc import Awaitable, Callable
3+
from typing import TypedDict, type_check_only
4+
5+
@type_check_only
6+
class _SocketDataBase(TypedDict):
7+
type: str
8+
9+
@type_check_only
10+
class _SocketDataProtocol(_SocketDataBase):
11+
subprotocol: str | None
12+
13+
@type_check_only
14+
class _SocketDataStr(_SocketDataBase):
15+
text: str
16+
17+
@type_check_only
18+
class _SocketDataBytes(_SocketDataBase):
19+
bytes: bytes
20+
21+
class WebSocketASGI:
22+
subprotocols: list[str]
23+
subprotocol: str
24+
connected: bool
25+
# this is set in `close` to `False`
26+
conncted: bool
27+
def __init__(
28+
self,
29+
scope: WSGIEnvironment,
30+
receive: Callable[[], Awaitable[_SocketDataBytes | _SocketDataStr]],
31+
send: Callable[[_SocketDataBase | _SocketDataProtocol | _SocketDataBytes | _SocketDataStr], Awaitable[None]],
32+
subprotocols: list[str] | None = None,
33+
) -> None: ...
34+
@classmethod
35+
async def accept(
36+
cls,
37+
scope: WSGIEnvironment,
38+
receive: Callable[[], Awaitable[_SocketDataBytes | _SocketDataStr]],
39+
send: Callable[[_SocketDataBase | _SocketDataProtocol | _SocketDataBytes | _SocketDataStr], Awaitable[None]],
40+
subprotocols: list[str] | None = None,
41+
) -> WebSocketASGI: ...
42+
async def receive(self) -> bytes | str: ...
43+
async def send(self, data: bytes | str) -> None: ...
44+
async def close(self) -> None: ...
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from wsproto.frame_protocol import CloseReason
2+
3+
class SimpleWebsocketError(RuntimeError): ...
4+
5+
class ConnectionError(SimpleWebsocketError):
6+
status_code: int | None
7+
def __init__(self, status_code: int | None = None) -> None: ...
8+
9+
class ConnectionClosed(SimpleWebsocketError):
10+
reason: CloseReason
11+
message: str | None
12+
def __init__(self, reason: CloseReason = ..., message: str | None = None) -> None: ...
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
import socket
2+
import threading
3+
from _typeshed import FileDescriptorLike
4+
from _typeshed.wsgi import WSGIEnvironment
5+
from collections.abc import Callable
6+
from selectors import SelectorKey, _EventMask
7+
from ssl import SSLContext
8+
from typing import Any, Protocol, type_check_only
9+
10+
from wsproto import ConnectionType, WSConnection
11+
from wsproto.events import Request
12+
from wsproto.frame_protocol import CloseReason
13+
14+
@type_check_only
15+
class _ThreadClassProtocol(Protocol):
16+
name: str
17+
def __init__(self, target: Callable[..., Any], *args: Any, **kwargs: Any) -> None: ...
18+
def start(self) -> None: ...
19+
20+
@type_check_only
21+
class _EventClassProtocol(Protocol):
22+
def clear(self) -> None: ...
23+
def set(self) -> None: ...
24+
def wait(self, timeout: float | None = None): ...
25+
26+
@type_check_only
27+
class _SelectorClassProtocol(Protocol):
28+
def register(self, fileobj: FileDescriptorLike, events: _EventMask, data: Any = None) -> SelectorKey: ...
29+
def select(self, timeout: float | None = None) -> list[tuple[SelectorKey, _EventMask]]: ...
30+
def close(self) -> None: ...
31+
32+
class Base:
33+
subprotocol: str | None
34+
sock: socket.socket | None
35+
receive_bytes: int
36+
ping_interval: float | None
37+
max_message_size: int | None
38+
pong_received: bool
39+
input_buffer: list[bytes | str]
40+
incoming_message: bytes | str | None
41+
incoming_message_len: int
42+
connected: bool
43+
is_server: bool
44+
close_reason: CloseReason
45+
close_message: str | None
46+
selector_class: type[_SelectorClassProtocol]
47+
event: _EventClassProtocol | threading.Event
48+
ws: WSConnection
49+
thread: _ThreadClassProtocol | threading.Thread
50+
def __init__(
51+
self,
52+
sock: socket.socket | None = None,
53+
connection_type: ConnectionType | None = None,
54+
receive_bytes: int = 4096,
55+
ping_interval: float | None = None,
56+
max_message_size: int | None = None,
57+
thread_class: type[_ThreadClassProtocol] | None = None,
58+
event_class: type[_EventClassProtocol] | None = None,
59+
selector_class: type[_SelectorClassProtocol] | None = None,
60+
) -> None: ...
61+
def handshake(self) -> None: ...
62+
def send(self, data: bytes | Any) -> None: ...
63+
def receive(self, timeout: float | None = None) -> bytes | str | None: ...
64+
def close(self, reason: CloseReason | None = None, message: str | None = None) -> None: ...
65+
def choose_subprotocol(self, request: Request) -> str | None: ...
66+
67+
class Server(Base):
68+
environ: WSGIEnvironment
69+
subprotocols: list[str]
70+
mode: str
71+
connected: bool
72+
def __init__(
73+
self,
74+
environ: WSGIEnvironment,
75+
subprotocols: list[str] | None = None,
76+
receive_bytes: int = 4096,
77+
ping_interval: float | None = None,
78+
max_message_size: int | None = None,
79+
thread_class: type[_ThreadClassProtocol] | None = None,
80+
event_class: type[_EventClassProtocol] | None = None,
81+
selector_class: type[_SelectorClassProtocol] | None = None,
82+
) -> None: ...
83+
@classmethod
84+
def accept(
85+
cls,
86+
environ: WSGIEnvironment,
87+
subprotocols: list[str] | None = None,
88+
receive_bytes: int = 4096,
89+
ping_interval: float | None = None,
90+
max_message_size: int | None = None,
91+
thread_class: type[_ThreadClassProtocol] | None = None,
92+
event_class: type[_EventClassProtocol] | None = None,
93+
selector_class: type[_SelectorClassProtocol] | None = None,
94+
) -> Server: ...
95+
def handshake(self) -> None: ...
96+
def choose_subprotocol(self, request: Request) -> str | None: ...
97+
98+
class Client(Base):
99+
host: str
100+
port: int
101+
path: str
102+
subprotocols: list[str]
103+
extra_headeers: list[tuple[bytes, bytes]]
104+
subprotocol: str | None
105+
connected: bool
106+
def __init__(
107+
self,
108+
url: str,
109+
subprotocols: list[str] | None = None,
110+
headers: dict[bytes, bytes] | list[tuple[bytes, bytes]] | None = None,
111+
receive_bytes: int = 4096,
112+
ping_interval: float | None = None,
113+
max_message_size: int | None = None,
114+
ssl_context: SSLContext | None = None,
115+
thread_class: type[_ThreadClassProtocol] | None = None,
116+
event_class: type[_EventClassProtocol] | None = None,
117+
) -> None: ...
118+
@classmethod
119+
def connect(
120+
cls,
121+
url: str,
122+
subprotocols: list[str] | None = None,
123+
headers: dict[bytes, bytes] | list[tuple[bytes, bytes]] | None = None,
124+
receive_bytes: int = 4096,
125+
ping_interval: float | None = None,
126+
max_message_size: int | None = None,
127+
ssl_context: SSLContext | None = None,
128+
thread_class: type[_ThreadClassProtocol] | None = None,
129+
event_class: type[_EventClassProtocol] | None = None,
130+
): ...
131+
def handshake(self) -> None: ...
132+
def close(self, reason: CloseReason | None = None, message: str | None = None) -> None: ...

0 commit comments

Comments
 (0)