mirror of
https://github.com/Textualize/textual.git
synced 2025-10-17 02:38:12 +03:00
prefer msgpack over json
This commit is contained in:
46
poetry.lock
generated
46
poetry.lock
generated
@@ -381,6 +381,14 @@ mkdocs-autorefs = ">=0.1"
|
||||
pymdown-extensions = ">=6.3"
|
||||
pytkdocs = ">=0.14.0"
|
||||
|
||||
[[package]]
|
||||
name = "msgpack"
|
||||
version = "1.0.3"
|
||||
description = "MessagePack (de)serializer."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = "*"
|
||||
|
||||
[[package]]
|
||||
name = "multidict"
|
||||
version = "6.0.2"
|
||||
@@ -765,7 +773,7 @@ testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-
|
||||
[metadata]
|
||||
lock-version = "1.1"
|
||||
python-versions = "^3.7"
|
||||
content-hash = "d801e69bdd847115e92104a8cdd51ba1f207a1b7c25c4f6c9fb88434594be975"
|
||||
content-hash = "05e80f2e4709cbc33327e1ddfaf7ae19a7f708fae251834d631317dc4cf4cd2f"
|
||||
|
||||
[metadata.files]
|
||||
aiohttp = [
|
||||
@@ -1121,6 +1129,42 @@ mkdocstrings = [
|
||||
{file = "mkdocstrings-0.17.0-py3-none-any.whl", hash = "sha256:103fc1dd58cb23b7e0a6da5292435f01b29dc6fa0ba829132537f3f556f985de"},
|
||||
{file = "mkdocstrings-0.17.0.tar.gz", hash = "sha256:75b5cfa2039aeaf3a5f5cf0aa438507b0330ce76c8478da149d692daa7213a98"},
|
||||
]
|
||||
msgpack = [
|
||||
{file = "msgpack-1.0.3-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:96acc674bb9c9be63fa8b6dabc3248fdc575c4adc005c440ad02f87ca7edd079"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2c3ca57c96c8e69c1a0d2926a6acf2d9a522b41dc4253a8945c4c6cd4981a4e3"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0a792c091bac433dfe0a70ac17fc2087d4595ab835b47b89defc8bbabcf5c73"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1c58cdec1cb5fcea8c2f1771d7b5fec79307d056874f746690bd2bdd609ab147"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2f97c0f35b3b096a330bb4a1a9247d0bd7e1f3a2eba7ab69795501504b1c2c39"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-win32.whl", hash = "sha256:36a64a10b16c2ab31dcd5f32d9787ed41fe68ab23dd66957ca2826c7f10d0b85"},
|
||||
{file = "msgpack-1.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:c1ba333b4024c17c7591f0f372e2daa3c31db495a9b2af3cf664aef3c14354f7"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:c2140cf7a3ec475ef0938edb6eb363fa704159e0bf71dde15d953bacc1cf9d7d"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6f4c22717c74d44bcd7af353024ce71c6b55346dad5e2cc1ddc17ce8c4507c6b"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:47d733a15ade190540c703de209ffbc42a3367600421b62ac0c09fde594da6ec"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7e03b06f2982aa98d4ddd082a210c3db200471da523f9ac197f2828e80e7770"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-win32.whl", hash = "sha256:3d875631ecab42f65f9dce6f55ce6d736696ced240f2634633188de2f5f21af9"},
|
||||
{file = "msgpack-1.0.3-cp36-cp36m-win_amd64.whl", hash = "sha256:40fb89b4625d12d6027a19f4df18a4de5c64f6f3314325049f219683e07e678a"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6eef0cf8db3857b2b556213d97dd82de76e28a6524853a9beb3264983391dc1a"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0d8c332f53ffff01953ad25131272506500b14750c1d0ce8614b17d098252fbc"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c0903bd93cbd34653dd63bbfcb99d7539c372795201f39d16fdfde4418de43a"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bf1e6bfed4860d72106f4e0a1ab519546982b45689937b40257cfd820650b920"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-win32.whl", hash = "sha256:d02cea2252abc3756b2ac31f781f7a98e89ff9759b2e7450a1c7a0d13302ff50"},
|
||||
{file = "msgpack-1.0.3-cp37-cp37m-win_amd64.whl", hash = "sha256:2f30dd0dc4dfe6231ad253b6f9f7128ac3202ae49edd3f10d311adc358772dba"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:f201d34dc89342fabb2a10ed7c9a9aaaed9b7af0f16a5923f1ae562b31258dea"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bb87f23ae7d14b7b3c21009c4b1705ec107cb21ee71975992f6aca571fb4a42a"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a3a5c4b16e9d0edb823fe54b59b5660cc8d4782d7bf2c214cb4b91a1940a8ef"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74da1e5fcf20ade12c6bf1baa17a2dc3604958922de8dc83cbe3eff22e8b611"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:73a80bd6eb6bcb338c1ec0da273f87420829c266379c8c82fa14c23fb586cfa1"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-win32.whl", hash = "sha256:9fce00156e79af37bb6db4e7587b30d11e7ac6a02cb5bac387f023808cd7d7f4"},
|
||||
{file = "msgpack-1.0.3-cp38-cp38-win_amd64.whl", hash = "sha256:9b6f2d714c506e79cbead331de9aae6837c8dd36190d02da74cb409b36162e8a"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:89908aea5f46ee1474cc37fbc146677f8529ac99201bc2faf4ef8edc023c2bf3"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:973ad69fd7e31159eae8f580f3f707b718b61141838321c6fa4d891c4a2cca52"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da24375ab4c50e5b7486c115a3198d207954fe10aaa5708f7b65105df09109b2"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a598d0685e4ae07a0672b59792d2cc767d09d7a7f39fd9bd37ff84e060b1a996"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e4c309a68cb5d6bbd0c50d5c71a25ae81f268c2dc675c6f4ea8ab2feec2ac4e2"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-win32.whl", hash = "sha256:494471d65b25a8751d19c83f1a482fd411d7ca7a3b9e17d25980a74075ba0e88"},
|
||||
{file = "msgpack-1.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:f01b26c2290cbd74316990ba84a14ac3d599af9cebefc543d241a66e785cf17d"},
|
||||
{file = "msgpack-1.0.3.tar.gz", hash = "sha256:51fdc7fb93615286428ee7758cecc2f374d5ff363bdd884c7ea622a7a327a81e"},
|
||||
]
|
||||
multidict = [
|
||||
{file = "multidict-6.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:0b9e95a740109c6047602f4db4da9949e6c5945cefbad34a1299775ddc9a62e2"},
|
||||
{file = "multidict-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ac0e27844758d7177989ce406acc6a83c16ed4524ebc363c1f748cba184d89d3"},
|
||||
|
||||
@@ -28,6 +28,7 @@ rich = "^12.3.0"
|
||||
click = "8.1.2"
|
||||
importlib-metadata = "^4.11.3"
|
||||
typing-extensions = { version = "^4.0.0", python = "<3.8" }
|
||||
msgpack = "^1.0.3"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
pytest = "^6.2.3"
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import base64
|
||||
import datetime
|
||||
import inspect
|
||||
import json
|
||||
import msgpack
|
||||
import pickle
|
||||
from time import time
|
||||
from asyncio import Queue, Task, QueueFull
|
||||
from io import StringIO
|
||||
from typing import Type, Any, NamedTuple
|
||||
@@ -97,7 +98,7 @@ class DevtoolsClient:
|
||||
self.update_console_task: Task | None = None
|
||||
self.console: DevtoolsConsole = DevtoolsConsole(file=StringIO())
|
||||
self.websocket: ClientWebSocketResponse | None = None
|
||||
self.log_queue: Queue[str | Type[ClientShutdown]] | None = None
|
||||
self.log_queue: Queue[str | bytes | Type[ClientShutdown]] | None = None
|
||||
self.spillover: int = 0
|
||||
|
||||
async def connect(self) -> None:
|
||||
@@ -144,7 +145,10 @@ class DevtoolsClient:
|
||||
if log is ClientShutdown:
|
||||
log_queue.task_done()
|
||||
break
|
||||
await websocket.send_str(log)
|
||||
if isinstance(log, str):
|
||||
await websocket.send_str(log)
|
||||
else:
|
||||
await websocket.send_bytes(log)
|
||||
log_queue.task_done()
|
||||
|
||||
self.log_queue_task = asyncio.create_task(send_queued_logs())
|
||||
@@ -203,17 +207,18 @@ class DevtoolsClient:
|
||||
segments = self.console.export_segments()
|
||||
|
||||
encoded_segments = self._encode_segments(segments)
|
||||
message = json.dumps(
|
||||
message: bytes | None = msgpack.packb(
|
||||
{
|
||||
"type": "client_log",
|
||||
"payload": {
|
||||
"timestamp": int(datetime.datetime.utcnow().timestamp()),
|
||||
"timestamp": int(time()),
|
||||
"path": getattr(log.caller, "filename", ""),
|
||||
"line_number": getattr(log.caller, "lineno", 0),
|
||||
"encoded_segments": encoded_segments,
|
||||
"segments": encoded_segments,
|
||||
},
|
||||
}
|
||||
)
|
||||
assert message is not None
|
||||
try:
|
||||
if self.log_queue:
|
||||
self.log_queue.put_nowait(message)
|
||||
@@ -233,8 +238,8 @@ class DevtoolsClient:
|
||||
except QueueFull:
|
||||
self.spillover += 1
|
||||
|
||||
def _encode_segments(self, segments: list[Segment]) -> str:
|
||||
"""Pickle and Base64 encode the list of Segments
|
||||
def _encode_segments(self, segments: list[Segment]) -> bytes:
|
||||
"""Pickle a list of Segments
|
||||
|
||||
Args:
|
||||
segments (list[Segment]): A list of Segments to encode
|
||||
@@ -242,6 +247,5 @@ class DevtoolsClient:
|
||||
Returns:
|
||||
str: The Segment list pickled with pickle protocol v3, then base64 encoded
|
||||
"""
|
||||
pickled = pickle.dumps(segments, protocol=3)
|
||||
encoded = base64.b64encode(pickled)
|
||||
return str(encoded, encoding="utf-8")
|
||||
pickled = pickle.dumps(segments, protocol=pickle.HIGHEST_PROTOCOL)
|
||||
return pickled
|
||||
|
||||
@@ -72,19 +72,13 @@ class DevConsoleLog:
|
||||
def __rich_console__(
|
||||
self, console: Console, options: ConsoleOptions
|
||||
) -> RenderResult:
|
||||
local_time = (
|
||||
datetime.fromtimestamp(self.unix_timestamp)
|
||||
.replace(tzinfo=timezone.utc)
|
||||
.astimezone(tz=datetime.now().astimezone().tzinfo)
|
||||
)
|
||||
timezone_name = local_time.tzname()
|
||||
local_time = datetime.fromtimestamp(self.unix_timestamp)
|
||||
table = Table.grid(expand=True)
|
||||
table.add_column()
|
||||
table.add_column()
|
||||
|
||||
file_link = escape(f"file://{Path(self.path).absolute()}")
|
||||
file_and_line = escape(f"{Path(self.path).name}:{self.line_number}")
|
||||
table.add_row(
|
||||
f"[dim]{local_time.time()} {timezone_name}",
|
||||
f"[dim]{local_time.time()}",
|
||||
Align.right(
|
||||
Text(f"{file_and_line}", style=Style(dim=True, link=file_link))
|
||||
),
|
||||
|
||||
@@ -14,6 +14,7 @@ from aiohttp.abc import Request
|
||||
from aiohttp.web_ws import WebSocketResponse
|
||||
from rich.console import Console
|
||||
from rich.markup import escape
|
||||
import msgpack
|
||||
|
||||
from textual.devtools.renderables import (
|
||||
DevConsoleLog,
|
||||
@@ -170,9 +171,9 @@ class ClientHandler:
|
||||
path = message_json["payload"]["path"]
|
||||
line_number = message_json["payload"]["line_number"]
|
||||
timestamp = message_json["payload"]["timestamp"]
|
||||
encoded_segments = message_json["payload"]["encoded_segments"]
|
||||
decoded_segments = base64.b64decode(encoded_segments)
|
||||
segments = pickle.loads(decoded_segments)
|
||||
encoded_segments = message_json["payload"]["segments"]
|
||||
# decoded_segments = base64.b64decode(encoded_segments)
|
||||
segments = pickle.loads(encoded_segments)
|
||||
message_time = time()
|
||||
if (
|
||||
last_message_time is not None
|
||||
@@ -219,21 +220,26 @@ class ClientHandler:
|
||||
await self.service.send_server_info(client_handler=self)
|
||||
async for message in self.websocket:
|
||||
message = cast(WSMessage, message)
|
||||
if message.type == WSMsgType.TEXT:
|
||||
|
||||
if message.type in (WSMsgType.TEXT, WSMsgType.BINARY):
|
||||
|
||||
try:
|
||||
message_json = json.loads(message.data)
|
||||
if isinstance(message.data, bytes):
|
||||
message = msgpack.unpackb(message.data)
|
||||
else:
|
||||
message = json.loads(message.data)
|
||||
except JSONDecodeError:
|
||||
self.service.console.print(escape(str(message.data)))
|
||||
continue
|
||||
|
||||
type = message_json.get("type")
|
||||
type = message.get("type")
|
||||
if not type:
|
||||
continue
|
||||
if (
|
||||
type in QUEUEABLE_TYPES
|
||||
and not self.service.shutdown_event.is_set()
|
||||
):
|
||||
await self.incoming_queue.put(message_json)
|
||||
await self.incoming_queue.put(message)
|
||||
elif message.type == WSMsgType.ERROR:
|
||||
self.service.console.print(
|
||||
DevConsoleNotice("Websocket error occurred", level="error")
|
||||
|
||||
Reference in New Issue
Block a user