Skip to content

Commit

Permalink
feat!: introduce HxClient
Browse files Browse the repository at this point in the history
  • Loading branch information
rick-jennings committed Sep 9, 2024
1 parent f6ce9a3 commit b27c20b
Show file tree
Hide file tree
Showing 6 changed files with 603 additions and 313 deletions.
3 changes: 3 additions & 0 deletions docs/hx_client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# `HxClient` class

::: phable.hx_client.HxClient
2 changes: 1 addition & 1 deletion phable/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

from phable.client import (
Client,
CommitFlag,
HaystackErrorGridResponseError,
HaystackHisWriteOpParametersError,
HaystackReadOpUnknownRecError,
)
from phable.hx_client import HxClient
from phable.kinds import (
NA,
Coord,
Expand Down
110 changes: 2 additions & 108 deletions phable/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,12 @@

from phable.auth.scram import ScramScheme
from phable.http import post
from phable.kinds import DateRange, DateTimeRange, Grid, Marker, Number, Ref
from phable.kinds import DateRange, DateTimeRange, Grid, Number, Ref
from phable.parsers.grid import merge_pt_data_to_his_grid_cols

if TYPE_CHECKING:
from ssl import SSLContext
from datetime import datetime

from enum import StrEnum, auto

# -----------------------------------------------------------------------------
# Module exceptions
# -----------------------------------------------------------------------------
from ssl import SSLContext


@dataclass
Expand Down Expand Up @@ -45,22 +39,6 @@ class HaystackIncompleteDataResponseError(Exception):
help_msg: str


# -----------------------------------------------------------------------------
# Enums for string inputs
# -----------------------------------------------------------------------------


class CommitFlag(StrEnum):
ADD = auto()
UPDATE = auto()
REMOVE = auto()


# -----------------------------------------------------------------------------
# Client core interface
# -----------------------------------------------------------------------------


class Client:
"""A client interface to a Project Haystack defined server application used for
authentication and operations.
Expand Down Expand Up @@ -504,90 +482,6 @@ def point_write_array(self, id: Ref) -> Grid:

return self._call("pointWrite", Grid.to_grid({"id": id}))

# -------------------------------------------------------------------------
# Haxall ops
# -------------------------------------------------------------------------

def eval(self, expr: str) -> Grid:
"""Evaluates an Axon string expression.
**Errors**
After the request `Grid` is successfully read by the server, the server
may respond with a `Grid` that triggers one of the following errors to be
raised:
1. `HaystackErrorGridResponseError` if the operation fails
2. `HaystackIncompleteDataResponseError` if incomplete data is being returned
**Additional info**
See Haxall's Eval operation docs for more details
[here](https://haxall.io/doc/lib-hx/op~eval).
Parameters:
expr: Axon string expression.
Returns:
`Grid` with the server's response.
"""

return self._call("eval", Grid.to_grid({"expr": expr}))

def commit(
self,
data: list[dict[str, Any]],
flag: CommitFlag,
read_return: bool = False,
) -> Grid:
"""Commits one or more diffs to Haxall's Folio database.
Commit access requires the API user to have admin permission.
**Errors**
After the request `Grid` is successfully read by the server, the server
may respond with a `Grid` that triggers one of the following errors to be
raised:
1. `HaystackErrorGridResponseError` if the operation fails
2. `HaystackIncompleteDataResponseError` if incomplete data is being returned
**Additional info**
See Haxall's Commit operation docs for more details
[here](https://haxall.io/doc/lib-hx/op~commit).
Parameters:
data: Changes to be commited to Haxall's Folio database.
flag:
`add`, `update`, and `remove` options are selected using `CommitFlag`.
`add` adds new records into the database and returns a grid with the
newly minted record identifiers. As a general rule you should not have
an `id` column in your commit grid. However if you wish to predefine
the id of the records, you can specify an `id` column in the commit
grid. `update` modifies existing records, the records must have both
an `id` and `mod` column. `remove` removes existing records, the
records should have only an `id` and `mod` column.
read_return:
If true the response contains the full tag definitions of the
new/updated records.
Returns:
`Grid` with the server's response.
"""

meta = {"commit": str(flag)}

if read_return:
meta = meta | {"readReturn": Marker()}

return self._call("commit", Grid.to_grid(data, meta))

# -------------------------------------------------------------------------
# base to Haystack and SkySpark ops
# -------------------------------------------------------------------------

def _call(
self,
op: str,
Expand Down
140 changes: 140 additions & 0 deletions phable/hx_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
from typing import Any

from phable.client import Client
from phable.kinds import Grid


class HxClient(Client):
"""A superset of `Client` with support for Haxall specific operations.
Learn more about Haxall [here](https://haxall.io/).
"""

def commit_add(self, recs: dict[str, Any] | list[dict[str, Any]] | Grid) -> Grid:
"""Adds one or more new records to the database.
As a general rule you should not have an `id` column in your commit grid.
However if you wish to predefine the id of the records, you can specify an `id`
column in the commit grid.
Commit access requires the API user to have admin permission.
**Errors**
After the request `Grid` is successfully read by the server, the server
may respond with a `Grid` that triggers one of the following errors to be
raised:
1. `HaystackErrorGridResponseError` if the operation fails
2. `HaystackIncompleteDataResponseError` if incomplete data is being returned
**Additional info**
See Haxall's Commit operation docs for more details
[here](https://haxall.io/doc/lib-hx/op~commit).
Parameters:
recs: Records to be added to the database.
Returns:
The full tag definitions for each of the newly added records.
"""
meta = {"commit": "add"}
if isinstance(recs, Grid):
recs = recs.rows
return self._call("commit", Grid.to_grid(recs, meta))

def commit_remove(self, recs: dict[str, Any] | list[dict[str, Any]] | Grid) -> Grid:
"""Removes one or more records from the database.
Commit access requires the API user to have admin permission.
**Errors**
A `HaystackErrorGridResponseError` is raised if any of the recs do not exist on
the server.
Also, after the request `Grid` is successfully read by the server, the server
may respond with a `Grid` that triggers one of the following errors to be
raised:
1. `HaystackErrorGridResponseError` if the operation fails
2. `HaystackIncompleteDataResponseError` if incomplete data is being returned
**Additional info**
See Haxall's Commit operation docs for more details
[here](https://haxall.io/doc/lib-hx/op~commit).
Parameters:
recs:
Records to be removed from the database. Each record (or row) must at
minimum define `id` and `mod` columns.
Returns:
An empty `Grid`.
"""
meta = {"commit": "remove"}
if isinstance(recs, Grid):
recs = recs.rows
return self._call("commit", Grid.to_grid(recs, meta))

def commit_update(self, recs: dict[str, Any] | list[dict[str, Any]] | Grid) -> Grid:
"""Updates one or more existing records within the database.
Commit access requires the API user to have admin permission.
**Errors**
After the request `Grid` is successfully read by the server, the server
may respond with a `Grid` that triggers one of the following errors to be
raised:
1. `HaystackErrorGridResponseError` if the operation fails
2. `HaystackIncompleteDataResponseError` if incomplete data is being returned
**Additional info**
See Haxall's Commit operation docs for more details
[here](https://haxall.io/doc/lib-hx/op~commit).
Parameters:
recs:
Existing records within the database to be updated. Each record (or
row) must at minimum have tags for the rec's existing `id` and `mod`
columns (defined by the server) and the columns being updated (defined
by the client).
Returns:
The latest full tag definitions for each of the updated records.
"""
meta = {"commit": "update"}
if isinstance(recs, Grid):
recs = recs.rows
return self._call("commit", Grid.to_grid(recs, meta))

def eval(self, expr: str) -> Grid:
"""Evaluates an Axon string expression.
**Errors**
After the request `Grid` is successfully read by the server, the server
may respond with a `Grid` that triggers one of the following errors to be
raised:
1. `HaystackErrorGridResponseError` if the operation fails
2. `HaystackIncompleteDataResponseError` if incomplete data is being returned
**Additional info**
See Haxall's Eval operation docs for more details
[here](https://haxall.io/doc/lib-hx/op~eval).
Parameters:
expr: Axon string expression.
Returns:
`Grid` with the server's response.
"""

return self._call("eval", Grid.to_grid({"expr": expr}))
Loading

0 comments on commit b27c20b

Please sign in to comment.