コンテンツにスキップ

WebSockets

WebSockets を定義する場合、通常は `WebSocket` 型のパラメータを宣言し、それを使用してクライアントからデータを読み取り、クライアントにデータを送信できます。

これは Starlette によって直接提供されますが、`fastapi` からインポートできます。

from fastapi import WebSocket

ヒント

HTTP と WebSockets の両方と互換性のある依存関係を定義する場合は、`Request` や `WebSocket` の代わりに `HTTPConnection` を受け取るパラメータを定義できます。

fastapi.WebSocket

WebSocket(scope, receive, send)

基底クラス: HTTPConnection

パラメータ 説明
スコープ

型: スコープ

受信

型: 受信

送信

型: 送信

ソースコードは `starlette/websockets.py` にあります
26
27
28
29
30
31
32
def __init__(self, scope: Scope, receive: Receive, send: Send) -> None:
    super().__init__(scope)
    assert scope["type"] == "websocket"
    self._receive = receive
    self._send = send
    self.client_state = WebSocketState.CONNECTING
    self.application_state = WebSocketState.CONNECTING

スコープ インスタンス属性

scope = scope

app プロパティ

app

url プロパティ

url

base_url プロパティ

base_url

headers プロパティ

headers

query_params プロパティ

query_params

path_params プロパティ

path_params

cookies プロパティ

cookies

client プロパティ

client

state プロパティ

state

client_state インスタンス属性

client_state = CONNECTING

application_state インスタンス属性

application_state = CONNECTING

url_for

url_for(name, /, **path_params)
パラメータ 説明
名前

型: str

**パス パラメータ

型: Any デフォルト: {}

ソースコードはstarlette/requests.pyにあります
177
178
179
180
def url_for(self, name: str, /, **path_params: typing.Any) -> URL:
    router: Router = self.scope["router"]
    url_path = router.url_path_for(name, **path_params)
    return url_path.make_absolute_url(base_url=self.base_url)

receive 非同期

receive()

有効な状態遷移を保証しながら、ASGI WebSocket メッセージを受信します。

ソースコードは `starlette/websockets.py` にあります
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
async def receive(self) -> Message:
    """
    Receive ASGI websocket messages, ensuring valid state transitions.
    """
    if self.client_state == WebSocketState.CONNECTING:
        message = await self._receive()
        message_type = message["type"]
        if message_type != "websocket.connect":
            raise RuntimeError(f'Expected ASGI message "websocket.connect", but got {message_type!r}')
        self.client_state = WebSocketState.CONNECTED
        return message
    elif self.client_state == WebSocketState.CONNECTED:
        message = await self._receive()
        message_type = message["type"]
        if message_type not in {"websocket.receive", "websocket.disconnect"}:
            raise RuntimeError(
                f'Expected ASGI message "websocket.receive" or "websocket.disconnect", but got {message_type!r}'
            )
        if message_type == "websocket.disconnect":
            self.client_state = WebSocketState.DISCONNECTED
        return message
    else:
        raise RuntimeError('Cannot call "receive" once a disconnect message has been received.')

send 非同期

send(message)

有効な状態遷移を保証しながら、ASGI WebSocket メッセージを送信します。

パラメータ 説明
メッセージ

型: Message

ソースコードは `starlette/websockets.py` にあります
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
async def send(self, message: Message) -> None:
    """
    Send ASGI websocket messages, ensuring valid state transitions.
    """
    if self.application_state == WebSocketState.CONNECTING:
        message_type = message["type"]
        if message_type not in {"websocket.accept", "websocket.close", "websocket.http.response.start"}:
            raise RuntimeError(
                'Expected ASGI message "websocket.accept", "websocket.close" or "websocket.http.response.start", '
                f"but got {message_type!r}"
            )
        if message_type == "websocket.close":
            self.application_state = WebSocketState.DISCONNECTED
        elif message_type == "websocket.http.response.start":
            self.application_state = WebSocketState.RESPONSE
        else:
            self.application_state = WebSocketState.CONNECTED
        await self._send(message)
    elif self.application_state == WebSocketState.CONNECTED:
        message_type = message["type"]
        if message_type not in {"websocket.send", "websocket.close"}:
            raise RuntimeError(
                f'Expected ASGI message "websocket.send" or "websocket.close", but got {message_type!r}'
            )
        if message_type == "websocket.close":
            self.application_state = WebSocketState.DISCONNECTED
        try:
            await self._send(message)
        except OSError:
            self.application_state = WebSocketState.DISCONNECTED
            raise WebSocketDisconnect(code=1006)
    elif self.application_state == WebSocketState.RESPONSE:
        message_type = message["type"]
        if message_type != "websocket.http.response.body":
            raise RuntimeError(f'Expected ASGI message "websocket.http.response.body", but got {message_type!r}')
        if not message.get("more_body", False):
            self.application_state = WebSocketState.DISCONNECTED
        await self._send(message)
    else:
        raise RuntimeError('Cannot call "send" once a close message has been sent.')

accept 非同期

accept(subprotocol=None, headers=None)
パラメータ 説明
サブプロトコル

型: str | None デフォルト: None

ヘッダー

型: Iterable[tuple[bytes, bytes]] | None デフォルト: None

ソースコードは `starlette/websockets.py` にあります
 99
100
101
102
103
104
105
106
107
108
109
async def accept(
    self,
    subprotocol: str | None = None,
    headers: typing.Iterable[tuple[bytes, bytes]] | None = None,
) -> None:
    headers = headers or []

    if self.client_state == WebSocketState.CONNECTING:
        # If we haven't yet seen the 'connect' message, then wait for it first.
        await self.receive()
    await self.send({"type": "websocket.accept", "subprotocol": subprotocol, "headers": headers})

receive_text 非同期

