init research

This commit is contained in:
2026-02-08 11:20:43 -10:00
commit bdf064f54d
3041 changed files with 1592200 additions and 0 deletions
+14
View File
@@ -0,0 +1,14 @@
## :dataframe-openapi
This **experimental** module, published as `dataframe-openapi` contains some functions to be able to use auto-generated
data schemas from OpenAPI 3.0.0 specifications. This module is a sister module to
[`dataframe-openapi-generator`](../dataframe-openapi-generator):
- `dataframe-openapi-generator` is used as a dependency of the Gradle plugin and Jupyter plugin to be able to generate
data schemas from OpenAPI specifications. In the Gradle plugin it adds support for the `dataschemas {}` DSL and the
`@file:ImportDataSchema()` annotation. In Jupyter, it adds support for the `importDataSchema()` function.
- `dataframe-openapi` must be used as a dependency of a user-project to be able to use the generated data schemas.
See [Import OpenAPI Schemas in Gradle project](https://kotlin.github.io/dataframe/schemasimportopenapigradle.html) and
[Import Data Schemas, e.g. from OpenAPI, in Jupyter](https://kotlin.github.io/dataframe/schemasimportopenapijupyter.html)
for more information about how to use it.
+21
View File
@@ -0,0 +1,21 @@
public abstract interface class org/jetbrains/kotlinx/dataframe/io/AdditionalProperty : org/jetbrains/kotlinx/dataframe/api/NameValueProperty {
public static final field Companion Lorg/jetbrains/kotlinx/dataframe/io/AdditionalProperty$Companion;
public abstract fun getName ()Ljava/lang/String;
public abstract fun getValue ()Ljava/lang/Object;
}
public final class org/jetbrains/kotlinx/dataframe/io/AdditionalProperty$Companion {
}
public final class org/jetbrains/kotlinx/dataframe/io/AdditionalPropertyKt {
public static final fun AdditionalProperty_key (Lorg/jetbrains/kotlinx/dataframe/ColumnsScope;)Lorg/jetbrains/kotlinx/dataframe/DataColumn;
public static final fun AdditionalProperty_key (Lorg/jetbrains/kotlinx/dataframe/DataRow;)Ljava/lang/String;
public static final fun NullableAdditionalProperty_key (Lorg/jetbrains/kotlinx/dataframe/ColumnsScope;)Lorg/jetbrains/kotlinx/dataframe/DataColumn;
public static final fun NullableAdditionalProperty_key (Lorg/jetbrains/kotlinx/dataframe/DataRow;)Ljava/lang/String;
public static final fun getKey (Lorg/jetbrains/kotlinx/dataframe/io/AdditionalProperty;)Ljava/lang/String;
}
public final class org/jetbrains/kotlinx/dataframe/io/ConvertDataRowsWithOpenApiKt {
public static final fun convertDataRowsWithOpenApi (Lorg/jetbrains/kotlinx/dataframe/api/ConvertSchemaDsl;)V
}
+24
View File
@@ -0,0 +1,24 @@
plugins {
with(convention.plugins) {
alias(kotlinJvm8)
}
with(libs.plugins) {
alias(publisher)
alias(binary.compatibility.validator)
}
}
group = "org.jetbrains.kotlinx"
dependencies {
api(projects.core)
}
kotlinPublications {
publication {
publicationName = "dataframeOpenApi"
artifactId = project.name
description = "OpenAPI support for Kotlin DataFrame"
packageName = artifactId
}
}
@@ -0,0 +1,49 @@
package org.jetbrains.kotlinx.dataframe.io
import org.jetbrains.kotlinx.dataframe.ColumnsScope
import org.jetbrains.kotlinx.dataframe.DataColumn
import org.jetbrains.kotlinx.dataframe.DataRow
import org.jetbrains.kotlinx.dataframe.annotations.DataSchema
import org.jetbrains.kotlinx.dataframe.api.NameValueProperty
import org.jetbrains.kotlinx.dataframe.api.cast
/**
* A [DataSchema] interface can implement this if it represents a map-like data schema (so name: value).
* Used in OpenAPI to represent objects with 'just' additionalProperties of a certain type.
*/
public interface AdditionalProperty<T> : NameValueProperty<T> {
/** Key of the property. */
override val name: String
/** Value of the property. */
override val value: T
public companion object
}
private const val DEPRECATION_MESSAGE = "'key' has been renamed to 'name'."
@Deprecated(DEPRECATION_MESSAGE, ReplaceWith("name"))
public val ColumnsScope<AdditionalProperty<*>>.key: DataColumn<String>
@JvmName("AdditionalProperty_key")
get() = get("name").cast()
@Deprecated(DEPRECATION_MESSAGE, ReplaceWith("name"))
public val ColumnsScope<AdditionalProperty<*>?>.key: DataColumn<String?>
@JvmName("NullableAdditionalProperty_key")
get() = get("name").cast()
@Deprecated(DEPRECATION_MESSAGE, ReplaceWith("name"))
public val DataRow<AdditionalProperty<*>>.key: String
@JvmName("AdditionalProperty_key")
get() = get("name") as String
@Deprecated(DEPRECATION_MESSAGE, ReplaceWith("name"))
public val DataRow<AdditionalProperty<*>?>.key: String?
@JvmName("NullableAdditionalProperty_key")
get() = get("name") as String?
@Deprecated(DEPRECATION_MESSAGE, ReplaceWith("name"))
public val AdditionalProperty<*>.key: String
get() = name
@@ -0,0 +1,63 @@
package org.jetbrains.kotlinx.dataframe.io
import org.jetbrains.kotlinx.dataframe.DataFrame
import org.jetbrains.kotlinx.dataframe.DataRow
import org.jetbrains.kotlinx.dataframe.api.ConvertSchemaDsl
import org.jetbrains.kotlinx.dataframe.api.convert
import org.jetbrains.kotlinx.dataframe.api.convertTo
import org.jetbrains.kotlinx.dataframe.api.with
import kotlin.reflect.KType
import kotlin.reflect.jvm.jvmErasure
import kotlin.reflect.typeOf
/**
* Function to be used in [ConvertSchemaDsl] ([DataFrame.convertTo]) to help convert a DataFrame to adhere to an
* OpenApi schema. Is used in generated OpenAPI code.
*/
public fun ConvertSchemaDsl<*>.convertDataRowsWithOpenApi() {
// Convert DataRow to Any if the schema requires the types to be erased.
convert<DataRow<*>>().with<_, Any?> { it }
// Provide converter for (recursive) List<DataFrame<>>
convertIf({ fromType, toSchema ->
val (fromIsRecursiveListOfDataFrame, fromDepth) = fromType.isRecursiveListOfDataFrame()
val (toIsRecursiveListOfDataFrame, toDepth) = toSchema.type.isRecursiveListOfDataFrame()
fromIsRecursiveListOfDataFrame && toIsRecursiveListOfDataFrame && fromDepth == toDepth
}) {
try {
it.convertRecursiveListOfDataFrame(toSchema.type) {
convertDataRowsWithOpenApi()
}
} catch (_: Exception) {
it
}
}
}
/**
* @receiver [KType] to check if it is a recursive list of [DataFrame]s
* @return [Pair] of result and the recursive depth.
* `true` if Receiver is a recursive list of [DataFrame]s, like [List]<[List]<[DataFrame]<*>>>
*/
private fun KType.isRecursiveListOfDataFrame(depth: Int = 0): Pair<Boolean, Int> =
when (jvmErasure) {
typeOf<List<*>>().jvmErasure -> arguments[0].type?.isRecursiveListOfDataFrame(depth + 1) ?: (false to depth)
typeOf<DataFrame<*>>().jvmErasure -> true to depth
typeOf<DataFrame<*>?>().jvmErasure -> true to depth
else -> false to depth
}
/**
* @receiver Recursive [List] of [DataFrame]s, like [List]<[List]<[DataFrame]<*>>>, for which to convert the [DataFrame]s.
* @param type Type to which to convert the [DataFrame]s.
* @param convertTo Optional [ConvertSchemaDsl] to use for the conversion.
* @return Receiver with converted [DataFrame]s.
*/
private fun Any?.convertRecursiveListOfDataFrame(type: KType, convertTo: ConvertSchemaDsl<*>.() -> Unit = {}): Any? =
when (this) {
is List<*> -> map { it?.convertRecursiveListOfDataFrame(type.arguments[0].type!!, convertTo) }
is DataFrame<*> -> convertTo(schemaType = type.arguments[0].type!!, body = convertTo)
null -> null
else -> throw IllegalArgumentException("$this is not a List or DataFrame")
}