Пример #1
0
    def grpc_table_op(self, table: Table, op: TableOp):
        try:
            result_id = self.session.make_ticket()
            if table:
                table_reference = table_pb2.TableReference(ticket=table.ticket)
            else:
                table_reference = None
            stub_func = op.__class__.get_stub_func(self._grpc_table_stub)
            response = stub_func(op.make_grpc_request(
                result_id=result_id, source_id=table_reference),
                                 metadata=self.session.grpc_metadata)

            if response.success:
                return Table(self.session,
                             ticket=response.result_id.ticket,
                             schema_header=response.schema_header,
                             size=response.size,
                             is_static=response.is_static)
            else:
                raise DHError(
                    f"Server error received for {op.__class__.__name__}: {response.error_info}"
                )
        except Exception as e:
            raise DHError(
                f"failed to finish {op.__class__.__name__} operation") from e
    def import_table(self, data: pyarrow.Table):
        try:
            options = paflight.FlightCallOptions(
                headers=self.session.grpc_metadata)
            if not isinstance(data, (pa.Table, pa.RecordBatch)):
                raise DHError(
                    "source data must be either a pa table or RecordBatch.")
            ticket = self.session.get_ticket()
            dh_fields = []
            for f in data.schema:
                dh_fields.append(
                    pa.field(name=f.name,
                             type=f.type,
                             metadata=_map_arrow_type(f.type)))
            dh_schema = pa.schema(dh_fields)

            writer, reader = self._flight_client.do_put(
                pa.flight.FlightDescriptor.for_path("export", str(ticket)),
                dh_schema,
                options=options)
            writer.write_table(data)
            writer.close()
            _ = reader.read()
            flight_ticket = self.session.make_ticket(ticket)
            return Table(self.session,
                         ticket=flight_ticket,
                         size=data.num_rows,
                         schema=dh_schema)
        except Exception as e:
            raise DHError(
                "failed to create a Deephaven table from Arrow data.") from e
Пример #3
0
 def bind_table(self, table, variable_name):
     if not table or not variable_name:
         raise DHError("invalid table and/or variable_name values.")
     try:
         response = self._grpc_console_stub.BindTableToVariable(
             console_pb2.BindTableToVariableRequest(console_id=self.console_id,
                                                    table_id=table.ticket,
                                                    variable_name=variable_name),
             metadata=self.session.grpc_metadata)
     except Exception as e:
         raise DHError("failed to bind a table to a variable on the server.") from e
Пример #4
0
 def close(self):
     try:
         self._grpc_session_stub.CloseSession(
             session_pb2.HandshakeRequest(auth_protocol=0, payload=self.session.session_token),
             metadata=self.session.grpc_metadata)
     except Exception as e:
         raise DHError("failed to close the session.") from e
Пример #5
0
    def sync_fields(self, repeating: bool):
        """ Check for fields that have been added/deleted by other sessions and add them to the local list

        This will start a new background thread when `repeating=True`.
        
        Args:
            repeating (bool): Continue to check in the background for new/updated tables
        
        Raises:
            DHError
        """
        with self._r_lock:
            if self._list_fields is not None:
                return

            self._list_fields = self.app_service.list_fields()
            self._parse_fields_change(next(self._list_fields))
            if repeating:
                self._field_update_thread = threading.Thread(target=self._update_fields)
                self._field_update_thread.daemon = True
                self._field_update_thread.start()
            else:
                if not self._list_fields.cancel():
                    raise DHError("could not cancel ListFields subscription")
                self._list_fields = None
Пример #6
0
    def get_ticket(self):
        with self._r_lock:
            self._last_ticket += 1
            if self._last_ticket == 2**31 - 1:
                raise DHError("fatal error: out of free internal ticket")

            return self._last_ticket
Пример #7
0
 def refresh_token(self):
     try:
         response = self._grpc_session_stub.RefreshSessionToken(
             session_pb2.HandshakeRequest(auth_protocol=0, payload=self.session.session_token),
             metadata=self.session.grpc_metadata)
         return response.session_token, response.token_expiration_delay_millis
     except Exception as e:
         raise DHError("failed to refresh session token.") from e