receive_text()
ソースコードは `starlette/websockets.py` にあります
115
116
117
118
119
120
async def receive_text(self) -> str:
    if self.application_state != WebSocketState.CONNECTED:
        raise RuntimeError('WebSocket is not connected. Need to call "accept" first.')
    message = await self.receive()
    self._raise_on_disconnect(message)
    return typing.cast(str, message["text"])

receive_bytes 非同期

receive_bytes()
ソースコードは `starlette/websockets.py` にあります
122
123
124
125
126
127
async def receive_bytes(self) -> bytes:
    if self.application_state != WebSocketState.CONNECTED:
        raise RuntimeError('WebSocket is not connected. Need to call "accept" first.')
    message = await self.receive()
    self._raise_on_disconnect(message)
    return typing.cast(bytes, message["bytes"])

receive_json 非同期

receive_json(mode='text')
パラメータ 説明
モード

型: str デフォルト: 'text'

ソースコードは `starlette/websockets.py` にあります
129
130
131
132
133
134
135
136
137
138
139
140
141
async def receive_json(self, mode: str = "text") -> typing.Any:
    if mode not in {"text", "binary"}:
        raise RuntimeError('The "mode" argument should be "text" or "binary".')
    if self.application_state != WebSocketState.CONNECTED:
        raise RuntimeError('WebSocket is not connected. Need to call "accept" first.')
    message = await self.receive()
    self._raise_on_disconnect(message)

    if mode == "text":
        text = message["text"]
    else:
        text = message["bytes"].decode("utf-8")
    return json.loads(text)

iter_text 非同期

iter_text()
ソースコードは `starlette/websockets.py` にあります
143
144
145
146
147
148
async def iter_text(self) -> typing.AsyncIterator[str]:
    try:
        while True:
            yield await self.receive_text()
    except WebSocketDisconnect:
        pass

iter_bytes 非同期

iter_bytes()
ソースコードは `starlette/websockets.py` にあります
150
151
152
153
154
155
async def iter_bytes(self) -> typing.AsyncIterator[bytes]:
    try:
        while True:
            yield await self.receive_bytes()
    except WebSocketDisconnect:
        pass

iter_json 非同期

iter_json()
ソースコードは `starlette/websockets.py` にあります
157
158
159
160
161
162
async def iter_json(self) -> typing.AsyncIterator[typing.Any]:
    try:
        while True:
            yield await self.receive_json()
    except WebSocketDisconnect:
        pass

send_text 非同期

send_text(data)
パラメータ 説明
データ

型: str

ソースコードは `starlette/websockets.py` にあります
164
165
async def send_text(self, data: str) -> None:
    await self.send({"type": "websocket.send", "text": data})

send_bytes 非同期

send_bytes(data)
パラメータ 説明
データ

型: bytes

ソースコードは `starlette/websockets.py` にあります
167
168
async def send_bytes(self, data: bytes) -> None:
    await self.send({"type": "websocket.send", "bytes": data})

send_json 非同期

send_json(data, mode='text')
パラメータ 説明
データ

型: Any

モード

型: str デフォルト: 'text'

ソースコードは `starlette/websockets.py` にあります
170
171
172
173
174
175
176
177
async def send_json(self, data: typing.Any, mode: str = "text") -> None:
    if mode not in {"text", "binary"}:
        raise RuntimeError('The "mode" argument should be "text" or "binary".')
    text = json.dumps(data, separators=(",", ":"), ensure_ascii=False)
    if mode == "text":
        await self.send({"type": "websocket.send", "text": text})
    else:
        await self.send({"type": "websocket.send", "bytes": text.encode("utf-8")})

close 非同期

close(code=1000, reason=None)
パラメータ 説明
コード

型: int デフォルト: 1000

理由

型: str | None デフォルト: None

ソースコードは `starlette/websockets.py` にあります
179
180
async def close(self, code: int = 1000, reason: str | None = None) -> None:
    await self.send({"type": "websocket.close", "code": code, "reason": reason or ""})

クライアントが切断された場合、`WebSocketDisconnect` 例外が発生します。これをキャッチすることができます。

`fastapi` から直接インポートできます

from fastapi import WebSocketDisconnect

fastapi.WebSocketDisconnect

WebSocketDisconnect(code=1000, reason=None)

基底クラス: Exception

パラメータ 説明
コード

型: int デフォルト: 1000

理由

型: str | None デフォルト: None

ソースコードは `starlette/websockets.py` にあります
20
21
22
def __init__(self, code: int = 1000, reason: str | None = None) -> None:
    self.code = code
    self.reason = reason or ""

code インスタンス属性

code = code

reason インスタンス属性

reason = reason or ''

WebSockets - 追加クラス

WebSockets を扱うための追加クラス。

Starlette によって直接提供されていますが、`fastapi` からインポートできます

from fastapi.websockets import WebSocketDisconnect, WebSocketState

fastapi.websockets.WebSocketDisconnect

WebSocketDisconnect(code=1000, reason=None)

基底クラス: Exception

パラメータ 説明
コード

型: int デフォルト: 1000

理由

型: str | None デフォルト: None

ソースコードは `starlette/websockets.py` にあります
20
21
22
def __init__(self, code: int = 1000, reason: str | None = None) -> None:
    self.code = code
    self.reason = reason or ""

code インスタンス属性

code = code

reason インスタンス属性

reason = reason or ''

fastapi.websockets.WebSocketState

基底クラス: Enum

CONNECTING クラス属性 インスタンス属性

CONNECTING = 0

CONNECTED クラス属性 インスタンス属性

CONNECTED = 1

DISCONNECTED クラス属性 インスタンス属性

DISCONNECTED = 2

RESPONSE クラス属性 インスタンス属性

RESPONSE = 3