Skip to content

Commit 6d5e61d

Browse files
committed
Add automatic libraries list generation
1 parent 4175906 commit 6d5e61d

30 files changed

+367
-15
lines changed

README.md .github/README.md

+16-9
Original file line numberDiff line numberDiff line change
@@ -157,20 +157,26 @@ Other options are resolving library descriptor from a local file or from remote
157157
```
158158

159159
List of supported libraries:
160+
- [dataframe](https://github.com/nikitinas/krangl-typed) - Kotlin framework for structured data processing
161+
- [deeplearning4j](https://github.com/eclipse/deeplearning4j) - Deep learning library for the JVM
162+
- [deeplearning4j-cuda](https://github.com/eclipse/deeplearning4j) - Deep learning library for the JVM (CUDA support)
163+
- default - Default imports: dataframe and lets-plot libraries
164+
- [exposed](https://github.com/JetBrains/Exposed) - Kotlin SQL framework
165+
- [fuel](https://github.com/kittinunf/fuel) - HTTP networking library
166+
- [gral](https://github.com/eseifert/gral) - Java library for displaying plots
167+
- [khttp](https://github.com/jkcclemens/khttp) - HTTP networking library
160168
- [klaxon](https://github.com/cbeust/klaxon) - JSON parser for Kotlin
161-
- [lets-plot](https://github.com/JetBrains/lets-plot-kotlin) - ggplot-like interactive visualization for Kotlin
162-
- [krangl](https://github.com/holgerbrandl/krangl) - Kotlin DSL for data wrangling
169+
- [kmath](https://github.com/mipt-npm/kmath) - Kotlin mathematical library analogous to NumPy
170+
- [koma](https://koma.kyonifer.com/index.html) - Scientific computing library
163171
- [kotlin-statistics](https://github.com/thomasnield/kotlin-statistics) - Idiomatic statistical operators for Kotlin
172+
- [krangl](https://github.com/holgerbrandl/krangl) - Kotlin DSL for data wrangling
164173
- [kravis](https://github.com/holgerbrandl/kravis) - Kotlin grammar for data visualization
165-
- [spark](https://github.com/apache/spark) - Unified analytics engine for large-scale data processing
166-
- [gral](https://github.com/eseifert/gral) - Java library for displaying plots
167-
- [koma](https://koma.kyonifer.com/index.html) - Scientific computing library
168-
- [kmath](https://github.com/mipt-npm/kmath) - Kotlin mathematical library analogous to NumPy
169-
- [numpy](https://github.com/Kotlin/kotlin-numpy) - Kotlin wrapper for Python NumPy package
170-
- [exposed](https://github.com/JetBrains/Exposed) - Kotlin SQL framework
174+
- [lets-plot](https://github.com/JetBrains/lets-plot-kotlin) - ggplot-like interactive visualization for Kotlin
175+
- [lets-plot-dataframe](https://github.com/JetBrains/lets-plot-kotlin) - A bridge between lets-plot and dataframe libraries
171176
- [mysql](https://github.com/mysql/mysql-connector-j) - MySql JDBC Connector
177+
- [numpy](https://github.com/Kotlin/kotlin-numpy) - Kotlin wrapper for Python NumPy package
172178
- [smile](https://github.com/haifengl/smile) - Statistical Machine Intelligence and Learning Engine
173-
- [deeplearning4j](https://github.com/eclipse/deeplearning4j) - Deep learning library for the JVM
179+
- [spark](https://github.com/apache/spark) - Unified analytics engine for large-scale data processing
174180

175181
### Rich output
176182

@@ -216,6 +222,7 @@ Check [libraries](libraries) directory to see examples of library descriptors.
216222

217223
Library descriptor is a `<libName>.json` file with the following fields:
218224
- `properties`: a dictionary of properties that are used within library descriptor
225+
- `description`: a short library description which is used for generating libraries list in README
219226
- `link`: a link to library homepage. This link will be displayed in `:help` command
220227
- `minKernelVersion`: a minimal version of Kotlin kernel which may be used with this descriptor
221228
- `repositories`: a list of maven or ivy repositories to search for dependencies

README-STUB.md

+239
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
[![JetBrains official project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
2+
[![PyPI](https://img.shields.io/pypi/v/kotlin-jupyter-kernel?label=PyPi)](https://pypi.org/project/kotlin-jupyter-kernel/)
3+
[![Anaconda](https://img.shields.io/conda/v/jetbrains/kotlin-jupyter-kernel?label=Anaconda)](https://anaconda.org/jetbrains/kotlin-jupyter-kernel)
4+
[![GitHub](https://img.shields.io/github/license/Kotlin/kotlin-jupyter)](https://www.apache.org/licenses/LICENSE-2.0)
5+
[![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/kotlin/kotlin-jupyter/master?filepath=samples)
6+
7+
# Kotlin kernel for IPython/Jupyter
8+
9+
[Kotlin](https://kotlinlang.org/) (1.4.0) kernel for [Jupyter](https://jupyter.org).
10+
11+
Alpha version. Tested with Jupyter 6.0.1 on OS X so far.
12+
13+
![Screenshot in Jupyter](./samples/Screenshot.png)
14+
15+
To start using Kotlin kernel for Jupyter take a look at [introductory guide](https://github.com/cheptsov/kotlin-jupyter-demo/blob/master/index.ipynb).
16+
17+
Example notebooks can be found in the [samples](samples) folder
18+
19+
Try samples online: [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/kotlin/kotlin-jupyter/master?filepath=samples)
20+
21+
## Installation
22+
23+
There are three ways to install kernel:
24+
25+
### Conda
26+
27+
If you have `conda` installed, just run the following command to install stable package version:
28+
29+
`conda install -c jetbrains kotlin-jupyter-kernel` ([package home](https://anaconda.org/jetbrains/kotlin-jupyter-kernel))
30+
31+
To install conda package from the dev channel:
32+
33+
`conda install -c jetbrains-dev kotlin-jupyter-kernel` ([package home](https://anaconda.org/jetbrains-dev/kotlin-jupyter-kernel))
34+
35+
Uninstall: `conda remove kotlin-jupyter-kernel`
36+
37+
### Pip
38+
39+
You can also install this package through `pip`:
40+
41+
Stable:
42+
`pip install kotlin-jupyter-kernel` ([package home](https://pypi.org/project/kotlin-jupyter-kernel/))
43+
44+
Dev:
45+
`pip install -i https://test.pypi.org/simple/ kotlin-jupyter-kernel` ([package home](https://test.pypi.org/project/kotlin-jupyter-kernel/))
46+
47+
Uninstall: `pip uninstall kotlin-jupyter-kernel`
48+
49+
### From sources
50+
51+
```bash
52+
git clone https://github.com/Kotlin/kotlin-jupyter.git
53+
cd kotlin-jupyter
54+
./gradlew install
55+
```
56+
57+
Default installation path is `~/.ipython/kernels/kotlin/`. To install to some other location use option `-PinstallPath=`, but note that Jupyter looks for kernel specs files only in predefined places
58+
59+
Uninstall: `./gradlew uninstall`
60+
61+
## Usage
62+
63+
- `jupyter console --kernel=kotlin`
64+
- `jupyter notebook`
65+
- `jupyter lab`
66+
67+
To start using `kotlin` kernel inside Jupyter Notebook or JupyterLab create a new notebook with `kotlin` kernel.
68+
69+
## Supported functionality
70+
71+
### REPL commands
72+
73+
The following REPL commands are supported:
74+
- `:help` - displays REPL commands help
75+
- `:classpath` - displays current classpath
76+
77+
### Dependencies resolving annotations
78+
79+
It is possible to add dynamic dependencies to the notebook using the following annotations:
80+
- `@file:DependsOn(<coordinates>)` - adds artifacts to classpath. Supports absolute and relative paths to class directories or jars, ivy and maven artifacts represented by colon separated string
81+
- `@file:Repository(<absolute-path>)` - adds a directory for relative path resolution or ivy/maven repository.
82+
To specify Maven local, use `@file:Repository("*mavenLocal")`.
83+
84+
Note that dependencies in remote repositories are resolved via Ivy resolver.
85+
Caches are stored in `~/.ivy2/cache` folder by default. Sometimes, due to network
86+
issues or running several artifacts resolutions in parallel, caches may get corrupted.
87+
If you have some troubles with artifacts resolution, please remove caches, restart kernel
88+
and try again.
89+
90+
### Default repositories
91+
92+
The following maven repositories are included by default:
93+
- [Bintray JCenter](https://jcenter.bintray.com)
94+
- [Maven Central](https://repo.maven.apache.org/maven2)
95+
- [JitPack](https://jitpack.io/)
96+
97+
### Line Magics
98+
99+
The following line magics are supported:
100+
- `%use <lib1>, <lib2> ...` - injects code for supported libraries: artifact resolution, default imports, initialization code, type renderers
101+
- `%trackClasspath` - logs any changes of current classpath. Useful for debugging artifact resolution failures
102+
- `%trackExecution` - logs pieces of code that are going to be executed. Useful for debugging of libraries support
103+
- `%useLatestDescriptors` - use latest versions of library descriptors available. By default, bundled descriptors are used
104+
- `%output [options]` - output capturing settings.
105+
106+
See detailed info about line magics [here](doc/magics.md).
107+
108+
### Supported Libraries
109+
110+
When a library is included with `%use` keyword, the following functionality is added to the notebook:
111+
- repositories to search for library artifacts
112+
- artifact dependencies
113+
- default imports
114+
- library initialization code
115+
- renderers for special types, e.g. charts and data frames
116+
117+
This behavior is defined by `json` library descriptor. Descriptors for all supported libraries can be found in [libraries](libraries) directory.
118+
A library descriptor may provide a set of properties with default values that can be overridden when library is included.
119+
The major use case for library properties is to specify particular version of library. If descriptor has only one property, it can be
120+
defined without naming:
121+
```
122+
%use krangl(0.10)
123+
```
124+
If library descriptor defines more than one property, property names should be used:
125+
```
126+
%use spark(scala=2.11.10, spark=2.4.2)
127+
```
128+
Several libraries can be included in single `%use` statement, separated by `,`:
129+
```
130+
%use lets-plot, krangl, mysql(8.0.15)
131+
```
132+
You can also specify the source of library descriptor. By default, it's downloaded from the latest commit on the
133+
branch which kernel was built from. If you want to try descriptor from another revision, use the following syntax:
134+
```
135+
// Specify tag
136+
%use lets-plot@0.8.2.5
137+
// Specify commit sha, with more verbose syntax
138+
%use lets-plot@ref[24a040fe22335648885b106e2f4ddd63b4d49469]
139+
// Specify git ref along with library arguments
140+
%use krangl@dev(0.10)
141+
```
142+
Other options are resolving library descriptor from a local file or from remote URL:
143+
```
144+
// Load library from file
145+
%use mylib@file[/home/user/lib.json]
146+
// Load library from file: kernel will guess it's a file actually
147+
%use @/home/user/libs/lib.json
148+
// Or use another approach: specify a directory and file name without
149+
// extension (it should be JSON in such case) before it
150+
%use lib@/home/user/libs
151+
// Load library descriptor from a remote URL
152+
%use herlib@url[https://site.com/lib.json]
153+
// If your URL responds with 200(OK), you may skip `url[]` part:
154+
%use @https://site.com/lib.json
155+
// You may omit library name for file and URL resolution:
156+
%use @file[lib.json]
157+
```
158+
159+
List of supported libraries:
160+
[[supported_libraries]]
161+
162+
### Rich output
163+
164+
By default the return values from REPL statements are displayed in the text form. To use richer representations, e.g.
165+
to display graphics or html, it is possible to send MIME-encoded result to the client using the `MIME` helper function:
166+
```kotlin
167+
fun MIME(vararg mimeToData: Pair<String, Any>): MimeTypedResult
168+
```
169+
E.g.:
170+
```kotlin
171+
MIME("text/html" to "<p>Some <em>HTML</em></p>", "text/plain" to "No HTML for text clients")
172+
173+
```
174+
HTML outputs can also be rendered with `HTML` helper function:
175+
```kotlin
176+
fun HTML(text: String): MimeTypedResult
177+
```
178+
179+
### Autocompletion
180+
181+
Press `TAB` to get the list of suggested items for completion. In Jupyter Notebook, you don't need to press `TAB`,
182+
completion is requested automatically. Completion works for all globally defined symbols and for local symbols
183+
which were loaded into notebook during cells evaluation.
184+
185+
### Error analysis
186+
187+
If you use Jupyter Notebook as Jupyter client, you will also see that compilation errors and warnings are underlined in
188+
red and in yellow correspondingly. This is achieved by kernel-level extension of Jupyter notebook which sends
189+
error-analysis requests to kernel and renders their results. If you hover the cursor over underlined text, you will get
190+
an error message which can help you to fix the error.
191+
192+
## Debugging
193+
194+
1. Run `./gradlew installDebug`. Use option `-PdebugPort=` to specify port address for debugger. Default port is 1044.
195+
2. Run `jupyter-notebook`
196+
3. Attach remote debugger to JVM with specified port
197+
198+
## Adding new libraries
199+
200+
To support new `JVM` library and make it available via `%use` magic command you need to create a library descriptor for it.
201+
202+
Check [libraries](libraries) directory to see examples of library descriptors.
203+
204+
Library descriptor is a `<libName>.json` file with the following fields:
205+
- `properties`: a dictionary of properties that are used within library descriptor
206+
- `description`: a short library description which is used for generating libraries list in README
207+
- `link`: a link to library homepage. This link will be displayed in `:help` command
208+
- `minKernelVersion`: a minimal version of Kotlin kernel which may be used with this descriptor
209+
- `repositories`: a list of maven or ivy repositories to search for dependencies
210+
- `dependencies`: a list of library dependencies
211+
- `imports`: a list of default imports for library
212+
- `init`: a list of code snippets to be executed when library is included
213+
- `initCell`: a list of code snippets to be executed before execution of any cell
214+
- `shutdown`: a list of code snippets to be executed on kernel shutdown. Any cleanup code goes here
215+
- `renderers`: a list of type converters for special rendering of particular types
216+
217+
*All fields are optional
218+
219+
Fields for type renderer:
220+
- `class`: fully-qualified class name for the type to be rendered
221+
- `result`: expression that produces output value. Source object is referenced as `$it`
222+
223+
Name of the file is a library name that is passed to '%use' command
224+
225+
Library properties can be used in any parts of library descriptor as `$property`
226+
227+
To register new library descriptor:
228+
1. For private usage - add it to local settings folder `<UserHome>/.jupyter_kotlin/libraries`
229+
2. For sharing with community - commit it to [libraries](libraries) directory and create pull request.
230+
231+
If you are maintaining some library and want to update your library descriptor, just create pull request with your update. After your request is accepted,
232+
new version of your library will be available to all Kotlin Jupyter users immediately on next kernel startup (no kernel update is needed).
233+
234+
If a library descriptor with the same name is found in several locations, the following resolution priority is used:
235+
1. Local settings folder (highest priority)
236+
2. [libraries](libraries) directory at the latest master branch of `https://github.com/Kotlin/kotlin-jupyter` repository
237+
3. Kernel installation directory
238+
239+
If you don't want some library to be updated automatically, put fixed version of its library descriptor into local settings folder.

build.gradle.kts

+43-2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ class TaskOptions: AllOptions {
2929
println("##teamcity[buildNumber '$version']")
3030
artifactsDir
3131
}()
32+
override val readmePath: Path = rootPath.resolve(".github").resolve("README.md")
3233

3334
private val installPath = rootProject.findProperty("installPath") as String?
3435

@@ -249,7 +250,7 @@ with(ProjectWithOptionsImpl(project, TaskOptions())) {
249250
)
250251
}
251252

252-
tasks.register("buildProperties") {
253+
val buildProperties by tasks.registering {
253254
group = buildGroup
254255
val outputDir = file(getSubDir(buildDir.toPath(), resourcesDir, mainSourceSetDir))
255256

@@ -277,7 +278,47 @@ with(ProjectWithOptionsImpl(project, TaskOptions())) {
277278
}
278279

279280
tasks.processResources {
280-
dependsOn("buildProperties")
281+
dependsOn(buildProperties)
282+
}
283+
284+
val readmeFile = readmePath.toFile()
285+
val readmeStubFile = File("README-STUB.md")
286+
val librariesDir = File(librariesPath)
287+
val readmeGenerator = ReadmeGenerator(librariesDir)
288+
289+
val generateReadme by tasks.registering {
290+
group = buildGroup
291+
292+
readmeFile.parentFile.mkdirs()
293+
294+
inputs.file(readmeStubFile)
295+
inputs.dir(librariesDir)
296+
outputs.file(readmeFile)
297+
298+
doLast {
299+
readmeGenerator.generate(readmeStubFile, readmeFile)
300+
}
301+
}
302+
303+
val checkReadme by tasks.registering {
304+
group = "verification"
305+
306+
inputs.file(readmeStubFile)
307+
inputs.dir(librariesDir)
308+
inputs.file(readmeFile)
309+
310+
doLast {
311+
val tempFile = createTempFile("kotlin-jupyter-readme")
312+
tempFile.deleteOnExit()
313+
readmeGenerator.generate(readmeStubFile, tempFile)
314+
if(tempFile.readText() != readmeFile.readText()) {
315+
throw AssertionError("Readme is not regenerated. Regenerate it using `./gradlew ${generateReadme.name}` command")
316+
}
317+
}
318+
}
319+
320+
tasks.check {
321+
dependsOn(checkReadme)
281322
}
282323

283324
createCleanTasks()

buildSrc/build.gradle.kts

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2-
31
plugins {
42
`kotlin-dsl`
53
}

buildSrc/src/main/kotlin/distTasks.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ fun ProjectWithOptions.prepareDistributionTasks() {
3434
dependsOn("installHintRemoverRequirements")
3535
}
3636
from(distributionPath)
37-
from("README.md")
37+
from(readmePath)
3838
into(distribBuildPath)
3939
exclude(".idea/**")
4040

buildSrc/src/main/kotlin/install.kt

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ interface BuildOptions {
1414
val rootPath: Path
1515

1616
val artifactsDir: Path
17+
val readmePath: Path
1718
}
1819

1920
interface ProjectWithBuildOptions: Project, BuildOptions

0 commit comments

Comments
 (0)