Пример #8
0
 def list_fields(self):
     try:
         fields = self._grpc_app_stub.ListFields(
             application_pb2.ListFieldsRequest(),
             metadata=self.session.grpc_metadata)
         return fields
     except Exception as e:
         raise DHError("failed to list fields.") from e
 def snapshot_table(self, table: Table):
     try:
         options = paflight.FlightCallOptions(
             headers=self.session.grpc_metadata)
         flight_ticket = paflight.Ticket(table.ticket.ticket)
         reader = self._flight_client.do_get(flight_ticket, options=options)
         return reader.read_all()
     except Exception as e:
         raise DHError("failed to take a snapshot of the table.") from e
Пример #10
0
 def __init__(self, session=None, ticket=None, schema_header=b'', size=None, is_static=None, schema=None):
     if not session or not session.is_alive:
         raise DHError("Must be associated with a active session")
     self.session = session
     self.ticket = ticket
     self.schema = schema
     self.is_static = is_static
     self.size = size
     if not schema:
         self._parse_schema(schema_header)
Пример #11
0
    def connect(self):
        grpc_channel = grpc.insecure_channel(":".join([self.session.host, str(self.session.port)]))
        self._grpc_session_stub = session_pb2_grpc.SessionServiceStub(grpc_channel)

        try:
            response = self._grpc_session_stub.NewSession(
                session_pb2.HandshakeRequest(auth_protocol=1, payload=b'hello pydeephaven'))
            return grpc_channel, response.session_token, response.token_expiration_delay_millis
        except Exception as e:
            grpc_channel.close()
            raise DHError("failed to connect to the server.") from e
Пример #12
0
    def batch(self, ops):
        batch_op = BatchOpAssembler(self.session, table_ops=ops).build_batch()

        try:
            response = self._grpc_table_stub.Batch(
                table_pb2.BatchTableRequest(ops=batch_op),
                metadata=self.session.grpc_metadata)

            exported_tables = []
            for exported in response:
                if not exported.success:
                    raise DHError(exported.error_info)
                if exported.result_id.WhichOneof("ref") == "ticket":
                    exported_tables.append(Table(self.session, ticket=exported.result_id.ticket,
                                                 schema_header=exported.schema_header,
                                                 size=exported.size,
                                                 is_static=exported.is_static))
            return exported_tables[-1]
        except Exception as e:
            raise DHError("failed to finish the table batch operation.") from e
Пример #13
0
    def open_table(self, name):
        self.start_console()

        try:
            result_id = self.session.make_ticket()
            response = self._grpc_console_stub.FetchTable(
                console_pb2.FetchTableRequest(console_id=self.console_id,
                                              table_id=result_id,
                                              table_name=name),
                metadata=self.session.grpc_metadata)

            if response.success:
                return Table(self.session, ticket=response.result_id.ticket,
                             schema_header=response.schema_header,
                             size=response.size,
                             is_static=response.is_static)
            else:
                raise DHError("error open a table: " + response.error_info)
        except Exception as e:
            raise DHError("failed to open a table.") from e
Пример #14
0
    def run_script(self, server_script):
        self.start_console()

        try:
            response = self._grpc_console_stub.ExecuteCommand(
                console_pb2.ExecuteCommandRequest(console_id=self.console_id,
                                                  code=server_script),
                metadata=self.session.grpc_metadata)
            return response
        except Exception as e:
            raise DHError("failed to execute a command in the console.") from e
Пример #15
0
    def start_console(self):
        if self.console_id:
            return

        try:
            result_id = self.session.make_ticket()
            response = self._grpc_console_stub.StartConsole(
                console_pb2.StartConsoleRequest(result_id=result_id, session_type='python'),
                metadata=self.session.grpc_metadata)
            self.console_id = response.result_id
        except Exception as e:
            raise DHError("failed to start a console.") from e
