Repository: jupyter/jupyter_client (python)

Issue:
Support metadata in kernel specs
Currently, there's no easy way to track metadata about a kernel beyond what language it supports. Having a display name is helpful, but it'd be nice to allow for programmatic access for more information about the kernel.

For example, internally we use Jupyter in a context where different backends have different functionality available (eg access to different libraries or hardware). It'd be nice to allow a FE to filter the list of available backends if we know a certain library is needed.

Similarly, as new versions of the Jupyter protocol roll out, some FEs will be in a situation where they might need to communicate with backends which speak different protocol versions. Having access to this info programmatically would be nicer than a trial-and-error approach.

/cc @rgbkrk 

Pull request description:
Add a `metadata` field to kernelspecs.
Currently, the only way for a kernel to offer additional information about its
capabilities is to encode information into the kernel name or display name;
this information can be useful to clients, especially for things like
filtering a list of kernels.

This adds support for a new kernelspec dict field, `metadata`. This allows
kernels to add additional information, which clients can then consume as
needed.

Fixes #273. /cc @rgbkrk 

Patch:
diff --git a/docs/api/kernelspec.rst b/docs/api/kernelspec.rst
index c2164ea..942a694 100644
--- a/docs/api/kernelspec.rst
+++ b/docs/api/kernelspec.rst
@@ -25,6 +25,11 @@ kernelspec - discovering kernels
       The name of the language the kernel implements, to help with picking
       appropriate kernels when loading notebooks.
 
+   .. attribute:: metadata
+
+      Additional kernel-specific metadata; clients can use this as needed,
+      for instance to aid in kernel selection and filtering.
+
    .. attribute:: resource_dir
 
       The path to the directory with this kernel's resources, such as icons.
diff --git a/docs/kernels.rst b/docs/kernels.rst
index 42101c3..780bac7 100644
--- a/docs/kernels.rst
+++ b/docs/kernels.rst
@@ -135,6 +135,8 @@ JSON serialised dictionary containing the following keys and values:
 - **env** (optional): A dictionary of environment variables to set for the kernel.
   These will be added to the current environment variables before the kernel is
   started.
+- **metadata** (optional): A dictionary of additional attributes about this
+  kernel; used by clients to aid clients in kernel selection.
 
 For example, the kernel.json file for IPython looks like this::
 
diff --git a/jupyter_client/kernelspec.py b/jupyter_client/kernelspec.py
index 0b882ad..3465ac7 100644
--- a/jupyter_client/kernelspec.py
+++ b/jupyter_client/kernelspec.py
@@ -28,6 +28,7 @@ class KernelSpec(HasTraits):
     language = Unicode()
     env = Dict()
     resource_dir = Unicode()
+    metadata = Dict()
 
     @classmethod
     def from_resource_dir(cls, resource_dir):
@@ -45,6 +46,7 @@ class KernelSpec(HasTraits):
                  env=self.env,
                  display_name=self.display_name,
                  language=self.language,
+                 metadata=self.metadata,
                 )
 
         return d


Test patch:
diff --git a/jupyter_client/tests/test_kernelspec.py b/jupyter_client/tests/test_kernelspec.py
index b02dd75..b2ec419 100644
--- a/jupyter_client/tests/test_kernelspec.py
+++ b/jupyter_client/tests/test_kernelspec.py
@@ -67,6 +67,7 @@ class KernelSpecTests(unittest.TestCase):
         self.assertEqual(ks.argv, sample_kernel_json['argv'])
         self.assertEqual(ks.display_name, sample_kernel_json['display_name'])
         self.assertEqual(ks.env, {})
+        self.assertEqual(ks.metadata, {})
 
     def test_find_all_specs(self):
         kernels = self.ksm.get_all_specs()