prefer msgpack over json

This commit is contained in:
Will McGugan
2022-05-13 15:56:58 +01:00
parent 96ce4202a5
commit 2dfda6e4dc
5 changed files with 77 additions and 28 deletions

46
poetry.lock generated
View File

@@ -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"},

View File

@@ -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"

View File

@@ -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

View File

@@ -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))
),

View File

@@ -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")