chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
# ClickHouse Virtual Server
|
||||
|
||||
Perspective provides a built-in virtual server for
|
||||
[ClickHouse](https://clickhouse.com/), allowing `<perspective-viewer>` clients
|
||||
to query a ClickHouse server over WebSocket.
|
||||
|
||||
For browser-only usage, see the
|
||||
[JavaScript ClickHouse guide](../../javascript/virtual_server/clickhouse.md).
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install perspective-python clickhouse-connect
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Create a server that exposes ClickHouse tables to browser clients:
|
||||
|
||||
```python
|
||||
import clickhouse_connect
|
||||
import tornado.web
|
||||
import tornado.ioloop
|
||||
from perspective import ClickhouseVirtualServer
|
||||
from perspective.handlers.tornado import PerspectiveTornadoHandler
|
||||
|
||||
# Connect to ClickHouse
|
||||
client = clickhouse_connect.get_client(host="localhost")
|
||||
|
||||
# Create virtual server backed by ClickHouse
|
||||
server = ClickhouseVirtualServer(client)
|
||||
|
||||
# Serve over WebSocket
|
||||
app = tornado.web.Application([
|
||||
(r"/websocket", PerspectiveTornadoHandler, {"perspective_server": server}),
|
||||
])
|
||||
|
||||
app.listen(8080)
|
||||
tornado.ioloop.IOLoop.current().start()
|
||||
```
|
||||
|
||||
Connect from the browser:
|
||||
|
||||
```javascript
|
||||
const websocket = await perspective.websocket("ws://localhost:8080/websocket");
|
||||
const table = await websocket.open_table("my_table");
|
||||
document.getElementById("viewer").load(table);
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
- [Python ClickHouse example](https://github.com/perspective-dev/perspective/tree/master/examples/python-clickhouse-virtual)
|
||||
@@ -0,0 +1,64 @@
|
||||
# Implementing a custom Virtual Server
|
||||
|
||||
You can connect Perspective to any data source by subclassing
|
||||
`VirtualServerHandler` and wrapping it with `VirtualServer`.
|
||||
|
||||
For background on virtual servers, see the
|
||||
[Virtual Servers overview](../../../explanation/virtual_servers.md).
|
||||
|
||||
## Example
|
||||
|
||||
```python
|
||||
from perspective import VirtualServerHandler, VirtualServer
|
||||
|
||||
class MyModel(VirtualServerHandler):
|
||||
def get_features(self):
|
||||
return {
|
||||
"group_by": True,
|
||||
"split_by": False,
|
||||
"sort": True,
|
||||
"filter_ops": {
|
||||
"string": ["==", "!=", "contains"],
|
||||
"float": ["==", "!=", ">", "<"],
|
||||
},
|
||||
"aggregates": {
|
||||
"float": ["sum", "avg", "count"],
|
||||
"string": ["count"],
|
||||
},
|
||||
}
|
||||
|
||||
def get_hosted_tables(self):
|
||||
return ["my_table"]
|
||||
|
||||
def table_schema(self, table_name):
|
||||
return {"name": "string", "price": "float"}
|
||||
|
||||
def table_size(self, table_name):
|
||||
return 1000
|
||||
|
||||
def table_make_view(self, table_name, view_id, config):
|
||||
# Translate `config` (group_by, sort, filter, etc.) into a
|
||||
# query against your data source. Store the query keyed by
|
||||
# `view_id` for later data retrieval.
|
||||
pass
|
||||
|
||||
def view_delete(self, view_id):
|
||||
# Clean up resources for this view
|
||||
pass
|
||||
|
||||
def view_get_data(self, view_id, start_row, end_row, start_col, end_col, ctx):
|
||||
# Execute the stored query with the given row/column window.
|
||||
# Push results via `ctx`.
|
||||
pass
|
||||
```
|
||||
|
||||
The `VirtualServer` instance can then be passed to a Tornado, Starlette, or
|
||||
AIOHTTP handler just like a regular `Server`:
|
||||
|
||||
```python
|
||||
from perspective.handlers.tornado import PerspectiveTornadoHandler
|
||||
|
||||
app = tornado.web.Application([
|
||||
(r"/websocket", PerspectiveTornadoHandler, {"perspective_server": VirtualServer(MyModel)}),
|
||||
])
|
||||
```
|
||||
@@ -0,0 +1,53 @@
|
||||
# DuckDB Virtual Server
|
||||
|
||||
Perspective provides a built-in virtual server for
|
||||
[DuckDB](https://duckdb.org/), allowing `<perspective-viewer>` clients to query
|
||||
a server-side DuckDB database over WebSocket.
|
||||
|
||||
For browser-only usage via DuckDB-WASM, see the
|
||||
[JavaScript DuckDB guide](../../javascript/virtual_server/duckdb.md).
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install perspective-python duckdb
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Create a server that exposes a DuckDB database to browser clients:
|
||||
|
||||
```python
|
||||
import duckdb
|
||||
import tornado.web
|
||||
import tornado.ioloop
|
||||
from perspective import DuckDBVirtualServer
|
||||
from perspective.handlers.tornado import PerspectiveTornadoHandler
|
||||
|
||||
# Create DuckDB connection and load data
|
||||
conn = duckdb.connect()
|
||||
conn.execute("CREATE TABLE my_table AS SELECT * FROM 'data.parquet'")
|
||||
|
||||
# Create virtual server backed by DuckDB
|
||||
server = DuckDBVirtualServer(conn)
|
||||
|
||||
# Serve over WebSocket
|
||||
app = tornado.web.Application([
|
||||
(r"/websocket", PerspectiveTornadoHandler, {"perspective_server": server}),
|
||||
])
|
||||
|
||||
app.listen(8080)
|
||||
tornado.ioloop.IOLoop.current().start()
|
||||
```
|
||||
|
||||
Connect from the browser:
|
||||
|
||||
```javascript
|
||||
const websocket = await perspective.websocket("ws://localhost:8080/websocket");
|
||||
const table = await websocket.open_table("my_table");
|
||||
document.getElementById("viewer").load(table);
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
- [Python DuckDB example](https://github.com/perspective-dev/perspective/tree/master/examples/python-duckdb-virtual)
|
||||
@@ -0,0 +1,49 @@
|
||||
# Polars Virtual Server
|
||||
|
||||
Perspective provides a built-in virtual server for
|
||||
[Polars](https://pola.rs/), allowing `<perspective-viewer>` clients to query
|
||||
in-memory Polars DataFrames over WebSocket.
|
||||
|
||||
## Installation
|
||||
|
||||
```bash
|
||||
pip install perspective-python polars
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Create a server that exposes Polars DataFrames to browser clients:
|
||||
|
||||
```python
|
||||
import polars as pl
|
||||
import tornado.web
|
||||
import tornado.ioloop
|
||||
from perspective.virtual_servers.polars import PolarsVirtualServer
|
||||
from perspective.handlers.tornado import PerspectiveTornadoHandler
|
||||
|
||||
# Load data into Polars DataFrames
|
||||
df = pl.read_parquet("data.parquet")
|
||||
|
||||
# Create virtual server backed by Polars (dict of name -> DataFrame)
|
||||
server = PolarsVirtualServer({"my_table": df})
|
||||
|
||||
# Serve over WebSocket
|
||||
app = tornado.web.Application([
|
||||
(r"/websocket", PerspectiveTornadoHandler, {"perspective_server": server}),
|
||||
])
|
||||
|
||||
app.listen(8080)
|
||||
tornado.ioloop.IOLoop.current().start()
|
||||
```
|
||||
|
||||
Connect from the browser:
|
||||
|
||||
```javascript
|
||||
const websocket = await perspective.websocket("ws://localhost:8080/websocket");
|
||||
const table = await websocket.open_table("my_table");
|
||||
document.getElementById("viewer").load(table);
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
- [Python Polars example](https://github.com/perspective-dev/perspective/tree/master/examples/python-polars-virtual)
|
||||
Reference in New Issue
Block a user