Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add execution start and end time metadata for code cells #29

Merged
merged 17 commits into from
Jan 27, 2025
Merged
12 changes: 10 additions & 2 deletions jupyter_server_nbmodel/handlers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from dataclasses import asdict, dataclass
from functools import partial
from http import HTTPStatus
from datetime import datetime, timezone

import jupyter_server
import jupyter_server.services
Expand Down Expand Up @@ -123,7 +124,6 @@ async def _get_ycell(
raise KeyError(
msg,
)

return ycell


Expand Down Expand Up @@ -219,6 +219,7 @@ async def _execute_snippet(
The execution status and outputs.
"""
ycell = None
time_info = {}
if metadata is not None:
ycell = await _get_ycell(ydoc, metadata)
if ycell is not None:
Expand All @@ -227,7 +228,11 @@ async def _execute_snippet(
del ycell["outputs"][:]
ycell["execution_count"] = None
ycell["execution_state"] = "running"

if metadata["record_timing"]:
time_info = ycell["metadata"].get("execution",{})
time_info["start_time"] = datetime.now(timezone.utc).isoformat()[:-6]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the metadata I think we will want to match the exact identifiers as used on the frontend, so instead of start_time we would use shell.execute_reply.started and for end time - shell.execute_reply - although these are less readable, it would make jupyter-server-nbmodel a drop-in replacement and compatible with existing extensions like jupyterlab-execute-time.

There also should be execution_failed for when the execution fails.

ycell["metadata"]["execution"] = time_info

outputs = []

# FIXME we don't check if the session is consistent (aka the kernel is linked to the document)
Expand All @@ -247,6 +252,9 @@ async def _execute_snippet(
with ycell.doc.transaction():
ycell["execution_count"] = reply_content.get("execution_count")
ycell["execution_state"] = "idle"
if metadata["record_timing"]:
time_info["end_time"] = datetime.now(timezone.utc).isoformat()[:-6]
ycell["metadata"]["execution"] = time_info

return {
"status": reply_content["status"],
Expand Down
3 changes: 2 additions & 1 deletion src/executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,13 @@ export class NotebookCellServerExecutor implements INotebookCellExecutor {
const code = cell.model.sharedModel.getSource();
const cellId = cell.model.sharedModel.getId();
const documentId = notebook.sharedModel.getState('document_id');
const { recordTiming } = notebookConfig

const init = {
method: 'POST',
body: JSON.stringify({
code,
metadata: { cell_id: cellId, document_id: documentId }
metadata: { cell_id: cellId, document_id: documentId, record_timing: recordTiming }
})
};
onCellExecutionScheduled({ cell });
Expand Down
Loading