Jupyter notebook xeus-lua to pegasus

Here is a short video. Sending code from jupyter notebook to Solar2D simulator

I was curious about Jupyter kernel for Lua called xeus-lua. It is using ilua. I though it can send a lua code from jupyter notebook to Solar2D simulator via http protocol. I added a little code to xeus and tested http post from xeus to lua http-server pegasus running on the simulator. It worked.

What can be done with Jupyter notebook, I will look for any ideas and suggestions.

xeus-lua - Jupyter kernel for Lua

http_print is added to xinterpreter.cpp

    bool http_print = config_table["http_print"];
    bool need_eval = true;

    if(http_print){
        std::stringstream test_code;
        test_code << "hprint([[" << code << "]])";
        auto test_code_result = lua.safe_script(test_code.str(), &sol::script_pass_on_error);
        need_eval = !test_code_result.valid();
    }else if(auto_print){
      ...

xextend.cpp

void add_ilua_module(sol::state_view & lua){
    std::string script = R""""(
    ilua = {
        display = { _version = "0.1.0" ,
            detail = {}
        },
        widgets = {
            detail = {}
        },
        canvas = {
            color = {},
            detail = {}
        },
        config = {
            printer = "pprint",
            auto_print = true,
            http_print = false,
        },

hprint() in ilua runtime receives the code text from a jupyter notebook.

M = {}

local http = require("socket.http")
local ltn12 = require("ltn12")

-- Set up the request URL
local url = "http://localhost:9090/hprint"

function M:post(code)
    -- Prepare the request body
    -- Set up the request headers
    local headers = {
      ["Content-Type"] = "application/lua",
      ["Content-Length"] = string.len(code)
    }
    -- ilua.detail.__custom_print(code)
    -- Prepare the response body
    local response_body = {}
    -- Make the POST request
    local res, httpCode, response_headers = http.request {
      url = url,
      method = "POST",
      headers = headers,
      source = ltn12.source.string(code),
      sink = ltn12.sink.table(response_body)
    }

    -- Check the response
    if httpCode ~= 200 then
      ilua.detail.__custom_print("Error: " .. httpCode)
    else
      ilua.detail.__custom_print("Response: " .. table.concat(response_body))
    end
end

hprint = function(code) M:post(code) return true end
ilua.config.http_print = true

pegasus

Solar2D runs a http-server.

pegasus/init.lua has been modifed to use enterFrame of Solar2D with server:settimeout(0)

function Pegasus:start(callback)
  local handler = Handler:new(callback, self.location, self.plugins)

  local server = assert(socket.bind(self.host, self.port))
  local ip, port = server:getsockname()
  print('Pegasus is up on ' .. ip .. ":".. port)
  server:settimeout(0)
  function self:enterFrame()
      local client, errmsg = server:accept()
      if client then
        client:settimeout(self.timeout, 'b')
        handler:processRequest(self.port, client, server)
      else
        --io.stderr:write('Failed to accept connection:' .. errmsg .. '\n')
      end
  end
  Runtime:addEventListener('enterFrame', self)
end

Post request to /hprint does loadstring() and pcall() and returns a result to xeus-lua

local function doPost(request)
  local data = requerst.data
  if data  then
    local f = loadstring(data)
    local status, arg = pcall(f)
    if status then
      return json.encode(arg) or "true"
    else -- error message in arg
      local pos = arg:find("stack traceback")
      if pos then
        return arg:sub(1, pos-1)
      else
        return arg
      end
    end
  end
1 Like