org.jetbrains.kotlinx.jupyter.apiImpl.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-jupyter-kernel Show documentation
Show all versions of kotlin-jupyter-kernel Show documentation
Kotlin Jupyter kernel published as artifact
package org.jetbrains.kotlinx.jupyter
import jupyter.kotlin.JavaRuntime
import org.jetbrains.kotlinx.jupyter.api.CodeCell
import org.jetbrains.kotlinx.jupyter.api.DisplayContainer
import org.jetbrains.kotlinx.jupyter.api.DisplayResult
import org.jetbrains.kotlinx.jupyter.api.DisplayResultWithCell
import org.jetbrains.kotlinx.jupyter.api.JREInfoProvider
import org.jetbrains.kotlinx.jupyter.api.KotlinKernelVersion
import org.jetbrains.kotlinx.jupyter.api.Notebook
import org.jetbrains.kotlinx.jupyter.api.RenderersProcessor
import org.jetbrains.kotlinx.jupyter.api.ResultsAccessor
import org.jetbrains.kotlinx.jupyter.api.VariableState
import org.jetbrains.kotlinx.jupyter.api.libraries.LibraryResolutionRequest
import org.jetbrains.kotlinx.jupyter.repl.impl.SharedReplContext
class DisplayResultWrapper private constructor(
val display: DisplayResult,
override val cell: CodeCellImpl,
) : DisplayResult by display, DisplayResultWithCell {
companion object {
fun create(display: DisplayResult, cell: CodeCellImpl): DisplayResultWrapper {
return if (display is DisplayResultWrapper) DisplayResultWrapper(display.display, cell)
else DisplayResultWrapper(display, cell)
}
}
}
class DisplayContainerImpl : DisplayContainer {
private val displays: MutableMap> = mutableMapOf()
fun add(display: DisplayResultWrapper) {
val list = displays.getOrPut(display.id) { mutableListOf() }
list.add(display)
}
fun add(display: DisplayResult, cell: CodeCellImpl) {
add(DisplayResultWrapper.create(display, cell))
}
override fun getAll(): List {
return displays.flatMap { it.value }
}
override fun getById(id: String?): List {
return displays[id].orEmpty()
}
fun update(id: String?, display: DisplayResult) {
val initialDisplays = displays[id] ?: return
val updated = initialDisplays.map { DisplayResultWrapper.create(display, it.cell) }
initialDisplays.clear()
initialDisplays.addAll(updated)
}
}
class CodeCellImpl(
override val notebook: NotebookImpl,
override val id: Int,
override val internalId: Int,
override val code: String,
override val preprocessedCode: String,
override val prevCell: CodeCell?,
) : CodeCell {
var resultVal: Any? = null
override val result: Any?
get() = resultVal
private var isStreamOutputUpToDate: Boolean = true
private var collectedStreamOutput: String = ""
private val streamBuilder = StringBuilder()
fun appendStreamOutput(output: String) {
isStreamOutputUpToDate = false
streamBuilder.append(output)
}
override val streamOutput: String
get() {
if (!isStreamOutputUpToDate) {
isStreamOutputUpToDate = true
collectedStreamOutput = streamBuilder.toString()
}
return collectedStreamOutput
}
override val displays = DisplayContainerImpl()
fun addDisplay(display: DisplayResult) {
val wrapper = DisplayResultWrapper.create(display, this)
displays.add(wrapper)
notebook.displays.add(wrapper)
}
}
class EvalData(
val executionCounter: Int,
val rawCode: String,
) {
constructor(evalRequestData: EvalRequestData) : this(evalRequestData.jupyterId, evalRequestData.code)
}
class NotebookImpl(
private val runtimeProperties: ReplRuntimeProperties,
) : Notebook {
private val cells = hashMapOf()
internal var sharedReplContext: SharedReplContext? = null
override val cellsList: Collection
get() = cells.values
override val variablesState: Map get() {
return sharedReplContext?.evaluator?.variablesHolder
?: throw IllegalStateException("Evaluator is not initialized yet")
}
override val cellVariables: Map> get() {
return sharedReplContext?.evaluator?.cellVariables
?: throw IllegalStateException("Evaluator is not initialized yet")
}
override val resultsAccessor = ResultsAccessor { getResult(it) }
override fun getCell(id: Int): CodeCellImpl {
return cells[id] ?: throw ArrayIndexOutOfBoundsException(
"There is no cell with number '$id'"
)
}
override fun getResult(id: Int): Any? {
return getCell(id).result
}
private val history = arrayListOf()
private var mainCellCreated = false
val displays = DisplayContainerImpl()
override fun getAllDisplays(): List {
return displays.getAll()
}
override fun getDisplaysById(id: String?): List {
return displays.getById(id)
}
override val kernelVersion: KotlinKernelVersion
get() = runtimeProperties.version ?: throw IllegalStateException("Kernel version is not known")
override val jreInfo: JREInfoProvider
get() = JavaRuntime
fun variablesReportAsHTML(): String {
return generateHTMLVarsReport(variablesState)
}
fun variablesReport(): String {
return if (variablesState.isEmpty()) ""
else {
buildString {
append("Visible vars: \n")
variablesState.forEach { (name, currentState) ->
append("\t$name : ${currentState.stringValue}\n")
}
}
}
}
fun addCell(
internalId: Int,
preprocessedCode: String,
data: EvalData,
): CodeCellImpl {
val cell = CodeCellImpl(this, data.executionCounter, internalId, data.rawCode, preprocessedCode, lastCell)
cells[data.executionCounter] = cell
history.add(cell)
mainCellCreated = true
return cell
}
fun beginEvalSession() {
mainCellCreated = false
}
override fun history(before: Int): CodeCellImpl? {
val offset = if (mainCellCreated) 1 else 0
return history.getOrNull(history.size - offset - before)
}
override val currentCell: CodeCellImpl?
get() = history(0)
override val lastCell: CodeCellImpl?
get() = history(1)
override val renderersProcessor: RenderersProcessor
get() = sharedReplContext?.renderersProcessor ?: throw IllegalStateException("Type renderers processor is not initialized yet")
override val libraryRequests: Collection
get() = sharedReplContext?.librariesProcessor?.requests.orEmpty()
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy