Skip to content

Repository files navigation

ContributorsForksStargazersIssuesMS-PL LicenseLinkedIn


Logo

LS-Server

HTTP server for the Lisp-Stat system
Explore the docs »

Report Bug · Request Feature

Table of Contents

  1. About the Project
  2. Getting Started
  3. Usage
  4. Plot Workflow
  5. API Endpoints
  6. Code Structure
  7. Configuration
  8. Testing
  9. Resources
  10. Contributing
  11. License
  12. Contact

About the Project

LS-Server is an HTTP server for the Lisp-Stat system, built on Hunchentoot. It provides a lightweight browser-facing layer over Lisp-Stat data frames and registered plots.

Core capabilities:

  1. Plot viewing — serve registered plots as interactive Vega-Embed pages
  2. Plot gallery and navigation — browse available plots through index and gallery pages
  3. Data frame viewing and editing — view data frames in an editable Handsontable grid
  4. CSV / JSON / s-expression data serving — serve data-frame contents in multiple formats via content negotiation
  5. Vega-Lite spec serving — serve raw plot specifications for registered plots
  6. REPL integration — when the server is running, printed data frames and plots include server URLs

LS-Server does not own plot construction. Plot creation and registration belong to plot / vega. LS-Server consumes those public APIs and serves the registered results.

Built With

Getting Started

Prerequisites

Installation

Quicklisp installation

(ql:quickload :ls-server)

Source installation

  1. Clone the repository into a directory ASDF knows about:
cd~/common-lisp && \
git clone https://github.com/Lisp-Stat/ls-server.git
  1. Reset the ASDF source registry from the REPL:
(asdf:clear-source-registry)
  1. Load the system and its dependencies:
(ql:quickload :ls-server)

Usage

Start the server on the default port (20202):

(ls-server:start-server)

Start on a custom port:

(ls-server:start-server :port8080)

Stop the server:

(ls-server:stop-server)

Once started, open http://localhost:20202/ in a browser.

REPL URL decoration

When the server is running, printed data frames and plots include URLs:

LS-USER> mtcars
#<DATA-FRAME (32 observations of 11 variables)
Motor Trend Car Road Tests
http://localhost:20202/table/MTCARS>
LS-USER> some-plot
#<PLOT SOME-PLOT: ...
http://localhost:20202/plot/some-plot>

Depending on your terminal or editor, these URLs may be clickable.

Plot Workflow

A plot appears in LS-Server only after it has been registered.

This is especially important if you are using quick-plot: qplot:qplot now returns a plot object, but it does not automatically register or display it.

Minimal plot-serving example

(ql:quickload '(:ls-server:quick-plot))
(ls-server:start-server)
(vega:load-vega-examples)
(import'(geom:point))
(import'(gg:label))
(import'(qplot:qplot))
(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p))

After registration, the plot is available through:

  • http://localhost:20202/plot/cars-basic
  • the plot index pages
  • any REPL URLs produced while the server is running

Explicit local display

If you also want to open the plot in a browser directly from Lisp, do that separately:

(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p)
(plot:plot p))

Loading example data

(ql:quickload :lisp-stat)
(vega:load-vega-examples)

You can also load other datasets and data frames through the normal Lisp-Stat mechanisms. Once they exist in the running image, LS-Server can expose them through its data and table endpoints.

API Endpoints

Data Endpoints

MethodPathDescription
GET/dataJSON array of available data frame names
GET/data/<name>Data frame contents, chosen by Accept header
PUT/data/<name>Replace a data frame with JSON row data
PATCH/data/<name>Update specific cells

Supported Accept types for GET /data/<name>:

Accept HeaderFormat
text/csv (default)CSV with header row
application/jsonJSON array of row objects
application/vega-jsonVega row-oriented JSON
text/s-expressionS-expression
(none or */*)CSV

Table Endpoints

MethodPathDescription
GET/table/<name>Interactive Handsontable page for the data frame

The table page displays data-frame documentation when available and loads its data through /data/<name>.

Plot Endpoints

MethodPathDescription
GET/plotJSON array of available plot names
GET/plot/<name>Plot page or raw Vega-Lite JSON spec
DELETE/plot/<name>Remove a plot from the registry

Supported Accept types for GET /plot/<name>:

Accept HeaderFormat
text/html (default)Full HTML page with Vega-Embed viewer
application/vega-jsonRaw Vega-Lite JSON specification

Navigation

MethodPathDescription
GET/Landing page
GET/plotsPlot gallery / index page
GET/tablesData-frame index page
GET/healthHealth endpoint returning {"status":"ok"}

Code Structure

ls-server/
├── ls-server.asd
├── src/
│ ├── pkgdcl.lisp
│ ├── config.lisp
│ ├── negotiation.lisp
│ ├── server.lisp
│ ├── health.lisp
│ ├── data-routes.lisp
│ ├── html.lisp
│ ├── plot-routes.lisp
│ ├── table-routes.lisp
│ ├── landing-routes.lisp
│ └── print-extensions.lisp
└── tests/
├── test-package.lisp
├── main.lisp
├── health-tests.lisp
├── server-tests.lisp
├── negotiation-tests.lisp
├── data-tests.lisp
├── plot-tests.lisp
├── table-tests.lisp
├── landing-tests.lisp
└── print-tests.lisp

Configuration

Configuration parameters are defined in src/config.lisp and can be set before starting the server.

ParameterDefaultDescription
*default-port*20202Default HTTP port
*server-host*"localhost"Hostname used in printed URLs
*access-log-destination*nilAccess log destination
*message-log-destination*nilMessage log destination

Example:

(setfls-server:*access-log-destination*"/tmp/ls-access.log")
(setfls-server:*message-log-destination*"/tmp/ls-messages.log")
(ls-server:start-server)

Testing

Run the main test suite:

(asdf:test-system :ls-server)

If the repo also exposes a dedicated test system in your local checkout, you can run that directly as well:

(asdf:test-system :ls-server/tests)

Example non-interactive run:

sbcl --non-interactive \
--eval '(ql:quickload :ls-server/tests)' \
--eval '(asdf:test-system "ls-server/tests")'

The test framework is CLUNIT2. Integration tests start a test server and exercise HTTP routes directly.

Resources

This system is part of the Lisp-Stat project; that should be your first stop for information. Also see the resources and community pages for more information.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated. Please see CONTRIBUTING for details on the code of conduct and the process for submitting pull requests.

License

Distributed under the MS-PL License. See LICENSE for more information.

Contact

Project Link: https://github.com/Lisp-Stat/ls-server

About

No description, website, or topics provided.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
GitHub - Lisp-Stat/ls-server · GitHub
Skip to content

Repository files navigation

ContributorsForksStargazersIssuesMS-PL LicenseLinkedIn


Logo

LS-Server

HTTP server for the Lisp-Stat system
Explore the docs »

Report Bug · Request Feature

Table of Contents

  1. About the Project
  2. Getting Started
  3. Usage
  4. Plot Workflow
  5. API Endpoints
  6. Code Structure
  7. Configuration
  8. Testing
  9. Resources
  10. Contributing
  11. License
  12. Contact

About the Project

LS-Server is an HTTP server for the Lisp-Stat system, built on Hunchentoot. It provides a lightweight browser-facing layer over Lisp-Stat data frames and registered plots.

Core capabilities:

  1. Plot viewing — serve registered plots as interactive Vega-Embed pages
  2. Plot gallery and navigation — browse available plots through index and gallery pages
  3. Data frame viewing and editing — view data frames in an editable Handsontable grid
  4. CSV / JSON / s-expression data serving — serve data-frame contents in multiple formats via content negotiation
  5. Vega-Lite spec serving — serve raw plot specifications for registered plots
  6. REPL integration — when the server is running, printed data frames and plots include server URLs

LS-Server does not own plot construction. Plot creation and registration belong to plot / vega. LS-Server consumes those public APIs and serves the registered results.

Built With

Getting Started

Prerequisites

Installation

Quicklisp installation

(ql:quickload :ls-server)

Source installation

  1. Clone the repository into a directory ASDF knows about:
cd~/common-lisp && \
git clone https://github.com/Lisp-Stat/ls-server.git
  1. Reset the ASDF source registry from the REPL:
(asdf:clear-source-registry)
  1. Load the system and its dependencies:
(ql:quickload :ls-server)

Usage

Start the server on the default port (20202):

(ls-server:start-server)

Start on a custom port:

(ls-server:start-server :port8080)

Stop the server:

(ls-server:stop-server)

Once started, open http://localhost:20202/ in a browser.

REPL URL decoration

When the server is running, printed data frames and plots include URLs:

LS-USER> mtcars
#<DATA-FRAME (32 observations of 11 variables)
Motor Trend Car Road Tests
http://localhost:20202/table/MTCARS>
LS-USER> some-plot
#<PLOT SOME-PLOT: ...
http://localhost:20202/plot/some-plot>

Depending on your terminal or editor, these URLs may be clickable.

Plot Workflow

A plot appears in LS-Server only after it has been registered.

This is especially important if you are using quick-plot: qplot:qplot now returns a plot object, but it does not automatically register or display it.

Minimal plot-serving example

(ql:quickload '(:ls-server:quick-plot))
(ls-server:start-server)
(vega:load-vega-examples)
(import'(geom:point))
(import'(gg:label))
(import'(qplot:qplot))
(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p))

After registration, the plot is available through:

  • http://localhost:20202/plot/cars-basic
  • the plot index pages
  • any REPL URLs produced while the server is running

Explicit local display

If you also want to open the plot in a browser directly from Lisp, do that separately:

(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p)
(plot:plot p))

Loading example data

(ql:quickload :lisp-stat)
(vega:load-vega-examples)

You can also load other datasets and data frames through the normal Lisp-Stat mechanisms. Once they exist in the running image, LS-Server can expose them through its data and table endpoints.

API Endpoints

Data Endpoints

MethodPathDescription
GET/dataJSON array of available data frame names
GET/data/<name>Data frame contents, chosen by Accept header
PUT/data/<name>Replace a data frame with JSON row data
PATCH/data/<name>Update specific cells

Supported Accept types for GET /data/<name>:

Accept HeaderFormat
text/csv (default)CSV with header row
application/jsonJSON array of row objects
application/vega-jsonVega row-oriented JSON
text/s-expressionS-expression
(none or */*)CSV

Table Endpoints

MethodPathDescription
GET/table/<name>Interactive Handsontable page for the data frame

The table page displays data-frame documentation when available and loads its data through /data/<name>.

Plot Endpoints

MethodPathDescription
GET/plotJSON array of available plot names
GET/plot/<name>Plot page or raw Vega-Lite JSON spec
DELETE/plot/<name>Remove a plot from the registry

Supported Accept types for GET /plot/<name>:

Accept HeaderFormat
text/html (default)Full HTML page with Vega-Embed viewer
application/vega-jsonRaw Vega-Lite JSON specification

Navigation

MethodPathDescription
GET/Landing page
GET/plotsPlot gallery / index page
GET/tablesData-frame index page
GET/healthHealth endpoint returning {"status":"ok"}

Code Structure

ls-server/
├── ls-server.asd
├── src/
│ ├── pkgdcl.lisp
│ ├── config.lisp
│ ├── negotiation.lisp
│ ├── server.lisp
│ ├── health.lisp
│ ├── data-routes.lisp
│ ├── html.lisp
│ ├── plot-routes.lisp
│ ├── table-routes.lisp
│ ├── landing-routes.lisp
│ └── print-extensions.lisp
└── tests/
├── test-package.lisp
├── main.lisp
├── health-tests.lisp
├── server-tests.lisp
├── negotiation-tests.lisp
├── data-tests.lisp
├── plot-tests.lisp
├── table-tests.lisp
├── landing-tests.lisp
└── print-tests.lisp

Configuration

Configuration parameters are defined in src/config.lisp and can be set before starting the server.

ParameterDefaultDescription
*default-port*20202Default HTTP port
*server-host*"localhost"Hostname used in printed URLs
*access-log-destination*nilAccess log destination
*message-log-destination*nilMessage log destination

Example:

(setfls-server:*access-log-destination*"/tmp/ls-access.log")
(setfls-server:*message-log-destination*"/tmp/ls-messages.log")
(ls-server:start-server)

Testing

Run the main test suite:

(asdf:test-system :ls-server)

If the repo also exposes a dedicated test system in your local checkout, you can run that directly as well:

(asdf:test-system :ls-server/tests)

Example non-interactive run:

sbcl --non-interactive \
--eval '(ql:quickload :ls-server/tests)' \
--eval '(asdf:test-system "ls-server/tests")'

The test framework is CLUNIT2. Integration tests start a test server and exercise HTTP routes directly.

Resources

This system is part of the Lisp-Stat project; that should be your first stop for information. Also see the resources and community pages for more information.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated. Please see CONTRIBUTING for details on the code of conduct and the process for submitting pull requests.

License

Distributed under the MS-PL License. See LICENSE for more information.

Contact

Project Link: https://github.com/Lisp-Stat/ls-server

About

No description, website, or topics provided.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - Lisp-Stat/ls-server · GitHub
Skip to content

Repository files navigation

ContributorsForksStargazersIssuesMS-PL LicenseLinkedIn


Logo

LS-Server

HTTP server for the Lisp-Stat system
Explore the docs »

Report Bug · Request Feature

Table of Contents

  1. About the Project
  2. Getting Started
  3. Usage
  4. Plot Workflow
  5. API Endpoints
  6. Code Structure
  7. Configuration
  8. Testing
  9. Resources
  10. Contributing
  11. License
  12. Contact

About the Project

LS-Server is an HTTP server for the Lisp-Stat system, built on Hunchentoot. It provides a lightweight browser-facing layer over Lisp-Stat data frames and registered plots.

Core capabilities:

  1. Plot viewing — serve registered plots as interactive Vega-Embed pages
  2. Plot gallery and navigation — browse available plots through index and gallery pages
  3. Data frame viewing and editing — view data frames in an editable Handsontable grid
  4. CSV / JSON / s-expression data serving — serve data-frame contents in multiple formats via content negotiation
  5. Vega-Lite spec serving — serve raw plot specifications for registered plots
  6. REPL integration — when the server is running, printed data frames and plots include server URLs

LS-Server does not own plot construction. Plot creation and registration belong to plot / vega. LS-Server consumes those public APIs and serves the registered results.

Built With

Getting Started

Prerequisites

Installation

Quicklisp installation

(ql:quickload :ls-server)

Source installation

  1. Clone the repository into a directory ASDF knows about:
cd~/common-lisp && \
git clone https://github.com/Lisp-Stat/ls-server.git
  1. Reset the ASDF source registry from the REPL:
(asdf:clear-source-registry)
  1. Load the system and its dependencies:
(ql:quickload :ls-server)

Usage

Start the server on the default port (20202):

(ls-server:start-server)

Start on a custom port:

(ls-server:start-server :port8080)

Stop the server:

(ls-server:stop-server)

Once started, open http://localhost:20202/ in a browser.

REPL URL decoration

When the server is running, printed data frames and plots include URLs:

LS-USER> mtcars
#<DATA-FRAME (32 observations of 11 variables)
Motor Trend Car Road Tests
http://localhost:20202/table/MTCARS>
LS-USER> some-plot
#<PLOT SOME-PLOT: ...
http://localhost:20202/plot/some-plot>

Depending on your terminal or editor, these URLs may be clickable.

Plot Workflow

A plot appears in LS-Server only after it has been registered.

This is especially important if you are using quick-plot: qplot:qplot now returns a plot object, but it does not automatically register or display it.

Minimal plot-serving example

(ql:quickload '(:ls-server:quick-plot))
(ls-server:start-server)
(vega:load-vega-examples)
(import'(geom:point))
(import'(gg:label))
(import'(qplot:qplot))
(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p))

After registration, the plot is available through:

  • http://localhost:20202/plot/cars-basic
  • the plot index pages
  • any REPL URLs produced while the server is running

Explicit local display

If you also want to open the plot in a browser directly from Lisp, do that separately:

(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p)
(plot:plot p))

Loading example data

(ql:quickload :lisp-stat)
(vega:load-vega-examples)

You can also load other datasets and data frames through the normal Lisp-Stat mechanisms. Once they exist in the running image, LS-Server can expose them through its data and table endpoints.

API Endpoints

Data Endpoints

MethodPathDescription
GET/dataJSON array of available data frame names
GET/data/<name>Data frame contents, chosen by Accept header
PUT/data/<name>Replace a data frame with JSON row data
PATCH/data/<name>Update specific cells

Supported Accept types for GET /data/<name>:

Accept HeaderFormat
text/csv (default)CSV with header row
application/jsonJSON array of row objects
application/vega-jsonVega row-oriented JSON
text/s-expressionS-expression
(none or */*)CSV

Table Endpoints

MethodPathDescription
GET/table/<name>Interactive Handsontable page for the data frame

The table page displays data-frame documentation when available and loads its data through /data/<name>.

Plot Endpoints

MethodPathDescription
GET/plotJSON array of available plot names
GET/plot/<name>Plot page or raw Vega-Lite JSON spec
DELETE/plot/<name>Remove a plot from the registry

Supported Accept types for GET /plot/<name>:

Accept HeaderFormat
text/html (default)Full HTML page with Vega-Embed viewer
application/vega-jsonRaw Vega-Lite JSON specification

Navigation

MethodPathDescription
GET/Landing page
GET/plotsPlot gallery / index page
GET/tablesData-frame index page
GET/healthHealth endpoint returning {"status":"ok"}

Code Structure

ls-server/
├── ls-server.asd
├── src/
│ ├── pkgdcl.lisp
│ ├── config.lisp
│ ├── negotiation.lisp
│ ├── server.lisp
│ ├── health.lisp
│ ├── data-routes.lisp
│ ├── html.lisp
│ ├── plot-routes.lisp
│ ├── table-routes.lisp
│ ├── landing-routes.lisp
│ └── print-extensions.lisp
└── tests/
├── test-package.lisp
├── main.lisp
├── health-tests.lisp
├── server-tests.lisp
├── negotiation-tests.lisp
├── data-tests.lisp
├── plot-tests.lisp
├── table-tests.lisp
├── landing-tests.lisp
└── print-tests.lisp

Configuration

Configuration parameters are defined in src/config.lisp and can be set before starting the server.

ParameterDefaultDescription
*default-port*20202Default HTTP port
*server-host*"localhost"Hostname used in printed URLs
*access-log-destination*nilAccess log destination
*message-log-destination*nilMessage log destination

Example:

(setfls-server:*access-log-destination*"/tmp/ls-access.log")
(setfls-server:*message-log-destination*"/tmp/ls-messages.log")
(ls-server:start-server)

Testing

Run the main test suite:

(asdf:test-system :ls-server)

If the repo also exposes a dedicated test system in your local checkout, you can run that directly as well:

(asdf:test-system :ls-server/tests)

Example non-interactive run:

sbcl --non-interactive \
--eval '(ql:quickload :ls-server/tests)' \
--eval '(asdf:test-system "ls-server/tests")'

The test framework is CLUNIT2. Integration tests start a test server and exercise HTTP routes directly.

Resources

This system is part of the Lisp-Stat project; that should be your first stop for information. Also see the resources and community pages for more information.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated. Please see CONTRIBUTING for details on the code of conduct and the process for submitting pull requests.

License

Distributed under the MS-PL License. See LICENSE for more information.

Contact

Project Link: https://github.com/Lisp-Stat/ls-server

About

No description, website, or topics provided.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - Lisp-Stat/ls-server · GitHub
Skip to content

Repository files navigation

ContributorsForksStargazersIssuesMS-PL LicenseLinkedIn


Logo

LS-Server

HTTP server for the Lisp-Stat system
Explore the docs »

Report Bug · Request Feature

Table of Contents

  1. About the Project
  2. Getting Started
  3. Usage
  4. Plot Workflow
  5. API Endpoints
  6. Code Structure
  7. Configuration
  8. Testing
  9. Resources
  10. Contributing
  11. License
  12. Contact

About the Project

LS-Server is an HTTP server for the Lisp-Stat system, built on Hunchentoot. It provides a lightweight browser-facing layer over Lisp-Stat data frames and registered plots.

Core capabilities:

  1. Plot viewing — serve registered plots as interactive Vega-Embed pages
  2. Plot gallery and navigation — browse available plots through index and gallery pages
  3. Data frame viewing and editing — view data frames in an editable Handsontable grid
  4. CSV / JSON / s-expression data serving — serve data-frame contents in multiple formats via content negotiation
  5. Vega-Lite spec serving — serve raw plot specifications for registered plots
  6. REPL integration — when the server is running, printed data frames and plots include server URLs

LS-Server does not own plot construction. Plot creation and registration belong to plot / vega. LS-Server consumes those public APIs and serves the registered results.

Built With

Getting Started

Prerequisites

Installation

Quicklisp installation

(ql:quickload :ls-server)

Source installation

  1. Clone the repository into a directory ASDF knows about:
cd~/common-lisp && \
git clone https://github.com/Lisp-Stat/ls-server.git
  1. Reset the ASDF source registry from the REPL:
(asdf:clear-source-registry)
  1. Load the system and its dependencies:
(ql:quickload :ls-server)

Usage

Start the server on the default port (20202):

(ls-server:start-server)

Start on a custom port:

(ls-server:start-server :port8080)

Stop the server:

(ls-server:stop-server)

Once started, open http://localhost:20202/ in a browser.

REPL URL decoration

When the server is running, printed data frames and plots include URLs:

LS-USER> mtcars
#<DATA-FRAME (32 observations of 11 variables)
Motor Trend Car Road Tests
http://localhost:20202/table/MTCARS>
LS-USER> some-plot
#<PLOT SOME-PLOT: ...
http://localhost:20202/plot/some-plot>

Depending on your terminal or editor, these URLs may be clickable.

Plot Workflow

A plot appears in LS-Server only after it has been registered.

This is especially important if you are using quick-plot: qplot:qplot now returns a plot object, but it does not automatically register or display it.

Minimal plot-serving example

(ql:quickload '(:ls-server:quick-plot))
(ls-server:start-server)
(vega:load-vega-examples)
(import'(geom:point))
(import'(gg:label))
(import'(qplot:qplot))
(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p))

After registration, the plot is available through:

  • http://localhost:20202/plot/cars-basic
  • the plot index pages
  • any REPL URLs produced while the server is running

Explicit local display

If you also want to open the plot in a browser directly from Lisp, do that separately:

(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p)
(plot:plot p))

Loading example data

(ql:quickload :lisp-stat)
(vega:load-vega-examples)

You can also load other datasets and data frames through the normal Lisp-Stat mechanisms. Once they exist in the running image, LS-Server can expose them through its data and table endpoints.

API Endpoints

Data Endpoints

MethodPathDescription
GET/dataJSON array of available data frame names
GET/data/<name>Data frame contents, chosen by Accept header
PUT/data/<name>Replace a data frame with JSON row data
PATCH/data/<name>Update specific cells

Supported Accept types for GET /data/<name>:

Accept HeaderFormat
text/csv (default)CSV with header row
application/jsonJSON array of row objects
application/vega-jsonVega row-oriented JSON
text/s-expressionS-expression
(none or */*)CSV

Table Endpoints

MethodPathDescription
GET/table/<name>Interactive Handsontable page for the data frame

The table page displays data-frame documentation when available and loads its data through /data/<name>.

Plot Endpoints

MethodPathDescription
GET/plotJSON array of available plot names
GET/plot/<name>Plot page or raw Vega-Lite JSON spec
DELETE/plot/<name>Remove a plot from the registry

Supported Accept types for GET /plot/<name>:

Accept HeaderFormat
text/html (default)Full HTML page with Vega-Embed viewer
application/vega-jsonRaw Vega-Lite JSON specification

Navigation

MethodPathDescription
GET/Landing page
GET/plotsPlot gallery / index page
GET/tablesData-frame index page
GET/healthHealth endpoint returning {"status":"ok"}

Code Structure

ls-server/
├── ls-server.asd
├── src/
│ ├── pkgdcl.lisp
│ ├── config.lisp
│ ├── negotiation.lisp
│ ├── server.lisp
│ ├── health.lisp
│ ├── data-routes.lisp
│ ├── html.lisp
│ ├── plot-routes.lisp
│ ├── table-routes.lisp
│ ├── landing-routes.lisp
│ └── print-extensions.lisp
└── tests/
├── test-package.lisp
├── main.lisp
├── health-tests.lisp
├── server-tests.lisp
├── negotiation-tests.lisp
├── data-tests.lisp
├── plot-tests.lisp
├── table-tests.lisp
├── landing-tests.lisp
└── print-tests.lisp

Configuration

Configuration parameters are defined in src/config.lisp and can be set before starting the server.

ParameterDefaultDescription
*default-port*20202Default HTTP port
*server-host*"localhost"Hostname used in printed URLs
*access-log-destination*nilAccess log destination
*message-log-destination*nilMessage log destination

Example:

(setfls-server:*access-log-destination*"/tmp/ls-access.log")
(setfls-server:*message-log-destination*"/tmp/ls-messages.log")
(ls-server:start-server)

Testing

Run the main test suite:

(asdf:test-system :ls-server)

If the repo also exposes a dedicated test system in your local checkout, you can run that directly as well:

(asdf:test-system :ls-server/tests)

Example non-interactive run:

sbcl --non-interactive \
--eval '(ql:quickload :ls-server/tests)' \
--eval '(asdf:test-system "ls-server/tests")'

The test framework is CLUNIT2. Integration tests start a test server and exercise HTTP routes directly.

Resources

This system is part of the Lisp-Stat project; that should be your first stop for information. Also see the resources and community pages for more information.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated. Please see CONTRIBUTING for details on the code of conduct and the process for submitting pull requests.

License

Distributed under the MS-PL License. See LICENSE for more information.

Contact

Project Link: https://github.com/Lisp-Stat/ls-server

About

No description, website, or topics provided.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' GitHub - Lisp-Stat/ls-server · GitHub
Skip to content

Repository files navigation

ContributorsForksStargazersIssuesMS-PL LicenseLinkedIn


Logo

LS-Server

HTTP server for the Lisp-Stat system
Explore the docs »

Report Bug · Request Feature

Table of Contents

  1. About the Project
  2. Getting Started
  3. Usage
  4. Plot Workflow
  5. API Endpoints
  6. Code Structure
  7. Configuration
  8. Testing
  9. Resources
  10. Contributing
  11. License
  12. Contact

About the Project

LS-Server is an HTTP server for the Lisp-Stat system, built on Hunchentoot. It provides a lightweight browser-facing layer over Lisp-Stat data frames and registered plots.

Core capabilities:

  1. Plot viewing — serve registered plots as interactive Vega-Embed pages
  2. Plot gallery and navigation — browse available plots through index and gallery pages
  3. Data frame viewing and editing — view data frames in an editable Handsontable grid
  4. CSV / JSON / s-expression data serving — serve data-frame contents in multiple formats via content negotiation
  5. Vega-Lite spec serving — serve raw plot specifications for registered plots
  6. REPL integration — when the server is running, printed data frames and plots include server URLs

LS-Server does not own plot construction. Plot creation and registration belong to plot / vega. LS-Server consumes those public APIs and serves the registered results.

Built With

Getting Started

Prerequisites

Installation

Quicklisp installation

(ql:quickload :ls-server)

Source installation

  1. Clone the repository into a directory ASDF knows about:
cd~/common-lisp && \
git clone https://github.com/Lisp-Stat/ls-server.git
  1. Reset the ASDF source registry from the REPL:
(asdf:clear-source-registry)
  1. Load the system and its dependencies:
(ql:quickload :ls-server)

Usage

Start the server on the default port (20202):

(ls-server:start-server)

Start on a custom port:

(ls-server:start-server :port8080)

Stop the server:

(ls-server:stop-server)

Once started, open http://localhost:20202/ in a browser.

REPL URL decoration

When the server is running, printed data frames and plots include URLs:

LS-USER> mtcars
#<DATA-FRAME (32 observations of 11 variables)
Motor Trend Car Road Tests
http://localhost:20202/table/MTCARS>
LS-USER> some-plot
#<PLOT SOME-PLOT: ...
http://localhost:20202/plot/some-plot>

Depending on your terminal or editor, these URLs may be clickable.

Plot Workflow

A plot appears in LS-Server only after it has been registered.

This is especially important if you are using quick-plot: qplot:qplot now returns a plot object, but it does not automatically register or display it.

Minimal plot-serving example

(ql:quickload '(:ls-server:quick-plot))
(ls-server:start-server)
(vega:load-vega-examples)
(import'(geom:point))
(import'(gg:label))
(import'(qplot:qplot))
(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p))

After registration, the plot is available through:

  • http://localhost:20202/plot/cars-basic
  • the plot index pages
  • any REPL URLs produced while the server is running

Explicit local display

If you also want to open the plot in a browser directly from Lisp, do that separately:

(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p)
(plot:plot p))

Loading example data

(ql:quickload :lisp-stat)
(vega:load-vega-examples)

You can also load other datasets and data frames through the normal Lisp-Stat mechanisms. Once they exist in the running image, LS-Server can expose them through its data and table endpoints.

API Endpoints

Data Endpoints

MethodPathDescription
GET/dataJSON array of available data frame names
GET/data/<name>Data frame contents, chosen by Accept header
PUT/data/<name>Replace a data frame with JSON row data
PATCH/data/<name>Update specific cells

Supported Accept types for GET /data/<name>:

Accept HeaderFormat
text/csv (default)CSV with header row
application/jsonJSON array of row objects
application/vega-jsonVega row-oriented JSON
text/s-expressionS-expression
(none or */*)CSV

Table Endpoints

MethodPathDescription
GET/table/<name>Interactive Handsontable page for the data frame

The table page displays data-frame documentation when available and loads its data through /data/<name>.

Plot Endpoints

MethodPathDescription
GET/plotJSON array of available plot names
GET/plot/<name>Plot page or raw Vega-Lite JSON spec
DELETE/plot/<name>Remove a plot from the registry

Supported Accept types for GET /plot/<name>:

Accept HeaderFormat
text/html (default)Full HTML page with Vega-Embed viewer
application/vega-jsonRaw Vega-Lite JSON specification

Navigation

MethodPathDescription
GET/Landing page
GET/plotsPlot gallery / index page
GET/tablesData-frame index page
GET/healthHealth endpoint returning {"status":"ok"}

Code Structure

ls-server/
├── ls-server.asd
├── src/
│ ├── pkgdcl.lisp
│ ├── config.lisp
│ ├── negotiation.lisp
│ ├── server.lisp
│ ├── health.lisp
│ ├── data-routes.lisp
│ ├── html.lisp
│ ├── plot-routes.lisp
│ ├── table-routes.lisp
│ ├── landing-routes.lisp
│ └── print-extensions.lisp
└── tests/
├── test-package.lisp
├── main.lisp
├── health-tests.lisp
├── server-tests.lisp
├── negotiation-tests.lisp
├── data-tests.lisp
├── plot-tests.lisp
├── table-tests.lisp
├── landing-tests.lisp
└── print-tests.lisp

Configuration

Configuration parameters are defined in src/config.lisp and can be set before starting the server.

ParameterDefaultDescription
*default-port*20202Default HTTP port
*server-host*"localhost"Hostname used in printed URLs
*access-log-destination*nilAccess log destination
*message-log-destination*nilMessage log destination

Example:

(setfls-server:*access-log-destination*"/tmp/ls-access.log")
(setfls-server:*message-log-destination*"/tmp/ls-messages.log")
(ls-server:start-server)

Testing

Run the main test suite:

(asdf:test-system :ls-server)

If the repo also exposes a dedicated test system in your local checkout, you can run that directly as well:

(asdf:test-system :ls-server/tests)

Example non-interactive run:

sbcl --non-interactive \
--eval '(ql:quickload :ls-server/tests)' \
--eval '(asdf:test-system "ls-server/tests")'

The test framework is CLUNIT2. Integration tests start a test server and exercise HTTP routes directly.

Resources

This system is part of the Lisp-Stat project; that should be your first stop for information. Also see the resources and community pages for more information.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated. Please see CONTRIBUTING for details on the code of conduct and the process for submitting pull requests.

License

Distributed under the MS-PL License. See LICENSE for more information.

Contact

Project Link: https://github.com/Lisp-Stat/ls-server

About

No description, website, or topics provided.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - Lisp-Stat/ls-server · GitHub
Skip to content

Repository files navigation

ContributorsForksStargazersIssuesMS-PL LicenseLinkedIn


Logo

LS-Server

HTTP server for the Lisp-Stat system
Explore the docs »

Report Bug · Request Feature

Table of Contents

  1. About the Project
  2. Getting Started
  3. Usage
  4. Plot Workflow
  5. API Endpoints
  6. Code Structure
  7. Configuration
  8. Testing
  9. Resources
  10. Contributing
  11. License
  12. Contact

About the Project

LS-Server is an HTTP server for the Lisp-Stat system, built on Hunchentoot. It provides a lightweight browser-facing layer over Lisp-Stat data frames and registered plots.

Core capabilities:

  1. Plot viewing — serve registered plots as interactive Vega-Embed pages
  2. Plot gallery and navigation — browse available plots through index and gallery pages
  3. Data frame viewing and editing — view data frames in an editable Handsontable grid
  4. CSV / JSON / s-expression data serving — serve data-frame contents in multiple formats via content negotiation
  5. Vega-Lite spec serving — serve raw plot specifications for registered plots
  6. REPL integration — when the server is running, printed data frames and plots include server URLs

LS-Server does not own plot construction. Plot creation and registration belong to plot / vega. LS-Server consumes those public APIs and serves the registered results.

Built With

Getting Started

Prerequisites

Installation

Quicklisp installation

(ql:quickload :ls-server)

Source installation

  1. Clone the repository into a directory ASDF knows about:
cd~/common-lisp && \
git clone https://github.com/Lisp-Stat/ls-server.git
  1. Reset the ASDF source registry from the REPL:
(asdf:clear-source-registry)
  1. Load the system and its dependencies:
(ql:quickload :ls-server)

Usage

Start the server on the default port (20202):

(ls-server:start-server)

Start on a custom port:

(ls-server:start-server :port8080)

Stop the server:

(ls-server:stop-server)

Once started, open http://localhost:20202/ in a browser.

REPL URL decoration

When the server is running, printed data frames and plots include URLs:

LS-USER> mtcars
#<DATA-FRAME (32 observations of 11 variables)
Motor Trend Car Road Tests
http://localhost:20202/table/MTCARS>
LS-USER> some-plot
#<PLOT SOME-PLOT: ...
http://localhost:20202/plot/some-plot>

Depending on your terminal or editor, these URLs may be clickable.

Plot Workflow

A plot appears in LS-Server only after it has been registered.

This is especially important if you are using quick-plot: qplot:qplot now returns a plot object, but it does not automatically register or display it.

Minimal plot-serving example

(ql:quickload '(:ls-server:quick-plot))
(ls-server:start-server)
(vega:load-vega-examples)
(import'(geom:point))
(import'(gg:label))
(import'(qplot:qplot))
(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p))

After registration, the plot is available through:

  • http://localhost:20202/plot/cars-basic
  • the plot index pages
  • any REPL URLs produced while the server is running

Explicit local display

If you also want to open the plot in a browser directly from Lisp, do that separately:

(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p)
(plot:plot p))

Loading example data

(ql:quickload :lisp-stat)
(vega:load-vega-examples)

You can also load other datasets and data frames through the normal Lisp-Stat mechanisms. Once they exist in the running image, LS-Server can expose them through its data and table endpoints.

API Endpoints

Data Endpoints

MethodPathDescription
GET/dataJSON array of available data frame names
GET/data/<name>Data frame contents, chosen by Accept header
PUT/data/<name>Replace a data frame with JSON row data
PATCH/data/<name>Update specific cells

Supported Accept types for GET /data/<name>:

Accept HeaderFormat
text/csv (default)CSV with header row
application/jsonJSON array of row objects
application/vega-jsonVega row-oriented JSON
text/s-expressionS-expression
(none or */*)CSV

Table Endpoints

MethodPathDescription
GET/table/<name>Interactive Handsontable page for the data frame

The table page displays data-frame documentation when available and loads its data through /data/<name>.

Plot Endpoints

MethodPathDescription
GET/plotJSON array of available plot names
GET/plot/<name>Plot page or raw Vega-Lite JSON spec
DELETE/plot/<name>Remove a plot from the registry

Supported Accept types for GET /plot/<name>:

Accept HeaderFormat
text/html (default)Full HTML page with Vega-Embed viewer
application/vega-jsonRaw Vega-Lite JSON specification

Navigation

MethodPathDescription
GET/Landing page
GET/plotsPlot gallery / index page
GET/tablesData-frame index page
GET/healthHealth endpoint returning {"status":"ok"}

Code Structure

ls-server/
├── ls-server.asd
├── src/
│ ├── pkgdcl.lisp
│ ├── config.lisp
│ ├── negotiation.lisp
│ ├── server.lisp
│ ├── health.lisp
│ ├── data-routes.lisp
│ ├── html.lisp
│ ├── plot-routes.lisp
│ ├── table-routes.lisp
│ ├── landing-routes.lisp
│ └── print-extensions.lisp
└── tests/
├── test-package.lisp
├── main.lisp
├── health-tests.lisp
├── server-tests.lisp
├── negotiation-tests.lisp
├── data-tests.lisp
├── plot-tests.lisp
├── table-tests.lisp
├── landing-tests.lisp
└── print-tests.lisp

Configuration

Configuration parameters are defined in src/config.lisp and can be set before starting the server.

ParameterDefaultDescription
*default-port*20202Default HTTP port
*server-host*"localhost"Hostname used in printed URLs
*access-log-destination*nilAccess log destination
*message-log-destination*nilMessage log destination

Example:

(setfls-server:*access-log-destination*"/tmp/ls-access.log")
(setfls-server:*message-log-destination*"/tmp/ls-messages.log")
(ls-server:start-server)

Testing

Run the main test suite:

(asdf:test-system :ls-server)

If the repo also exposes a dedicated test system in your local checkout, you can run that directly as well:

(asdf:test-system :ls-server/tests)

Example non-interactive run:

sbcl --non-interactive \
--eval '(ql:quickload :ls-server/tests)' \
--eval '(asdf:test-system "ls-server/tests")'

The test framework is CLUNIT2. Integration tests start a test server and exercise HTTP routes directly.

Resources

This system is part of the Lisp-Stat project; that should be your first stop for information. Also see the resources and community pages for more information.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated. Please see CONTRIBUTING for details on the code of conduct and the process for submitting pull requests.

License

Distributed under the MS-PL License. See LICENSE for more information.

Contact

Project Link: https://github.com/Lisp-Stat/ls-server

About

No description, website, or topics provided.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' GitHub - Lisp-Stat/ls-server · GitHub
Skip to content

Repository files navigation

ContributorsForksStargazersIssuesMS-PL LicenseLinkedIn


Logo

LS-Server

HTTP server for the Lisp-Stat system
Explore the docs »

Report Bug · Request Feature

Table of Contents

  1. About the Project
  2. Getting Started
  3. Usage
  4. Plot Workflow
  5. API Endpoints
  6. Code Structure
  7. Configuration
  8. Testing
  9. Resources
  10. Contributing
  11. License
  12. Contact

About the Project

LS-Server is an HTTP server for the Lisp-Stat system, built on Hunchentoot. It provides a lightweight browser-facing layer over Lisp-Stat data frames and registered plots.

Core capabilities:

  1. Plot viewing — serve registered plots as interactive Vega-Embed pages
  2. Plot gallery and navigation — browse available plots through index and gallery pages
  3. Data frame viewing and editing — view data frames in an editable Handsontable grid
  4. CSV / JSON / s-expression data serving — serve data-frame contents in multiple formats via content negotiation
  5. Vega-Lite spec serving — serve raw plot specifications for registered plots
  6. REPL integration — when the server is running, printed data frames and plots include server URLs

LS-Server does not own plot construction. Plot creation and registration belong to plot / vega. LS-Server consumes those public APIs and serves the registered results.

Built With

Getting Started

Prerequisites

Installation

Quicklisp installation

(ql:quickload :ls-server)

Source installation

  1. Clone the repository into a directory ASDF knows about:
cd~/common-lisp && \
git clone https://github.com/Lisp-Stat/ls-server.git
  1. Reset the ASDF source registry from the REPL:
(asdf:clear-source-registry)
  1. Load the system and its dependencies:
(ql:quickload :ls-server)

Usage

Start the server on the default port (20202):

(ls-server:start-server)

Start on a custom port:

(ls-server:start-server :port8080)

Stop the server:

(ls-server:stop-server)

Once started, open http://localhost:20202/ in a browser.

REPL URL decoration

When the server is running, printed data frames and plots include URLs:

LS-USER> mtcars
#<DATA-FRAME (32 observations of 11 variables)
Motor Trend Car Road Tests
http://localhost:20202/table/MTCARS>
LS-USER> some-plot
#<PLOT SOME-PLOT: ...
http://localhost:20202/plot/some-plot>

Depending on your terminal or editor, these URLs may be clickable.

Plot Workflow

A plot appears in LS-Server only after it has been registered.

This is especially important if you are using quick-plot: qplot:qplot now returns a plot object, but it does not automatically register or display it.

Minimal plot-serving example

(ql:quickload '(:ls-server:quick-plot))
(ls-server:start-server)
(vega:load-vega-examples)
(import'(geom:point))
(import'(gg:label))
(import'(qplot:qplot))
(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p))

After registration, the plot is available through:

  • http://localhost:20202/plot/cars-basic
  • the plot index pages
  • any REPL URLs produced while the server is running

Explicit local display

If you also want to open the plot in a browser directly from Lisp, do that separately:

(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p)
(plot:plot p))

Loading example data

(ql:quickload :lisp-stat)
(vega:load-vega-examples)

You can also load other datasets and data frames through the normal Lisp-Stat mechanisms. Once they exist in the running image, LS-Server can expose them through its data and table endpoints.

API Endpoints

Data Endpoints

MethodPathDescription
GET/dataJSON array of available data frame names
GET/data/<name>Data frame contents, chosen by Accept header
PUT/data/<name>Replace a data frame with JSON row data
PATCH/data/<name>Update specific cells

Supported Accept types for GET /data/<name>:

Accept HeaderFormat
text/csv (default)CSV with header row
application/jsonJSON array of row objects
application/vega-jsonVega row-oriented JSON
text/s-expressionS-expression
(none or */*)CSV

Table Endpoints

MethodPathDescription
GET/table/<name>Interactive Handsontable page for the data frame

The table page displays data-frame documentation when available and loads its data through /data/<name>.

Plot Endpoints

MethodPathDescription
GET/plotJSON array of available plot names
GET/plot/<name>Plot page or raw Vega-Lite JSON spec
DELETE/plot/<name>Remove a plot from the registry

Supported Accept types for GET /plot/<name>:

Accept HeaderFormat
text/html (default)Full HTML page with Vega-Embed viewer
application/vega-jsonRaw Vega-Lite JSON specification

Navigation

MethodPathDescription
GET/Landing page
GET/plotsPlot gallery / index page
GET/tablesData-frame index page
GET/healthHealth endpoint returning {"status":"ok"}

Code Structure

ls-server/
├── ls-server.asd
├── src/
│ ├── pkgdcl.lisp
│ ├── config.lisp
│ ├── negotiation.lisp
│ ├── server.lisp
│ ├── health.lisp
│ ├── data-routes.lisp
│ ├── html.lisp
│ ├── plot-routes.lisp
│ ├── table-routes.lisp
│ ├── landing-routes.lisp
│ └── print-extensions.lisp
└── tests/
├── test-package.lisp
├── main.lisp
├── health-tests.lisp
├── server-tests.lisp
├── negotiation-tests.lisp
├── data-tests.lisp
├── plot-tests.lisp
├── table-tests.lisp
├── landing-tests.lisp
└── print-tests.lisp

Configuration

Configuration parameters are defined in src/config.lisp and can be set before starting the server.

ParameterDefaultDescription
*default-port*20202Default HTTP port
*server-host*"localhost"Hostname used in printed URLs
*access-log-destination*nilAccess log destination
*message-log-destination*nilMessage log destination

Example:

(setfls-server:*access-log-destination*"/tmp/ls-access.log")
(setfls-server:*message-log-destination*"/tmp/ls-messages.log")
(ls-server:start-server)

Testing

Run the main test suite:

(asdf:test-system :ls-server)

If the repo also exposes a dedicated test system in your local checkout, you can run that directly as well:

(asdf:test-system :ls-server/tests)

Example non-interactive run:

sbcl --non-interactive \
--eval '(ql:quickload :ls-server/tests)' \
--eval '(asdf:test-system "ls-server/tests")'

The test framework is CLUNIT2. Integration tests start a test server and exercise HTTP routes directly.

Resources

This system is part of the Lisp-Stat project; that should be your first stop for information. Also see the resources and community pages for more information.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated. Please see CONTRIBUTING for details on the code of conduct and the process for submitting pull requests.

License

Distributed under the MS-PL License. See LICENSE for more information.

Contact

Project Link: https://github.com/Lisp-Stat/ls-server

About

No description, website, or topics provided.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); GitHub - Lisp-Stat/ls-server · GitHub
Skip to content

Repository files navigation

ContributorsForksStargazersIssuesMS-PL LicenseLinkedIn


Logo

LS-Server

HTTP server for the Lisp-Stat system
Explore the docs »

Report Bug · Request Feature

Table of Contents

  1. About the Project
  2. Getting Started
  3. Usage
  4. Plot Workflow
  5. API Endpoints
  6. Code Structure
  7. Configuration
  8. Testing
  9. Resources
  10. Contributing
  11. License
  12. Contact

About the Project

LS-Server is an HTTP server for the Lisp-Stat system, built on Hunchentoot. It provides a lightweight browser-facing layer over Lisp-Stat data frames and registered plots.

Core capabilities:

  1. Plot viewing — serve registered plots as interactive Vega-Embed pages
  2. Plot gallery and navigation — browse available plots through index and gallery pages
  3. Data frame viewing and editing — view data frames in an editable Handsontable grid
  4. CSV / JSON / s-expression data serving — serve data-frame contents in multiple formats via content negotiation
  5. Vega-Lite spec serving — serve raw plot specifications for registered plots
  6. REPL integration — when the server is running, printed data frames and plots include server URLs

LS-Server does not own plot construction. Plot creation and registration belong to plot / vega. LS-Server consumes those public APIs and serves the registered results.

Built With

Getting Started

Prerequisites

Installation

Quicklisp installation

(ql:quickload :ls-server)

Source installation

  1. Clone the repository into a directory ASDF knows about:
cd~/common-lisp && \
git clone https://github.com/Lisp-Stat/ls-server.git
  1. Reset the ASDF source registry from the REPL:
(asdf:clear-source-registry)
  1. Load the system and its dependencies:
(ql:quickload :ls-server)

Usage

Start the server on the default port (20202):

(ls-server:start-server)

Start on a custom port:

(ls-server:start-server :port8080)

Stop the server:

(ls-server:stop-server)

Once started, open http://localhost:20202/ in a browser.

REPL URL decoration

When the server is running, printed data frames and plots include URLs:

LS-USER> mtcars
#<DATA-FRAME (32 observations of 11 variables)
Motor Trend Car Road Tests
http://localhost:20202/table/MTCARS>
LS-USER> some-plot
#<PLOT SOME-PLOT: ...
http://localhost:20202/plot/some-plot>

Depending on your terminal or editor, these URLs may be clickable.

Plot Workflow

A plot appears in LS-Server only after it has been registered.

This is especially important if you are using quick-plot: qplot:qplot now returns a plot object, but it does not automatically register or display it.

Minimal plot-serving example

(ql:quickload '(:ls-server:quick-plot))
(ls-server:start-server)
(vega:load-vega-examples)
(import'(geom:point))
(import'(gg:label))
(import'(qplot:qplot))
(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p))

After registration, the plot is available through:

  • http://localhost:20202/plot/cars-basic
  • the plot index pages
  • any REPL URLs produced while the server is running

Explicit local display

If you also want to open the plot in a browser directly from Lisp, do that separately:

(let ((p (qplot 'cars-basic vgcars
'(:title"Horsepower vs. MPG")
(point :horsepower:miles-per-gallon)
(label :x"Horsepower":y"MPG"))))
(vega:register-plot p)
(plot:plot p))

Loading example data

(ql:quickload :lisp-stat)
(vega:load-vega-examples)

You can also load other datasets and data frames through the normal Lisp-Stat mechanisms. Once they exist in the running image, LS-Server can expose them through its data and table endpoints.

API Endpoints

Data Endpoints

MethodPathDescription
GET/dataJSON array of available data frame names
GET/data/<name>Data frame contents, chosen by Accept header
PUT/data/<name>Replace a data frame with JSON row data
PATCH/data/<name>Update specific cells

Supported Accept types for GET /data/<name>:

Accept HeaderFormat
text/csv (default)CSV with header row
application/jsonJSON array of row objects
application/vega-jsonVega row-oriented JSON
text/s-expressionS-expression
(none or */*)CSV

Table Endpoints

MethodPathDescription
GET/table/<name>Interactive Handsontable page for the data frame

The table page displays data-frame documentation when available and loads its data through /data/<name>.

Plot Endpoints

MethodPathDescription
GET/plotJSON array of available plot names
GET/plot/<name>Plot page or raw Vega-Lite JSON spec
DELETE/plot/<name>Remove a plot from the registry

Supported Accept types for GET /plot/<name>:

Accept HeaderFormat
text/html (default)Full HTML page with Vega-Embed viewer
application/vega-jsonRaw Vega-Lite JSON specification

Navigation

MethodPathDescription
GET/Landing page
GET/plotsPlot gallery / index page
GET/tablesData-frame index page
GET/healthHealth endpoint returning {"status":"ok"}

Code Structure

ls-server/
├── ls-server.asd
├── src/
│ ├── pkgdcl.lisp
│ ├── config.lisp
│ ├── negotiation.lisp
│ ├── server.lisp
│ ├── health.lisp
│ ├── data-routes.lisp
│ ├── html.lisp
│ ├── plot-routes.lisp
│ ├── table-routes.lisp
│ ├── landing-routes.lisp
│ └── print-extensions.lisp
└── tests/
├── test-package.lisp
├── main.lisp
├── health-tests.lisp
├── server-tests.lisp
├── negotiation-tests.lisp
├── data-tests.lisp
├── plot-tests.lisp
├── table-tests.lisp
├── landing-tests.lisp
└── print-tests.lisp

Configuration

Configuration parameters are defined in src/config.lisp and can be set before starting the server.

ParameterDefaultDescription
*default-port*20202Default HTTP port
*server-host*"localhost"Hostname used in printed URLs
*access-log-destination*nilAccess log destination
*message-log-destination*nilMessage log destination

Example:

(setfls-server:*access-log-destination*"/tmp/ls-access.log")
(setfls-server:*message-log-destination*"/tmp/ls-messages.log")
(ls-server:start-server)

Testing

Run the main test suite:

(asdf:test-system :ls-server)

If the repo also exposes a dedicated test system in your local checkout, you can run that directly as well:

(asdf:test-system :ls-server/tests)

Example non-interactive run:

sbcl --non-interactive \
--eval '(ql:quickload :ls-server/tests)' \
--eval '(asdf:test-system "ls-server/tests")'

The test framework is CLUNIT2. Integration tests start a test server and exercise HTTP routes directly.

Resources

This system is part of the Lisp-Stat project; that should be your first stop for information. Also see the resources and community pages for more information.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated. Please see CONTRIBUTING for details on the code of conduct and the process for submitting pull requests.

License

Distributed under the MS-PL License. See LICENSE for more information.

Contact

Project Link: https://github.com/Lisp-Stat/ls-server

About

No description, website, or topics provided.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages