uvicorn 0.24.0__py3-none-any.whl → 0.25.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- uvicorn/__init__.py +1 -1
- uvicorn/_types.py +31 -13
- uvicorn/config.py +3 -3
- uvicorn/main.py +5 -5
- uvicorn/protocols/websockets/websockets_impl.py +43 -13
- uvicorn/protocols/websockets/wsproto_impl.py +59 -15
- uvicorn/supervisors/watchfilesreload.py +3 -0
- uvicorn/supervisors/watchgodreload.py +3 -0
- {uvicorn-0.24.0.dist-info → uvicorn-0.25.0.dist-info}/METADATA +3 -3
- {uvicorn-0.24.0.dist-info → uvicorn-0.25.0.dist-info}/RECORD +13 -13
- {uvicorn-0.24.0.dist-info → uvicorn-0.25.0.dist-info}/WHEEL +1 -1
- {uvicorn-0.24.0.dist-info → uvicorn-0.25.0.dist-info}/entry_points.txt +0 -0
- {uvicorn-0.24.0.dist-info → uvicorn-0.25.0.dist-info}/licenses/LICENSE.md +0 -0
uvicorn/__init__.py
CHANGED
uvicorn/_types.py
CHANGED
@@ -124,14 +124,14 @@ class HTTPResponseDebugEvent(TypedDict):
|
|
124
124
|
class HTTPResponseStartEvent(TypedDict):
|
125
125
|
type: Literal["http.response.start"]
|
126
126
|
status: int
|
127
|
-
headers: Iterable[Tuple[bytes, bytes]]
|
127
|
+
headers: NotRequired[Iterable[Tuple[bytes, bytes]]]
|
128
128
|
trailers: NotRequired[bool]
|
129
129
|
|
130
130
|
|
131
131
|
class HTTPResponseBodyEvent(TypedDict):
|
132
132
|
type: Literal["http.response.body"]
|
133
133
|
body: bytes
|
134
|
-
more_body: bool
|
134
|
+
more_body: NotRequired[bool]
|
135
135
|
|
136
136
|
|
137
137
|
class HTTPResponseTrailersEvent(TypedDict):
|
@@ -156,20 +156,38 @@ class WebSocketConnectEvent(TypedDict):
|
|
156
156
|
|
157
157
|
class WebSocketAcceptEvent(TypedDict):
|
158
158
|
type: Literal["websocket.accept"]
|
159
|
-
subprotocol: Optional[str]
|
160
|
-
headers: Iterable[Tuple[bytes, bytes]]
|
159
|
+
subprotocol: NotRequired[Optional[str]]
|
160
|
+
headers: NotRequired[Iterable[Tuple[bytes, bytes]]]
|
161
|
+
|
162
|
+
|
163
|
+
class _WebSocketReceiveEventBytes(TypedDict):
|
164
|
+
type: Literal["websocket.receive"]
|
165
|
+
bytes: bytes
|
166
|
+
text: NotRequired[None]
|
161
167
|
|
162
168
|
|
163
|
-
class
|
169
|
+
class _WebSocketReceiveEventText(TypedDict):
|
164
170
|
type: Literal["websocket.receive"]
|
165
|
-
bytes:
|
166
|
-
text:
|
171
|
+
bytes: NotRequired[None]
|
172
|
+
text: str
|
173
|
+
|
174
|
+
|
175
|
+
WebSocketReceiveEvent = Union[_WebSocketReceiveEventBytes, _WebSocketReceiveEventText]
|
167
176
|
|
168
177
|
|
169
|
-
class
|
178
|
+
class _WebSocketSendEventBytes(TypedDict):
|
170
179
|
type: Literal["websocket.send"]
|
171
|
-
bytes:
|
172
|
-
text:
|
180
|
+
bytes: bytes
|
181
|
+
text: NotRequired[None]
|
182
|
+
|
183
|
+
|
184
|
+
class _WebSocketSendEventText(TypedDict):
|
185
|
+
type: Literal["websocket.send"]
|
186
|
+
bytes: NotRequired[None]
|
187
|
+
text: str
|
188
|
+
|
189
|
+
|
190
|
+
WebSocketSendEvent = Union[_WebSocketSendEventBytes, _WebSocketSendEventText]
|
173
191
|
|
174
192
|
|
175
193
|
class WebSocketResponseStartEvent(TypedDict):
|
@@ -181,7 +199,7 @@ class WebSocketResponseStartEvent(TypedDict):
|
|
181
199
|
class WebSocketResponseBodyEvent(TypedDict):
|
182
200
|
type: Literal["websocket.http.response.body"]
|
183
201
|
body: bytes
|
184
|
-
more_body: bool
|
202
|
+
more_body: NotRequired[bool]
|
185
203
|
|
186
204
|
|
187
205
|
class WebSocketDisconnectEvent(TypedDict):
|
@@ -191,8 +209,8 @@ class WebSocketDisconnectEvent(TypedDict):
|
|
191
209
|
|
192
210
|
class WebSocketCloseEvent(TypedDict):
|
193
211
|
type: Literal["websocket.close"]
|
194
|
-
code: int
|
195
|
-
reason: Optional[str]
|
212
|
+
code: NotRequired[int]
|
213
|
+
reason: NotRequired[Optional[str]]
|
196
214
|
|
197
215
|
|
198
216
|
class LifespanStartupEvent(TypedDict):
|
uvicorn/config.py
CHANGED
@@ -187,7 +187,7 @@ def _normalize_dirs(dirs: Union[List[str], str, None]) -> List[str]:
|
|
187
187
|
class Config:
|
188
188
|
def __init__(
|
189
189
|
self,
|
190
|
-
app: Union["ASGIApplication", Callable, str],
|
190
|
+
app: Union["ASGIApplication", Callable[..., Any], str],
|
191
191
|
host: str = "127.0.0.1",
|
192
192
|
port: int = 8000,
|
193
193
|
uds: Optional[str] = None,
|
@@ -201,7 +201,7 @@ class Config:
|
|
201
201
|
ws_ping_timeout: Optional[float] = 20.0,
|
202
202
|
ws_per_message_deflate: bool = True,
|
203
203
|
lifespan: LifespanType = "auto",
|
204
|
-
env_file:
|
204
|
+
env_file: "str | os.PathLike[str] | None" = None,
|
205
205
|
log_config: Optional[Union[Dict[str, Any], str]] = LOGGING_CONFIG,
|
206
206
|
log_level: Optional[Union[str, int]] = None,
|
207
207
|
access_log: bool = True,
|
@@ -226,7 +226,7 @@ class Config:
|
|
226
226
|
timeout_graceful_shutdown: Optional[int] = None,
|
227
227
|
callback_notify: Optional[Callable[..., Awaitable[None]]] = None,
|
228
228
|
ssl_keyfile: Optional[str] = None,
|
229
|
-
ssl_certfile:
|
229
|
+
ssl_certfile: "str | os.PathLike[str] | None" = None,
|
230
230
|
ssl_keyfile_password: Optional[str] = None,
|
231
231
|
ssl_version: int = SSL_PROTOCOL_VERSION,
|
232
232
|
ssl_cert_reqs: int = ssl.CERT_NONE,
|
uvicorn/main.py
CHANGED
@@ -156,14 +156,14 @@ def print_version(ctx: click.Context, param: click.Parameter, value: bool) -> No
|
|
156
156
|
"--ws-ping-interval",
|
157
157
|
type=float,
|
158
158
|
default=20.0,
|
159
|
-
help="WebSocket ping interval",
|
159
|
+
help="WebSocket ping interval in seconds.",
|
160
160
|
show_default=True,
|
161
161
|
)
|
162
162
|
@click.option(
|
163
163
|
"--ws-ping-timeout",
|
164
164
|
type=float,
|
165
165
|
default=20.0,
|
166
|
-
help="WebSocket ping timeout",
|
166
|
+
help="WebSocket ping timeout in seconds.",
|
167
167
|
show_default=True,
|
168
168
|
)
|
169
169
|
@click.option(
|
@@ -465,7 +465,7 @@ def main(
|
|
465
465
|
|
466
466
|
|
467
467
|
def run(
|
468
|
-
app: typing.Union["ASGIApplication", typing.Callable, str],
|
468
|
+
app: typing.Union["ASGIApplication", typing.Callable[..., typing.Any], str],
|
469
469
|
*,
|
470
470
|
host: str = "127.0.0.1",
|
471
471
|
port: int = 8000,
|
@@ -487,7 +487,7 @@ def run(
|
|
487
487
|
reload_excludes: typing.Optional[typing.Union[typing.List[str], str]] = None,
|
488
488
|
reload_delay: float = 0.25,
|
489
489
|
workers: typing.Optional[int] = None,
|
490
|
-
env_file:
|
490
|
+
env_file: "str | os.PathLike[str] | None" = None,
|
491
491
|
log_config: typing.Optional[
|
492
492
|
typing.Union[typing.Dict[str, typing.Any], str]
|
493
493
|
] = LOGGING_CONFIG,
|
@@ -504,7 +504,7 @@ def run(
|
|
504
504
|
timeout_keep_alive: int = 5,
|
505
505
|
timeout_graceful_shutdown: typing.Optional[int] = None,
|
506
506
|
ssl_keyfile: typing.Optional[str] = None,
|
507
|
-
ssl_certfile:
|
507
|
+
ssl_certfile: "str | os.PathLike[str] | None" = None,
|
508
508
|
ssl_keyfile_password: typing.Optional[str] = None,
|
509
509
|
ssl_version: int = SSL_PROTOCOL_VERSION,
|
510
510
|
ssl_cert_reqs: int = ssl.CERT_NONE,
|
@@ -29,6 +29,8 @@ from uvicorn._types import (
|
|
29
29
|
WebSocketConnectEvent,
|
30
30
|
WebSocketDisconnectEvent,
|
31
31
|
WebSocketReceiveEvent,
|
32
|
+
WebSocketResponseBodyEvent,
|
33
|
+
WebSocketResponseStartEvent,
|
32
34
|
WebSocketScope,
|
33
35
|
WebSocketSendEvent,
|
34
36
|
)
|
@@ -196,6 +198,7 @@ class WebSocketProtocol(WebSocketServerProtocol):
|
|
196
198
|
"headers": asgi_headers,
|
197
199
|
"subprotocols": subprotocols,
|
198
200
|
"state": self.app_state.copy(),
|
201
|
+
"extensions": {"websocket.http.response": {}},
|
199
202
|
}
|
200
203
|
task = self.loop.create_task(self.run_asgi())
|
201
204
|
task.add_done_callback(self.on_task_complete)
|
@@ -302,14 +305,31 @@ class WebSocketProtocol(WebSocketServerProtocol):
|
|
302
305
|
self.handshake_started_event.set()
|
303
306
|
self.closed_event.set()
|
304
307
|
|
308
|
+
elif message_type == "websocket.http.response.start":
|
309
|
+
message = cast("WebSocketResponseStartEvent", message)
|
310
|
+
self.logger.info(
|
311
|
+
'%s - "WebSocket %s" %d',
|
312
|
+
self.scope["client"],
|
313
|
+
get_path_with_query_string(self.scope),
|
314
|
+
message["status"],
|
315
|
+
)
|
316
|
+
# websockets requires the status to be an enum. look it up.
|
317
|
+
status = http.HTTPStatus(message["status"])
|
318
|
+
headers = [
|
319
|
+
(name.decode("latin-1"), value.decode("latin-1"))
|
320
|
+
for name, value in message.get("headers", [])
|
321
|
+
]
|
322
|
+
self.initial_response = (status, headers, b"")
|
323
|
+
self.handshake_started_event.set()
|
324
|
+
|
305
325
|
else:
|
306
326
|
msg = (
|
307
|
-
"Expected ASGI message 'websocket.accept'
|
308
|
-
"but got '%s'."
|
327
|
+
"Expected ASGI message 'websocket.accept', 'websocket.close', "
|
328
|
+
"or 'websocket.http.response.start' but got '%s'."
|
309
329
|
)
|
310
330
|
raise RuntimeError(msg % message_type)
|
311
331
|
|
312
|
-
elif not self.closed_event.is_set():
|
332
|
+
elif not self.closed_event.is_set() and self.initial_response is None:
|
313
333
|
await self.handshake_completed_event.wait()
|
314
334
|
|
315
335
|
if message_type == "websocket.send":
|
@@ -333,8 +353,25 @@ class WebSocketProtocol(WebSocketServerProtocol):
|
|
333
353
|
)
|
334
354
|
raise RuntimeError(msg % message_type)
|
335
355
|
|
356
|
+
elif self.initial_response is not None:
|
357
|
+
if message_type == "websocket.http.response.body":
|
358
|
+
message = cast("WebSocketResponseBodyEvent", message)
|
359
|
+
body = self.initial_response[2] + message["body"]
|
360
|
+
self.initial_response = self.initial_response[:2] + (body,)
|
361
|
+
if not message.get("more_body", False):
|
362
|
+
self.closed_event.set()
|
363
|
+
else:
|
364
|
+
msg = (
|
365
|
+
"Expected ASGI message 'websocket.http.response.body' "
|
366
|
+
"but got '%s'."
|
367
|
+
)
|
368
|
+
raise RuntimeError(msg % message_type)
|
369
|
+
|
336
370
|
else:
|
337
|
-
msg =
|
371
|
+
msg = (
|
372
|
+
"Unexpected ASGI message '%s', after sending 'websocket.close' "
|
373
|
+
"or response already completed."
|
374
|
+
)
|
338
375
|
raise RuntimeError(msg % message_type)
|
339
376
|
|
340
377
|
async def asgi_receive(
|
@@ -364,13 +401,6 @@ class WebSocketProtocol(WebSocketServerProtocol):
|
|
364
401
|
return {"type": "websocket.disconnect", "code": 1012}
|
365
402
|
return {"type": "websocket.disconnect", "code": exc.code}
|
366
403
|
|
367
|
-
msg: WebSocketReceiveEvent = { # type: ignore[typeddict-item]
|
368
|
-
"type": "websocket.receive"
|
369
|
-
}
|
370
|
-
|
371
404
|
if isinstance(data, str):
|
372
|
-
|
373
|
-
|
374
|
-
msg["bytes"] = data
|
375
|
-
|
376
|
-
return msg
|
405
|
+
return {"type": "websocket.receive", "text": data}
|
406
|
+
return {"type": "websocket.receive", "bytes": data}
|
@@ -15,7 +15,8 @@ from uvicorn._types import (
|
|
15
15
|
WebSocketAcceptEvent,
|
16
16
|
WebSocketCloseEvent,
|
17
17
|
WebSocketEvent,
|
18
|
-
|
18
|
+
WebSocketResponseBodyEvent,
|
19
|
+
WebSocketResponseStartEvent,
|
19
20
|
WebSocketScope,
|
20
21
|
WebSocketSendEvent,
|
21
22
|
)
|
@@ -64,6 +65,9 @@ class WSProtocol(asyncio.Protocol):
|
|
64
65
|
self.handshake_complete = False
|
65
66
|
self.close_sent = False
|
66
67
|
|
68
|
+
# Rejection state
|
69
|
+
self.response_started = False
|
70
|
+
|
67
71
|
self.conn = wsproto.WSConnection(connection_type=ConnectionType.SERVER)
|
68
72
|
|
69
73
|
self.read_paused = False
|
@@ -172,6 +176,7 @@ class WSProtocol(asyncio.Protocol):
|
|
172
176
|
"headers": headers,
|
173
177
|
"subprotocols": event.subprotocols,
|
174
178
|
"state": self.app_state.copy(),
|
179
|
+
"extensions": {"websocket.http.response": {}},
|
175
180
|
}
|
176
181
|
self.queue.put_nowait({"type": "websocket.connect"})
|
177
182
|
task = self.loop.create_task(self.run_asgi())
|
@@ -181,11 +186,7 @@ class WSProtocol(asyncio.Protocol):
|
|
181
186
|
def handle_text(self, event: events.TextMessage) -> None:
|
182
187
|
self.text += event.data
|
183
188
|
if event.message_finished:
|
184
|
-
|
185
|
-
"type": "websocket.receive",
|
186
|
-
"text": self.text,
|
187
|
-
}
|
188
|
-
self.queue.put_nowait(msg)
|
189
|
+
self.queue.put_nowait({"type": "websocket.receive", "text": self.text})
|
189
190
|
self.text = ""
|
190
191
|
if not self.read_paused:
|
191
192
|
self.read_paused = True
|
@@ -195,11 +196,7 @@ class WSProtocol(asyncio.Protocol):
|
|
195
196
|
self.bytes += event.data
|
196
197
|
# todo: we may want to guard the size of self.bytes and self.text
|
197
198
|
if event.message_finished:
|
198
|
-
|
199
|
-
"type": "websocket.receive",
|
200
|
-
"bytes": self.bytes,
|
201
|
-
}
|
202
|
-
self.queue.put_nowait(msg)
|
199
|
+
self.queue.put_nowait({"type": "websocket.receive", "bytes": self.bytes})
|
203
200
|
self.bytes = b""
|
204
201
|
if not self.read_paused:
|
205
202
|
self.read_paused = True
|
@@ -215,6 +212,8 @@ class WSProtocol(asyncio.Protocol):
|
|
215
212
|
self.transport.write(self.conn.send(event.response()))
|
216
213
|
|
217
214
|
def send_500_response(self) -> None:
|
215
|
+
if self.response_started or self.handshake_complete:
|
216
|
+
return # we cannot send responses anymore
|
218
217
|
headers = [
|
219
218
|
(b"content-type", b"text/plain; charset=utf-8"),
|
220
219
|
(b"connection", b"close"),
|
@@ -234,8 +233,7 @@ class WSProtocol(asyncio.Protocol):
|
|
234
233
|
result = await self.app(self.scope, self.receive, self.send)
|
235
234
|
except BaseException:
|
236
235
|
self.logger.exception("Exception in ASGI application\n")
|
237
|
-
|
238
|
-
self.send_500_response()
|
236
|
+
self.send_500_response()
|
239
237
|
self.transport.close()
|
240
238
|
else:
|
241
239
|
if not self.handshake_complete:
|
@@ -291,14 +289,37 @@ class WSProtocol(asyncio.Protocol):
|
|
291
289
|
self.transport.write(output)
|
292
290
|
self.transport.close()
|
293
291
|
|
292
|
+
elif message_type == "websocket.http.response.start":
|
293
|
+
message = typing.cast("WebSocketResponseStartEvent", message)
|
294
|
+
# ensure status code is in the valid range
|
295
|
+
if not (100 <= message["status"] < 600):
|
296
|
+
msg = "Invalid HTTP status code '%d' in response."
|
297
|
+
raise RuntimeError(msg % message["status"])
|
298
|
+
self.logger.info(
|
299
|
+
'%s - "WebSocket %s" %d',
|
300
|
+
self.scope["client"],
|
301
|
+
get_path_with_query_string(self.scope),
|
302
|
+
message["status"],
|
303
|
+
)
|
304
|
+
self.handshake_complete = True
|
305
|
+
event = events.RejectConnection(
|
306
|
+
status_code=message["status"],
|
307
|
+
headers=list(message["headers"]),
|
308
|
+
has_body=True,
|
309
|
+
)
|
310
|
+
output = self.conn.send(event)
|
311
|
+
self.transport.write(output)
|
312
|
+
self.response_started = True
|
313
|
+
|
294
314
|
else:
|
295
315
|
msg = (
|
296
|
-
"Expected ASGI message 'websocket.accept'
|
316
|
+
"Expected ASGI message 'websocket.accept', 'websocket.close' "
|
317
|
+
"or 'websocket.http.response.start' "
|
297
318
|
"but got '%s'."
|
298
319
|
)
|
299
320
|
raise RuntimeError(msg % message_type)
|
300
321
|
|
301
|
-
elif not self.close_sent:
|
322
|
+
elif not self.close_sent and not self.response_started:
|
302
323
|
if message_type == "websocket.send":
|
303
324
|
message = typing.cast("WebSocketSendEvent", message)
|
304
325
|
bytes_data = message.get("bytes")
|
@@ -329,6 +350,29 @@ class WSProtocol(asyncio.Protocol):
|
|
329
350
|
" but got '%s'."
|
330
351
|
)
|
331
352
|
raise RuntimeError(msg % message_type)
|
353
|
+
elif self.response_started:
|
354
|
+
if message_type == "websocket.http.response.body":
|
355
|
+
message = typing.cast("WebSocketResponseBodyEvent", message)
|
356
|
+
body_finished = not message.get("more_body", False)
|
357
|
+
reject_data = events.RejectData(
|
358
|
+
data=message["body"], body_finished=body_finished
|
359
|
+
)
|
360
|
+
output = self.conn.send(reject_data)
|
361
|
+
self.transport.write(output)
|
362
|
+
|
363
|
+
if body_finished:
|
364
|
+
self.queue.put_nowait(
|
365
|
+
{"type": "websocket.disconnect", "code": 1006}
|
366
|
+
)
|
367
|
+
self.close_sent = True
|
368
|
+
self.transport.close()
|
369
|
+
|
370
|
+
else:
|
371
|
+
msg = (
|
372
|
+
"Expected ASGI message 'websocket.http.response.body' "
|
373
|
+
"but got '%s'."
|
374
|
+
)
|
375
|
+
raise RuntimeError(msg % message_type)
|
332
376
|
|
333
377
|
else:
|
334
378
|
msg = "Unexpected ASGI message '%s', after sending 'websocket.close'."
|
@@ -43,6 +43,9 @@ class FileFilter:
|
|
43
43
|
def __call__(self, path: Path) -> bool:
|
44
44
|
for include_pattern in self.includes:
|
45
45
|
if path.match(include_pattern):
|
46
|
+
if str(path).endswith(include_pattern):
|
47
|
+
return True
|
48
|
+
|
46
49
|
for exclude_dir in self.exclude_dirs:
|
47
50
|
if exclude_dir in path.parents:
|
48
51
|
return False
|
@@ -56,6 +56,9 @@ class CustomWatcher(DefaultWatcher):
|
|
56
56
|
self.watched_files[entry.path] = False
|
57
57
|
return False
|
58
58
|
for include_pattern in self.includes:
|
59
|
+
if str(entry_path).endswith(include_pattern):
|
60
|
+
self.watched_files[entry.path] = True
|
61
|
+
return True
|
59
62
|
if entry_path.match(include_pattern):
|
60
63
|
for exclude_pattern in self.excludes:
|
61
64
|
if entry_path.match(exclude_pattern):
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: uvicorn
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.25.0
|
4
4
|
Summary: The lightning-fast ASGI server.
|
5
5
|
Project-URL: Changelog, https://github.com/encode/uvicorn/blob/master/CHANGELOG.md
|
6
6
|
Project-URL: Funding, https://github.com/sponsors/encode
|
@@ -28,11 +28,11 @@ Requires-Dist: click>=7.0
|
|
28
28
|
Requires-Dist: h11>=0.8
|
29
29
|
Requires-Dist: typing-extensions>=4.0; python_version < '3.11'
|
30
30
|
Provides-Extra: standard
|
31
|
-
Requires-Dist: colorama>=0.4; sys_platform == 'win32' and extra == 'standard'
|
31
|
+
Requires-Dist: colorama>=0.4; (sys_platform == 'win32') and extra == 'standard'
|
32
32
|
Requires-Dist: httptools>=0.5.0; extra == 'standard'
|
33
33
|
Requires-Dist: python-dotenv>=0.13; extra == 'standard'
|
34
34
|
Requires-Dist: pyyaml>=5.1; extra == 'standard'
|
35
|
-
Requires-Dist: uvloop!=0.15.0,!=0.15.1,>=0.14.0; sys_platform != 'win32' and (sys_platform != 'cygwin' and platform_python_implementation != 'PyPy') and extra == 'standard'
|
35
|
+
Requires-Dist: uvloop!=0.15.0,!=0.15.1,>=0.14.0; (sys_platform != 'win32' and (sys_platform != 'cygwin' and platform_python_implementation != 'PyPy')) and extra == 'standard'
|
36
36
|
Requires-Dist: watchfiles>=0.13; extra == 'standard'
|
37
37
|
Requires-Dist: websockets>=10.4; extra == 'standard'
|
38
38
|
Description-Content-Type: text/markdown
|
@@ -1,11 +1,11 @@
|
|
1
|
-
uvicorn/__init__.py,sha256
|
1
|
+
uvicorn/__init__.py,sha256=-GQlN0xMFpg1ntNr7QlELWI7VtfhxiUnL5A7wtIFLEQ,147
|
2
2
|
uvicorn/__main__.py,sha256=DQizy6nKP0ywhPpnCHgmRDYIMfcqZKVEzNIWQZjqtVQ,62
|
3
3
|
uvicorn/_subprocess.py,sha256=zip7kqIlWL_GG7dBnl9dVuzScnjDt97VJJNH5PJFcts,2403
|
4
|
-
uvicorn/_types.py,sha256=
|
5
|
-
uvicorn/config.py,sha256=
|
4
|
+
uvicorn/_types.py,sha256=TWRo-0difQgk-N5wNlEUnRv4mCvTn6Qi_v9jiEaSzRQ,7970
|
5
|
+
uvicorn/config.py,sha256=CLLmv45z5TVFdEh4IefRJr5rElRCi-_tfwCXF881JAI,21370
|
6
6
|
uvicorn/importer.py,sha256=rUjBcH3xCBIvuEE7Buq4uWxjAzHPjEfP1dESQyAmPpU,1174
|
7
7
|
uvicorn/logging.py,sha256=dHOiKuWbWq8jtnEGScceF9_Q_LvHoMbCDhgnaW1aBvw,4255
|
8
|
-
uvicorn/main.py,sha256=
|
8
|
+
uvicorn/main.py,sha256=R63NYRHmA4FybE_EasnCYU7zkNS2KuxBYlqfdXNHUqE,16970
|
9
9
|
uvicorn/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
10
10
|
uvicorn/server.py,sha256=n0AKrPNoh4GaHdVILXNPj5-AqmEo0w8MEDRiQ7Z6H4k,12254
|
11
11
|
uvicorn/workers.py,sha256=XKDxsZ4qrCc3adtWh6wtl3qQlExWPS0EGOsdBOvm1xg,3675
|
@@ -30,16 +30,16 @@ uvicorn/protocols/http/h11_impl.py,sha256=TRO0ubSxPTxbVyoYGsYYn8fkgflk_ExftzCb53
|
|
30
30
|
uvicorn/protocols/http/httptools_impl.py,sha256=CeuBFgxeD-A6cL6QeeBt1Ya1pbd3YAyEmj89jS2m4Gs,21673
|
31
31
|
uvicorn/protocols/websockets/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
32
32
|
uvicorn/protocols/websockets/auto.py,sha256=H7irPeGN2MdHE29hdPKwca9YTA7HaOuWdIxvRuOgRtM,548
|
33
|
-
uvicorn/protocols/websockets/websockets_impl.py,sha256=
|
34
|
-
uvicorn/protocols/websockets/wsproto_impl.py,sha256=
|
33
|
+
uvicorn/protocols/websockets/websockets_impl.py,sha256=qry8rRMY0WFfAaWKaSQYlT-4PsJ2mTWj5P9BRt6wHFw,15203
|
34
|
+
uvicorn/protocols/websockets/wsproto_impl.py,sha256=dJfZlRT8Mjmk3JUFDnBdlIypUpRjVrbnNTpKLE0kgPw,15093
|
35
35
|
uvicorn/supervisors/__init__.py,sha256=YSH0n2BiqyN5m3QaT_QAkS0DkFE2xXHpKDc4ORbh82o,670
|
36
36
|
uvicorn/supervisors/basereload.py,sha256=mVZwTaxbGCR2Jzfx60V3gEUHUWIcALoTSd15QcW4Nm8,3922
|
37
37
|
uvicorn/supervisors/multiprocess.py,sha256=b-LzO1MiEN0HyhHJGx2gYMk9-Tuv2-tgmXzyJlnn7rA,2232
|
38
38
|
uvicorn/supervisors/statreload.py,sha256=p4_6gR9wOWRT6k04DBiwtQl6GINwuKdoTZJz6afArT4,1580
|
39
|
-
uvicorn/supervisors/watchfilesreload.py,sha256=
|
40
|
-
uvicorn/supervisors/watchgodreload.py,sha256=
|
41
|
-
uvicorn-0.
|
42
|
-
uvicorn-0.
|
43
|
-
uvicorn-0.
|
44
|
-
uvicorn-0.
|
45
|
-
uvicorn-0.
|
39
|
+
uvicorn/supervisors/watchfilesreload.py,sha256=oPdzBtVpQZAlidsFZ_yJDzV4PmXc7w8k5Ilnm5-xY-Y,3013
|
40
|
+
uvicorn/supervisors/watchgodreload.py,sha256=E1hgMdnVY9fJuKJl-SglzbL4GaaErZoPQG3NcaARykY,5630
|
41
|
+
uvicorn-0.25.0.dist-info/METADATA,sha256=ullm6qK5l_nGL8wBPVu6HTgBabaI4t1MQFv-kstqjJk,6356
|
42
|
+
uvicorn-0.25.0.dist-info/WHEEL,sha256=mRYSEL3Ih6g5a_CVMIcwiF__0Ae4_gLYh01YFNwiq1k,87
|
43
|
+
uvicorn-0.25.0.dist-info/entry_points.txt,sha256=FW1w-hkc9QgwaGoovMvm0ZY73w_NcycWdGAUfDsNGxw,46
|
44
|
+
uvicorn-0.25.0.dist-info/licenses/LICENSE.md,sha256=7-Gs8-YvuZwoiw7HPlp3O3Jo70Mg_nV-qZQhTktjw3E,1526
|
45
|
+
uvicorn-0.25.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|