Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Py310 support #71

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion pymarketstore/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
from .client import Client # noqa
from .params import Params, ListSymbolsFormat # noqa
from .jsonrpc_client import MsgpackRpcClient # noqa
from .grpc_client import GRPCClient # noqa
try:
from .grpc_client import GRPCClient # noqa
except TypeError:
import logging
log = logging.getLogger()
log.exception("Failed to import GRPC Client\n\n")

# alias
Param = Params # noqa
Expand Down
67 changes: 58 additions & 9 deletions pymarketstore/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@

import logging
import re
from typing import List, Dict, Union, Tuple
from typing import List, Dict, Union, Tuple, Any

import numpy as np

from .grpc_client import GRPCClient
from .jsonrpc_client import JsonRpcClient
from .params import Params, ListSymbolsFormat
from .results import QueryReply
Expand All @@ -23,9 +22,33 @@
http_regex = re.compile(r'^https?://(.+):\d+/rpc') # http:// or https://


class RequestError(Exception):
"Generic client error"


def err_on_resp(response: dict) -> None:
"""
Raise any errors found in responses from client request.
"""
responses = response['responses']
if responses is not None:
for r in responses:
err = r['error']
if err:
raise RequestError(err)


class Client:
def __init__(self, endpoint: str = 'http://localhost:5993/rpc', grpc: bool = False):
def __init__(
self,
endpoint: str = 'http://localhost:5993/rpc',
grpc: bool = False,
raise_errors: bool = False,

) -> None:
self._raise_errors = raise_errors
if grpc:
from .grpc_client import GRPCClient
match = re.findall(http_regex, endpoint)

# when endpoint is specified in "http://{host}:{port}/rpc" format,
Expand All @@ -43,21 +66,39 @@ def __init__(self, endpoint: str = 'http://localhost:5993/rpc', grpc: bool = Fal
self.endpoint = endpoint
self.client = JsonRpcClient(self.endpoint)

def _maybe_raise(
self,
result: Any,
) -> Any:
"""
If an error response is received back from the server, raise a
local ``RequestError`` with its contents.

"""
if not self._raise_errors:
return result
else:
return err_on_resp(result)

def query(self, params: Params) -> QueryReply:
"""
execute QUERY to MarketStore server
:param params: Params object used to query
:return: QueryReply object
"""
return self.client.query(params)
return self._maybe_raise(
self.client.query(params)
)

def sql(self, statements: Union[str, List[str]]) -> QueryReply:
"""
execute SQL to MarketStore server
:param statements: List of SQL statements in a string
:return: QueryReply object
"""
return self.client.sql(statements)
return self._maybe_raise(
self.client.sql(statements)
)

def _build_query(self, params: Union[Params, List[Params]]) -> Dict:
return self.client.build_query(params)
Expand All @@ -70,7 +111,9 @@ def create(self, tbk: str, dtype: List[Tuple[str, str]], isvariablelength: bool
:param isvariablelength: should be set true if the record content is variable-length array
:return: str
"""
return self.client.create(tbk=tbk, dtype=dtype, isvariablelength=isvariablelength)
return self._maybe_raise(
self.client.create(tbk=tbk, dtype=dtype, isvariablelength=isvariablelength)
)

def write(self, recarray: np.array, tbk: str, isvariablelength: bool = False) -> str:
"""
Expand All @@ -81,16 +124,22 @@ def write(self, recarray: np.array, tbk: str, isvariablelength: bool = False) ->
:param isvariablelength: should be set true if the record content is variable-length array
:return:
"""
return self.client.write(recarray, tbk, isvariablelength=isvariablelength)
return self._maybe_raise(
self.client.write(recarray, tbk, isvariablelength=isvariablelength)
)

def list_symbols(self, fmt: ListSymbolsFormat = ListSymbolsFormat.SYMBOL) -> List[str]:
return self.client.list_symbols(fmt)

def destroy(self, tbk: str) -> Dict:
return self.client.destroy(tbk)
return self._maybe_raise(
self.client.destroy(tbk)
)

def server_version(self) -> str:
return self.client.server_version()
return self._maybe_raise(
self.client.server_version()
)

def __repr__(self):
return self.client.__repr__()
11 changes: 8 additions & 3 deletions pymarketstore/results.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from typing import List, Dict
from __future__ import annotations
from typing import List, Dict, TYPE_CHECKING

import numpy as np
import pandas as pd
import six

import pymarketstore.proto.marketstore_pb2 as proto
if TYPE_CHECKING:
import pymarketstore.proto.marketstore_pb2 as proto


def decode(column_names: List[str], column_types: List[str], column_data, data_length) -> np.ndarray:
Expand Down Expand Up @@ -122,7 +124,10 @@ def from_response(cls, resp: Dict):
return cls([QueryResult(result, resp['timezone']) for result in results], resp['timezone'])

@classmethod
def from_grpc_response(cls, resp: proto.MultiQueryResponse): # ->QueryReply:
def from_grpc_response(
cls,
resp: proto.MultiQueryResponse
): # ->QueryReply:
results = decode_grpc_responses(resp.responses)
return cls([QueryResult(result, resp.timezone) for result in results], resp.timezone)

Expand Down