diff --git a/steem/steem.py b/steem/steem.py index ccdc867..ef14f95 100644 --- a/steem/steem.py +++ b/steem/steem.py @@ -1,6 +1,6 @@ from .commit import Commit from .steemd import Steemd - +from steembase.exceptions import RPCError class Steem: """ Connect to the Steem network. @@ -57,9 +57,37 @@ def __getattr__(self, item): return getattr(self.steemd, item) if hasattr(self.commit, item): return getattr(self.commit, item) + if item.endswith("_api"): + return Steem.Api(api_name=item, exec_method=self.steemd.exec) raise AttributeError('Steem has no attribute "%s"' % item) + class Api(object): + def __init__(self, api_name="", exec_method=None): + self.api_name = api_name + self.exec_method = exec_method + return + + def __getattr__(self, method_name): + return Steem.Method( + api_name=self.api_name, + method_name=method_name, + exec_method=self.exec_method, + ) + + class Method(object): + def __init__(self, api_name="", method_name="", exec_method=None): + self.api_name = api_name + self.method_name = method_name + self.exec_method = exec_method + return + + def __call__(self, *args, **kwargs): + if len(kwargs) > 0: + if len(args) > 0: + raise RPCError("Cannot specify both args and kwargs in RPC") + return self.exec_method(self.method_name, kwargs=kwargs, api=self.api_name) + return self.exec_method(self.method_name, *args, api=self.api_name) if __name__ == '__main__': s = Steem() diff --git a/steembase/http_client.py b/steembase/http_client.py index f140e98..ffb5709 100644 --- a/steembase/http_client.py +++ b/steembase/http_client.py @@ -106,7 +106,7 @@ def hostname(self): return urlparse(self.url).hostname @staticmethod - def json_rpc_body(name, *args, api=None, as_json=True, _id=0): + def json_rpc_body(name, *args, api=None, as_json=True, _id=0, kwargs=None): """ Build request body for steemd RPC requests. Args: @@ -123,7 +123,9 @@ def json_rpc_body(name, *args, api=None, as_json=True, _id=0): Otherwise, a Python dictionary is returned. """ headers = {"jsonrpc": "2.0", "id": _id} - if api: + if kwargs is not None: + body_dict = {**headers, "method": "call", "params": [api, name, kwargs]} + elif api: body_dict = {**headers, "method": "call", "params": [api, name, args]} else: body_dict = {**headers, "method": name, "params": args} @@ -132,7 +134,7 @@ def json_rpc_body(name, *args, api=None, as_json=True, _id=0): else: return body_dict - def exec(self, name, *args, api=None, return_with_args=None, _ret_cnt=0): + def exec(self, name, *args, api=None, return_with_args=None, _ret_cnt=0, kwargs=None): """ Execute a method against steemd RPC. Warnings: @@ -140,7 +142,7 @@ def exec(self, name, *args, api=None, return_with_args=None, _ret_cnt=0): node fail-over, unless we are broadcasting a transaction. In latter case, the exception is **re-raised**. """ - body = HttpClient.json_rpc_body(name, *args, api=api) + body = HttpClient.json_rpc_body(name, *args, api=api, kwargs=kwargs) response = None try: response = self.request(body=body)