feat: expose Jupyter shell through web app
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import asyncio
|
||||
import unittest
|
||||
|
||||
from ipython_shell.jupyter_app import JupyterApp
|
||||
from ipython_shell.jupyter_shell import JupyterShell
|
||||
from ipython_shell.transport import InputRequest, KernelMessage
|
||||
from ipython_shell.jupyter.app import JupyterApp
|
||||
from ipython_shell.jupyter.shell import JupyterShell
|
||||
from ipython_shell.jupyter.transport import InputRequest, KernelMessage
|
||||
|
||||
|
||||
class JupyterShellTests(unittest.IsolatedAsyncioTestCase):
|
||||
@@ -48,6 +48,52 @@ class JupyterShellTests(unittest.IsolatedAsyncioTestCase):
|
||||
|
||||
|
||||
class JupyterAppTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_named_shells_have_isolated_namespaces(self):
|
||||
app = JupyterApp()
|
||||
try:
|
||||
_alpha_setup = [
|
||||
message
|
||||
async for message in app.run_code_stream(
|
||||
"alpha_only = 'alpha'",
|
||||
shell_name="alpha",
|
||||
)
|
||||
]
|
||||
beta_view = [
|
||||
message
|
||||
async for message in app.run_code_stream(
|
||||
"'alpha_only' in globals()",
|
||||
shell_name="beta",
|
||||
)
|
||||
]
|
||||
alpha_view = [
|
||||
message
|
||||
async for message in app.run_code_stream(
|
||||
"alpha_only",
|
||||
shell_name="alpha",
|
||||
)
|
||||
]
|
||||
finally:
|
||||
await app.shutdown()
|
||||
|
||||
self.assertEqual(
|
||||
next(
|
||||
message.content["data"]["text/plain"]
|
||||
for message in beta_view
|
||||
if isinstance(message, KernelMessage)
|
||||
and message.msg_type == "execute_result"
|
||||
),
|
||||
"False",
|
||||
)
|
||||
self.assertEqual(
|
||||
next(
|
||||
message.content["data"]["text/plain"]
|
||||
for message in alpha_view
|
||||
if isinstance(message, KernelMessage)
|
||||
and message.msg_type == "execute_result"
|
||||
),
|
||||
"'alpha'",
|
||||
)
|
||||
|
||||
async def test_app_routes_input_reply_to_the_call(self):
|
||||
app = JupyterApp()
|
||||
stream = app.run_code_stream(
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
import json
|
||||
import unittest
|
||||
|
||||
import httpx
|
||||
|
||||
from ipython_webapp.jupyter.app import (
|
||||
InputReply,
|
||||
app,
|
||||
reply_to_input,
|
||||
run_code,
|
||||
shell_app,
|
||||
)
|
||||
|
||||
|
||||
class JupyterWebAppTests(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_run_endpoint_streams_json_events_with_mime_data(self):
|
||||
transport = httpx.ASGITransport(app=app)
|
||||
async with httpx.AsyncClient(
|
||||
transport=transport,
|
||||
base_url="http://testserver",
|
||||
) as client:
|
||||
try:
|
||||
response = await client.post(
|
||||
"/shells/new/run",
|
||||
content="{'answer': 42}",
|
||||
headers={"content-type": "text/plain"},
|
||||
)
|
||||
finally:
|
||||
await shell_app.shutdown()
|
||||
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTrue(
|
||||
response.headers["content-type"].startswith("application/x-ndjson")
|
||||
)
|
||||
events = [json.loads(line) for line in response.text.splitlines()]
|
||||
result = next(event for event in events if event["msg_type"] == "execute_result")
|
||||
self.assertEqual(result["content"]["data"]["text/plain"], "{'answer': 42}")
|
||||
|
||||
async def test_input_request_can_be_replied_to_while_run_streams(self):
|
||||
try:
|
||||
response = await run_code("new", "answer = input('name? '); answer")
|
||||
self.assertEqual(response.media_type, "application/x-ndjson")
|
||||
events = []
|
||||
async for line in response.body_iterator:
|
||||
event = json.loads(line)
|
||||
events.append(event)
|
||||
if event["type"] == "input_request":
|
||||
reply = await reply_to_input(
|
||||
event["call_id"],
|
||||
InputReply(value="Ada"),
|
||||
)
|
||||
self.assertEqual(reply.status_code, 204)
|
||||
finally:
|
||||
await shell_app.shutdown()
|
||||
|
||||
result = next(event for event in events if event.get("msg_type") == "execute_result")
|
||||
self.assertEqual(result["content"]["data"]["text/plain"], "'Ada'")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -1,7 +1,7 @@
|
||||
import asyncio
|
||||
import unittest
|
||||
|
||||
from ipython_shell.transport import InputRequest, JupyterTransport, KernelMessage
|
||||
from ipython_shell.jupyter.transport import InputRequest, JupyterTransport, KernelMessage
|
||||
|
||||
|
||||
class TransportTests(unittest.TestCase):
|
||||
|
||||
Reference in New Issue
Block a user