pub struct Client(/* private fields */);
Expand description
An instance of a Client
is a unique connection to a single
perspective_server::Server
, whether locally in-memory or remote over some
transport like a WebSocket.
perspective
docs for the Rust API.
The browser and node.js libraries both support the websocket(url)
constructor,
which connects to a remote perspective_server::Server
instance over a
WebSocket transport.
In the browser, the worker()
constructor creates a new Web Worker
perspective_server::Server
and returns a Client
connected to it.
In node.js, a pre-instantied Client
connected synhronously to a global
singleton perspective_server::Server
is the default module export.
§JavaScript Examples
Create a Web Worker perspective_server::Server
in the browser and return a
Client
instance connected for it:
import perspective from "@finos/perspective";
const client = await perspective.worker();
Create a WebSocket connection to a remote perspective_server::Server
:
import perspective from "@finos/perspective";
const client = await perspective.websocket("ws://locahost:8080/ws");
Access the synchronous client in node.js:
import { default as client } from "@finos/perspective";
perspective
docs for the Rust API.
§Python Examples
Create a perspective_server::Server
and a local, synchronous Client
instance connected for it:
import perspective;
server = perspective.Server()
client = server.new_local_client();
Implementations§
Source§impl Client
impl Client
pub fn new( handle_request: Py<PyAny>, close_cb: Option<Py<PyAny>>, ) -> PyResult<Self>
pub fn from_server( py: Python<'_>, server: Py<PySyncServer>, loop_callback: Option<Py<PyAny>>, ) -> PyResult<Self>
pub fn handle_response( &self, py: Python<'_>, response: Py<PyBytes>, ) -> PyResult<bool>
Sourcepub fn table(
&self,
py: Python<'_>,
input: Py<PyAny>,
limit: Option<u32>,
index: Option<Py<PyString>>,
name: Option<Py<PyString>>,
format: Option<Py<PyString>>,
) -> PyResult<Table>
pub fn table( &self, py: Python<'_>, input: Py<PyAny>, limit: Option<u32>, index: Option<Py<PyString>>, name: Option<Py<PyString>>, format: Option<Py<PyString>>, ) -> PyResult<Table>
Creates a new Table
from either a schema or data.
The Client::table
factory function can be initialized with either a schema
(see Table::schema
), or data in one of these formats:
- Apache Arrow
- CSV
- JSON row-oriented
- JSON column-oriented
When instantiated with data, the schema is inferred from this data. While this
is convenient, inferrence is sometimes imperfect e.g. when the input is empty,
null or ambiguous. For these cases, Client::table
can first be instantiated
with a explicit schema.
When instantiated with a schema, the resulting Table
is empty but with
known column names and column types. When subsqeuently populated with
Table::update
, these columns will be coerced to the schema’s type. This
behavior can be useful when Client::table
’s column type inferences doesn’t
work.
The resulting Table
is virtual, and invoking its methods dispatches events
to the perspective_server::Server
this Client
connects to, where the data
is stored and all calculation occurs.
§Arguments
arg
- Either schema or initialization data.options
- Optional configuration which provides one of:limit
- The max number of rows the resultingTable
can store.index
- The column name to use as an index column. If thisTable
is being instantiated by data, this column name must be present in the data.name
- The name of the table. This will be generated if it is not provided.format
- The explicit format of the input data, can be one of"json"
,"columns"
,"csv"
or"arrow"
. This overrides language-specific type dispatch behavior, which allows stringified and byte array alternative inputs.
§JavaScript Examples
Load a CSV from a string
:
const table = await client.table("x,y\n1,2\n3,4");
Load an Arrow from an ArrayBuffer
:
import * as fs from "node:fs/promises";
const table2 = await client.table(await fs.readFile("superstore.arrow"));
Load a CSV from a UInt8Array
(the default for this type is Arrow) using a
format override:
const enc = new TextEncoder();
const table = await client.table(enc.encode("x,y\n1,2\n3,4"), {
format: "csv",
});
Create a table with an index
:
const table = await client.table(data, { index: "Row ID" });
§Examples
Load a CSV from a String
:
let opts = TableInitOptions::default();
let data = TableData::Update(UpdateData::Csv("x,y\n1,2\n3,4".into()));
let table = client.table(data, opts).await?;
Sourcepub fn open_table(&self, py: Python<'_>, name: String) -> PyResult<Table>
pub fn open_table(&self, py: Python<'_>, name: String) -> PyResult<Table>
Opens a Table
that is hosted on the perspective_server::Server
that is
connected to this Client
.
The name
property of TableInitOptions
is used to identify each Table
.
Table
name
s can be looked up for each Client
via
Client::get_hosted_table_names
.
§JavaScript Examples
Get a virtual Table
named “table_one” from this Client
const tables = await client.open_table("table_one");
§Python Examples
tables = client.open_table("table_one");
§Examples
let tables = client.open_table("table_one").await;
Sourcepub fn get_hosted_table_names(&self, py: Python<'_>) -> PyResult<Vec<String>>
pub fn get_hosted_table_names(&self, py: Python<'_>) -> PyResult<Vec<String>>
Retrieves the names of all tables that this client has access to.
name
is a string identifier unique to the Table
(per Client
), which
can be used in conjunction with Client::open_table
to get a Table
instance without the use of Client::table
constructor directly (e.g., one
created by another Client
).
§JavaScript Examples
const tables = await client.get_hosted_table_names();
§Python Examples
tables = client.get_hosted_table_names();
§Examples
let tables = client.get_hosted_table_names().await;
Sourcepub fn on_hosted_tables_update(
&self,
py: Python<'_>,
callback: Py<PyAny>,
) -> PyResult<u32>
pub fn on_hosted_tables_update( &self, py: Python<'_>, callback: Py<PyAny>, ) -> PyResult<u32>
Register a callback which is invoked whenever Client::table
(on this Client
)
or Table::delete
(on a Table
belinging to this Client
) are called.
§JavaScript Examples
const sub = await client.on_hosted_tables_update(() => {
console.log("Tables have updated!", await client.get_hosted_table_names());
});
// This invokes the handler
const table = await client.table("x\n1", {name: "test"});
// So does this
await table.delete();
// cleanup
await client.remove_hosted_tables_update(sub);
Sourcepub fn remove_hosted_tables_update(
&self,
py: Python<'_>,
callback_id: u32,
) -> PyResult<()>
pub fn remove_hosted_tables_update( &self, py: Python<'_>, callback_id: u32, ) -> PyResult<()>
Remove a callback previously registered via Client::on_hosted_tables_update
.
Sourcepub fn set_loop_callback(
&self,
py: Python<'_>,
loop_cb: Py<PyAny>,
) -> PyResult<()>
pub fn set_loop_callback( &self, py: Python<'_>, loop_cb: Py<PyAny>, ) -> PyResult<()>
Methods such as View::on_update
take a callback function as an argument,
which may be invoked by the Perspective runtime when updates occur. If provided
a loop callback function via Client::set_loop_callback
, such callback
function invocations be passed to the loop callback instead.
Client::set_loop_callback
can be used to control scheduling/conflation (e.g.
by adding a delay), as well as executor integration.
Trait Implementations§
Source§impl<'py> IntoPyObject<'py> for Client
impl<'py> IntoPyObject<'py> for Client
Source§type Output = Bound<'py, <Client as IntoPyObject<'py>>::Target>
type Output = Bound<'py, <Client as IntoPyObject<'py>>::Target>
Source§fn into_pyobject(
self,
py: Python<'py>,
) -> Result<<Self as IntoPyObject<'_>>::Output, <Self as IntoPyObject<'_>>::Error>
fn into_pyobject( self, py: Python<'py>, ) -> Result<<Self as IntoPyObject<'_>>::Output, <Self as IntoPyObject<'_>>::Error>
Source§impl PyClassBaseType for Client
impl PyClassBaseType for Client
type LayoutAsBase = PyClassObject<Client>
type BaseNativeType = <Client as PyClassImpl>::BaseNativeType
type Initializer = PyClassInitializer<Client>
type PyClassMutability = <Client as PyClassImpl>::PyClassMutability
Source§impl PyClassImpl for Client
impl PyClassImpl for Client
Source§const IS_BASETYPE: bool = true
const IS_BASETYPE: bool = true
Source§const IS_SUBCLASS: bool = false
const IS_SUBCLASS: bool = false
Source§const IS_MAPPING: bool = false
const IS_MAPPING: bool = false
Source§const IS_SEQUENCE: bool = false
const IS_SEQUENCE: bool = false
Source§type ThreadChecker = SendablePyClass<Client>
type ThreadChecker = SendablePyClass<Client>
Source§type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::MutableChild
type PyClassMutability = <<PyAny as PyClassBaseType>::PyClassMutability as PyClassMutability>::MutableChild
Source§type BaseNativeType = PyAny
type BaseNativeType = PyAny
PyAny
by default, and when you declare
#[pyclass(extends=PyDict)]
, it’s PyDict
.fn items_iter() -> PyClassItemsIter
fn lazy_type_object() -> &'static LazyTypeObject<Self>
fn dict_offset() -> Option<isize>
fn weaklist_offset() -> Option<isize>
Source§impl PyClassNewTextSignature<Client> for PyClassImplCollector<Client>
impl PyClassNewTextSignature<Client> for PyClassImplCollector<Client>
fn new_text_signature(self) -> Option<&'static str>
Source§impl PyMethods<Client> for PyClassImplCollector<Client>
impl PyMethods<Client> for PyClassImplCollector<Client>
fn py_methods(self) -> &'static PyClassItems
Source§impl PyTypeInfo for Client
impl PyTypeInfo for Client
Source§fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject
fn type_object_raw(py: Python<'_>) -> *mut PyTypeObject
Source§fn type_object(py: Python<'_>) -> Bound<'_, PyType>
fn type_object(py: Python<'_>) -> Bound<'_, PyType>
Source§fn type_object_bound(py: Python<'_>) -> Bound<'_, PyType>
fn type_object_bound(py: Python<'_>) -> Bound<'_, PyType>
PyTypeInfo::type_object
PyTypeInfo::type_object
.Source§fn is_type_of(object: &Bound<'_, PyAny>) -> bool
fn is_type_of(object: &Bound<'_, PyAny>) -> bool
object
is an instance of this type or a subclass of this type.Source§fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool
fn is_type_of_bound(object: &Bound<'_, PyAny>) -> bool
PyTypeInfo::is_type_of
PyTypeInfo::is_type_of
.Source§fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool
fn is_exact_type_of(object: &Bound<'_, PyAny>) -> bool
object
is an instance of this type.Source§fn is_exact_type_of_bound(object: &Bound<'_, PyAny>) -> bool
fn is_exact_type_of_bound(object: &Bound<'_, PyAny>) -> bool
PyTypeInfo::is_exact_type_of
PyTypeInfo::is_exact_type_of
.impl DerefToPyAny for Client
Auto Trait Implementations§
impl Freeze for Client
impl !RefUnwindSafe for Client
impl Send for Client
impl Sync for Client
impl Unpin for Client
impl !UnwindSafe for Client
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§impl<'py, T> IntoPyObjectExt<'py> for Twhere
T: IntoPyObject<'py>,
impl<'py, T> IntoPyObjectExt<'py> for Twhere
T: IntoPyObject<'py>,
Source§fn into_bound_py_any(self, py: Python<'py>) -> Result<Bound<'py, PyAny>, PyErr>
fn into_bound_py_any(self, py: Python<'py>) -> Result<Bound<'py, PyAny>, PyErr>
self
into an owned Python object, dropping type information.