Пример #16
0
    def __init__(self, host: str = None, port: int = None, never_timeout: bool = True, session_type: str = 'python', sync_fields: int = NO_SYNC):
        """ Initialize a Session object that connects to the Deephaven server

        Args:
            host (str): the host name or IP address of the remote machine, default is 'localhost'
            port (int): the port number that Deephaven server is listening on, default is 10000
            never_timeout (bool, optional): never allow the session to timeout, default is True
            session_type (str, optional): the Deephaven session type. Defaults to 'python'
            sync_fields (int, optional): equivalent to calling `Session.sync_fields()` (see below), default is NO_SYNC
        
        Sync Options:
            session.NO_SYNC: does not check for existing tables on the server
            session.SYNC_ONCE: equivalent to `Session.sync_fields(repeating=False)`
            session.SYNC_REPEATED: equivalent to `Session.sync_fields(repeating=True)`

        Raises:
            DHError
        """
        self._r_lock = threading.RLock()
        self._last_ticket = 0
        self._ticket_bitarray = BitArray(1024)

        self.host = host
        if not host:
            self.host = os.environ.get("DH_HOST", "localhost")

        self.port = port
        if not port:
            self.port = int(os.environ.get("DH_PORT", 10000))

        if sync_fields not in (NO_SYNC, SYNC_ONCE, SYNC_REPEATED):
            raise DHError("invalid sync_fields setting")

        self.is_connected = False
        self.session_token = None
        self.grpc_channel = None
        self._session_service = None
        self._table_service = None
        self._grpc_barrage_stub = None
        self._console_service = None
        self._flight_service = None
        self._app_service = None
        self._never_timeout = never_timeout
        self._keep_alive_timer = None
        self._session_type = session_type
        self._sync_fields = sync_fields
        self._list_fields = None
        self._field_update_thread = None
        self._fields = {}

        self._connect()
def _map_arrow_type(arrow_type):
    arrow_to_dh = {
        pa.null(): '',
        pa.bool_(): '',
        pa.int8(): 'byte',
        pa.int16(): 'short',
        pa.int32(): 'int',
        pa.int64(): 'long',
        pa.uint8(): '',
        pa.uint16(): 'char',
        pa.uint32(): '',
        pa.uint64(): '',
        pa.float16(): '',
        pa.float32(): 'float',
        pa.float64(): 'double',
        pa.time32('s'): '',
        pa.time32('ms'): '',
        pa.time64('us'): '',
        pa.time64('ns'): 'io.deephaven.time.DateTime',
        pa.timestamp('us', tz=None): '',
        pa.timestamp('ns', tz=None): '',
        pa.date32(): 'java.time.LocalDate',
        pa.date64(): 'java.time.LocalDate',
        pa.binary(): '',
        pa.string(): 'java.lang.String',
        pa.utf8(): 'java.lang.String',
        pa.large_binary(): '',
        pa.large_string(): '',
        pa.large_utf8(): '',
        # decimal128(int precision, int scale=0)
        # list_(value_type, int list_size=-1)
        # large_list(value_type)
        # map_(key_type, item_type[, keys_sorted])
        # struct(fields)
        # dictionary(index_type, value_type, …)
        # field(name, type, bool nullable = True[, metadata])
        # schema(fields[, metadata])
        # from_numpy_dtype(dtype)
    }

    dh_type = arrow_to_dh.get(arrow_type)
    if not dh_type:
        # if this is a case of timestamp with tz specified
        if isinstance(arrow_type, pa.TimestampType):
            dh_type = "io.deephaven.time.DateTime"

    if not dh_type:
        raise DHError(f'unsupported arrow data type : {arrow_type}')

    return {"deephaven:type": dh_type}
Пример #18
0
    def open_table(self, name: str) -> Table:
        """ Open a table in the global scope with the given name on the server.

        Args:
            name (str): the name of the table

        Returns:
            a Table object

        Raises:
            DHError
        """
        with self._r_lock:
            if name not in self.tables:
                raise DHError(f"no table by the name {name}")
            table_op = FetchTableOp()
            return self.table_service.grpc_table_op(self._fields[('scope', name)][1], table_op)
Пример #19
0
 def release(self, ticket):
     try:
         self._grpc_session_stub.Release(session_pb2.ReleaseRequest(id=ticket), metadata=self.session.grpc_metadata)
     except Exception as e:
         raise DHError("failed to release a ticket.") from e
Пример #20
0
 def __init__(self, session, table):
     self.session = session
     if not self.session or not table:
         raise DHError("invalid session or table value.")
     self._ops = [NoneOp(table=table)]