This commit is contained in:
lda
2026-08-30 21:20:37 +07:00 Verified
parent 56e1b96077
commit b48443cdc3
6 changed files with 30 additions and 25 deletions
+8 -8
View File
@@ -1,13 +1,14 @@
"""Small, side-effect-free API for the in-process IPython runner.""" """Small, side-effect-free API for the in-process IPython runner."""
from .app import App from .app import App
from .jupyter.app import JupyterApp
from .jupyter.shell import JupyterShell
from .events import ( from .events import (
error_from_execution_result, error_from_execution_result,
event_from_execution_result, event_from_execution_result,
event_from_history_output, event_from_history_output,
) )
from .jupyter.app import JupyterApp
from .jupyter.shell import JupyterShell
from .jupyter.transport import InputRequest, JupyterTransport, KernelMessage
from .models import ( from .models import (
AppInfo, AppInfo,
CallError, CallError,
@@ -28,16 +29,10 @@ from .shell import (
run_cell_and_collect, run_cell_and_collect,
setup_shell, setup_shell,
) )
from .jupyter.transport import InputRequest, JupyterTransport, KernelMessage
from .utils import generate_good_names from .utils import generate_good_names
__all__ = [ __all__ = [
"App", "App",
"JupyterApp",
"JupyterShell",
"JupyterTransport",
"InputRequest",
"KernelMessage",
"AppInfo", "AppInfo",
"CallError", "CallError",
"CallEvent", "CallEvent",
@@ -46,7 +41,12 @@ __all__ = [
"CallResponse", "CallResponse",
"CallResult", "CallResult",
"CallResultResponse", "CallResultResponse",
"InputRequest",
"JSONValue", "JSONValue",
"JupyterApp",
"JupyterShell",
"JupyterTransport",
"KernelMessage",
"Shell", "Shell",
"ShellInfo", "ShellInfo",
"ShellStatus", "ShellStatus",
+1 -1
View File
@@ -1,9 +1,9 @@
from collections.abc import AsyncIterator from collections.abc import AsyncIterator
from uuid import uuid4 from uuid import uuid4
from ..utils import generate_good_names
from .shell import JupyterShell from .shell import JupyterShell
from .transport import InputRequest, KernelMessage from .transport import InputRequest, KernelMessage
from ..utils import generate_good_names
class JupyterApp: class JupyterApp:
+3 -1
View File
@@ -97,7 +97,9 @@ class JupyterTransport:
msg_type=message["msg_type"], msg_type=message["msg_type"],
parent_id=parent_id, parent_id=parent_id,
content=dict(message.get("content", {})), content=dict(message.get("content", {})),
buffers=[bytes(buffer) for buffer in message.get("buffers", [])], buffers=[
bytes(buffer) for buffer in message.get("buffers", [])
],
) )
if decoded.msg_type == "execute_reply": if decoded.msg_type == "execute_reply":
# The shell reply and IOPub messages use different # The shell reply and IOPub messages use different
+3 -1
View File
@@ -36,7 +36,9 @@ def serialize_event(event: KernelMessage | InputRequest) -> dict[str, object]:
"msg_type": event.msg_type, "msg_type": event.msg_type,
"parent_id": event.parent_id, "parent_id": event.parent_id,
"content": event.content, "content": event.content,
"buffers": [base64.b64encode(buffer).decode("ascii") for buffer in event.buffers], "buffers": [
base64.b64encode(buffer).decode("ascii") for buffer in event.buffers
],
} }
+6 -2
View File
@@ -47,7 +47,9 @@ class JupyterWebAppTests(unittest.IsolatedAsyncioTestCase):
response.headers["content-type"].startswith("application/x-ndjson") response.headers["content-type"].startswith("application/x-ndjson")
) )
events = [json.loads(line) for line in response.text.splitlines()] events = [json.loads(line) for line in response.text.splitlines()]
result = next(event for event in events if event["msg_type"] == "execute_result") result = next(
event for event in events if event["msg_type"] == "execute_result"
)
self.assertEqual(result["content"]["data"]["text/plain"], "{'answer': 42}") self.assertEqual(result["content"]["data"]["text/plain"], "{'answer': 42}")
async def test_input_request_can_be_replied_to_while_run_streams(self): async def test_input_request_can_be_replied_to_while_run_streams(self):
@@ -67,7 +69,9 @@ class JupyterWebAppTests(unittest.IsolatedAsyncioTestCase):
finally: finally:
await shell_app.shutdown() await shell_app.shutdown()
result = next(event for event in events if event.get("msg_type") == "execute_result") result = next(
event for event in events if event.get("msg_type") == "execute_result"
)
self.assertEqual(result["content"]["data"]["text/plain"], "'Ada'") self.assertEqual(result["content"]["data"]["text/plain"], "'Ada'")
+9 -12
View File
@@ -1,7 +1,11 @@
import asyncio import asyncio
import unittest import unittest
from ipython_shell.jupyter.transport import InputRequest, JupyterTransport, KernelMessage from ipython_shell.jupyter.transport import (
InputRequest,
JupyterTransport,
KernelMessage,
)
class TransportTests(unittest.TestCase): class TransportTests(unittest.TestCase):
@@ -24,9 +28,7 @@ class AsyncTransportTests(unittest.IsolatedAsyncioTestCase):
await transport.start() await transport.start()
try: try:
call_id = await transport.execute("2 + 2") call_id = await transport.execute("2 + 2")
messages = [ messages = [message async for message in transport.messages_for(call_id)]
message async for message in transport.messages_for(call_id)
]
finally: finally:
await transport.shutdown() await transport.shutdown()
@@ -72,19 +74,14 @@ class AsyncTransportTests(unittest.IsolatedAsyncioTestCase):
await transport.start() await transport.start()
try: try:
call_id = await transport.execute( call_id = await transport.execute(
"import matplotlib.pyplot as plt\n" "import matplotlib.pyplot as plt\nplt.plot([1, 2, 3], [4, 5, 6])"
"plt.plot([1, 2, 3], [4, 5, 6])"
) )
messages = [ messages = [message async for message in transport.messages_for(call_id)]
message async for message in transport.messages_for(call_id)
]
finally: finally:
await transport.shutdown() await transport.shutdown()
display = next( display = next(
message message for message in messages if message.msg_type == "display_data"
for message in messages
if message.msg_type == "display_data"
) )
self.assertIn("image/png", display.content["data"]) self.assertIn("image/png", display.content["data"])