""" RPC wrapper around requests library """ import json import requests from .exceptions import RequestsError, RequestsTimeoutError, RPCError from ..constants import DEFAULT_ENDPOINT, DEFAULT_TIMEOUT def base_request( method, params = None, endpoint = DEFAULT_ENDPOINT, timeout = DEFAULT_TIMEOUT ) -> str: """Basic RPC request. Parameters --------- method: str RPC Method to call params: :obj:`list`, optional Parameters for the RPC method endpoint: :obj:`str`, optional Endpoint to send request to timeout: :obj:`int`, optional Timeout in seconds Returns ------- str Raw output from the request Raises ------ TypeError If params is not a list or None RequestsTimeoutError If request timed out RequestsError If other request error occured """ if params is None: params = [] elif not isinstance( params, list ): raise TypeError( f"invalid type {params.__class__}" ) try: payload = { "id": "1", "jsonrpc": "2.0", "method": method, "params": params } headers = { "Content-Type": "application/json" } resp = requests.request( "POST", endpoint, headers = headers, data = json.dumps( payload ), timeout = timeout, allow_redirects = True, ) return resp.content except requests.exceptions.Timeout as err: raise RequestsTimeoutError( endpoint ) from err except requests.exceptions.RequestException as err: raise RequestsError( endpoint ) from err def rpc_request( method, params = None, endpoint = DEFAULT_ENDPOINT, timeout = DEFAULT_TIMEOUT ) -> dict: """RPC request. Parameters --------- method: str RPC Method to call params: :obj:`list`, optional Parameters for the RPC method endpoint: :obj:`str`, optional Endpoint to send request to timeout: :obj:`int`, optional Timeout in seconds Returns ------- dict Returns dictionary representation of RPC response Example format: { "jsonrpc": "2.0", "id": 1, "result": ... } Raises ------ RPCError If RPC response returned a blockchain error See Also -------- base_request """ raw_resp = base_request( method, params, endpoint, timeout ) try: resp = json.loads( raw_resp ) if "error" in resp: raise RPCError( method, endpoint, str( resp[ "error" ] ) ) return resp except json.decoder.JSONDecodeError as err: raise RPCError( method, endpoint, raw_resp ) from err