jupyter-0.9.0: examples/calculator/Main.hs
{-|
Module : Main
Description : Main module for a stdin-using Jupyter kernel created using the @jupyter@ library.
Copyright : (c) Andrew Gibiansky, 2016
License : MIT
Maintainer : andrew.gibiansky@gmail.com
Stability : stable
Portability : POSIX
This module is the Main module for @kernel-calculator@, a Jupyter kernel which implements a simple
calculator language using the @jupyter@ library. It is intended to demonstrate a full yet basic kernel,
one which implements execution, inspection, completion, as well as the basic informational requests.
-}
{-# Language OverloadedStrings #-}
module Main(main) where
-- Imports from 'base'
import Control.Concurrent (newMVar)
import System.Environment (getArgs)
import System.Exit (exitFailure)
import System.IO (stderr)
-- Imports from 'text'
import qualified Data.Text.IO as T
-- Imports from 'jupyter'
import Jupyter.Install (installKernel, simpleKernelspec, InstallUser(..), InstallResult(..),
Kernelspec)
import Jupyter.Kernel (readProfile, serve, defaultCommHandler)
-- Imports from 'kernel-calculator'
import Calculator.Handler (requestHandler)
-- | In `main`, support two commands:
--
-- - `kernel-calculator install`: Register this kernel with Jupyter.
-- - `kernel-calculator kernel $FILE`: Serve a kernel given ports in connection file $FILE.
main :: IO ()
main = do
args <- getArgs
case args of
["install"] -> runInstall
["kernel", profilePath] -> runKernel profilePath
_ -> putStrLn $ "Invalid arguments: " ++ show args
-- | Register this kernel with Jupyter.
runInstall :: IO ()
runInstall =
installKernel InstallLocal calculatorKernelspec >>= handleInstallResult
where
-- A basic kernelspec with limited info.
calculatorKernelspec :: Kernelspec
calculatorKernelspec =
simpleKernelspec "Calculator" "calculator" $ \exe connect -> [exe, "kernel", connect]
-- Print an error message and exit with non-zero exit code if the install failed.
handleInstallResult :: InstallResult -> IO ()
handleInstallResult installResult =
case installResult of
InstallSuccessful -> return ()
InstallFailed reason -> do
T.hPutStrLn stderr reason
exitFailure
-- | Run the kernel on ports determined by parsing the connection file provided.
runKernel :: FilePath -> IO ()
runKernel profilePath = do
Just profile <- readProfile profilePath
-- Keep track of the current execution using an MVar. In general, kernel state (when it exists)
-- often needs to be kept in some sort of temporary mutable state.
execCountVar <- newMVar 1
serve profile defaultCommHandler $ requestHandler profile execCountVar