register api command with metaclass, add deprecated and flags decorators

This commit is contained in:
Jack Robison 2017-05-28 15:59:17 -04:00
parent 17b692d258
commit 0b4c4cf6ca
2 changed files with 95 additions and 18 deletions

View file

@ -990,6 +990,7 @@ class Daemon(AuthJSONRPCServer):
############################################################################
@defer.inlineCallbacks
@AuthJSONRPCServer.flags(session_status="-s", dht_status="-d")
def jsonrpc_status(self, session_status=False, dht_status=False):
"""
Return daemon status
@ -1042,6 +1043,7 @@ class Daemon(AuthJSONRPCServer):
response['dht_status'] = self.session.dht_node.get_bandwidth_stats()
defer.returnValue(response)
@AuthJSONRPCServer.deprecated('status')
def jsonrpc_get_best_blockhash(self):
"""
DEPRECATED. Use `status blockchain_status=True` instead
@ -1051,6 +1053,7 @@ class Daemon(AuthJSONRPCServer):
x['blockchain_status']['best_blockhash']))
return d
@AuthJSONRPCServer.deprecated('status')
def jsonrpc_is_running(self):
"""
DEPRECATED. Use `status` instead
@ -1059,6 +1062,7 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda x: self._render_response(x['is_running']))
return d
@AuthJSONRPCServer.deprecated('status')
def jsonrpc_daemon_status(self):
"""
DEPRECATED. Use `status` instead
@ -1094,6 +1098,7 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda x: self._render_response(x)) # is this necessary?
return d
@AuthJSONRPCServer.deprecated('status')
def jsonrpc_is_first_run(self):
"""
DEPRECATED. Use `status` instead
@ -1102,6 +1107,7 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda x: self._render_response(x['is_first_run']))
return d
@AuthJSONRPCServer.deprecated('status')
def jsonrpc_get_lbry_session_info(self):
"""
DEPRECATED. Use `status` instead
@ -1115,6 +1121,7 @@ class Daemon(AuthJSONRPCServer):
}))
return d
@AuthJSONRPCServer.deprecated('status')
def jsonrpc_get_time_behind_blockchain(self):
"""
DEPRECATED. Use `status` instead
@ -1168,6 +1175,7 @@ class Daemon(AuthJSONRPCServer):
)
return self._render_response(True)
@AuthJSONRPCServer.deprecated('settings_get')
def jsonrpc_get_settings(self):
"""
DEPRECATED. Use `settings_get` instead.
@ -1184,6 +1192,7 @@ class Daemon(AuthJSONRPCServer):
"""
return self._render_response(conf.settings.get_adjustable_settings_dict())
@AuthJSONRPCServer.deprecated('settings_set')
@AuthJSONRPCServer.auth_required
def jsonrpc_set_settings(self, **kwargs):
"""
@ -1256,12 +1265,14 @@ class Daemon(AuthJSONRPCServer):
if 'DEPRECATED' not in getattr(self, "jsonrpc_" + command).__doc__]
))
@AuthJSONRPCServer.deprecated('wallet_balance')
def jsonrpc_get_balance(self, address=None, include_unconfirmed=False):
"""
DEPRECATED. Use `wallet_balance` instead.
"""
return self.jsonrpc_wallet_balance(address, include_unconfirmed)
@AuthJSONRPCServer.flags(include_unconfirmed='-u')
def jsonrpc_wallet_balance(self, address=None, include_unconfirmed=False):
"""
Return the balance of the wallet
@ -1280,6 +1291,7 @@ class Daemon(AuthJSONRPCServer):
return self._render_response(float(
self.session.wallet.get_address_balance(address, include_unconfirmed)))
@AuthJSONRPCServer.deprecated('daemon_stop')
def jsonrpc_stop(self):
"""
DEPRECATED. Use `daemon_stop` instead.
@ -1301,6 +1313,7 @@ class Daemon(AuthJSONRPCServer):
defer.returnValue(response)
@defer.inlineCallbacks
@AuthJSONRPCServer.flags(full_status='-f')
def jsonrpc_file_list(self, **kwargs):
"""
List files limited by optional filters
@ -1348,6 +1361,7 @@ class Daemon(AuthJSONRPCServer):
defer.returnValue(response)
@defer.inlineCallbacks
@AuthJSONRPCServer.flags(force='-f')
def jsonrpc_resolve_name(self, name, force=False):
"""
Resolve stream info from a LBRY name
@ -1367,6 +1381,7 @@ class Daemon(AuthJSONRPCServer):
else:
defer.returnValue(metadata)
@AuthJSONRPCServer.deprecated('claim_show')
def jsonrpc_get_claim_info(self, **kwargs):
"""
DEPRECATED. Use `claim_show` instead.
@ -1414,6 +1429,7 @@ class Daemon(AuthJSONRPCServer):
@AuthJSONRPCServer.auth_required
@defer.inlineCallbacks
@AuthJSONRPCServer.flags(force='-f')
def jsonrpc_resolve(self, uri, force=False):
"""
Resolve a LBRY URI
@ -1568,6 +1584,7 @@ class Daemon(AuthJSONRPCServer):
response = yield self._render_response(result)
defer.returnValue(response)
@AuthJSONRPCServer.deprecated('file_set_status')
@AuthJSONRPCServer.auth_required
def jsonrpc_stop_lbry_file(self, **kwargs):
"""
@ -1575,6 +1592,7 @@ class Daemon(AuthJSONRPCServer):
"""
return self.jsonrpc_file_set_status(status='stop', **kwargs)
@AuthJSONRPCServer.deprecated('file_set_status')
@AuthJSONRPCServer.auth_required
def jsonrpc_start_lbry_file(self, **kwargs):
"""
@ -1618,6 +1636,7 @@ class Daemon(AuthJSONRPCServer):
@AuthJSONRPCServer.auth_required
@defer.inlineCallbacks
@AuthJSONRPCServer.flags(delete_target_file='-f', delete_all='-a')
def jsonrpc_file_delete(self, delete_target_file=True, delete_all=False, **kwargs):
"""
Delete a lbry file
@ -1663,6 +1682,7 @@ class Daemon(AuthJSONRPCServer):
response = yield self._render_response(result)
defer.returnValue(response)
@AuthJSONRPCServer.deprecated('stream_cost_estimate')
def jsonrpc_get_est_cost(self, **kwargs):
"""
DEPRECATED. Use `stream_cost_estimate` instead
@ -1883,6 +1903,7 @@ class Daemon(AuthJSONRPCServer):
response = yield self._render_response(result)
defer.returnValue(response)
@AuthJSONRPCServer.deprecated('claim_abandon')
@AuthJSONRPCServer.auth_required
def jsonrpc_abandon_claim(self, **kwargs):
"""
@ -1919,6 +1940,7 @@ class Daemon(AuthJSONRPCServer):
response = yield self._render_response(err)
defer.returnValue(response)
@AuthJSONRPCServer.deprecated('claim_abandon')
@AuthJSONRPCServer.auth_required
def jsonrpc_abandon_name(self, **kwargs):
"""
@ -1926,6 +1948,7 @@ class Daemon(AuthJSONRPCServer):
"""
return self.jsonrpc_claim_abandon(**kwargs)
@AuthJSONRPCServer.deprecated('claim_support_new')
@AuthJSONRPCServer.auth_required
def jsonrpc_support_claim(self, **kwargs):
"""
@ -1957,6 +1980,7 @@ class Daemon(AuthJSONRPCServer):
defer.returnValue(result)
# TODO: merge this into claim_list
@AuthJSONRPCServer.deprecated('claim_list_mine')
@AuthJSONRPCServer.auth_required
def jsonrpc_get_my_claim(self, name):
"""
@ -1974,6 +1998,7 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda r: self._render_response(r))
return d
@AuthJSONRPCServer.deprecated('claim_list_mine')
@AuthJSONRPCServer.auth_required
def jsonrpc_get_name_claims(self):
"""
@ -2016,12 +2041,14 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda claims: self._render_response(claims))
return d
@AuthJSONRPCServer.deprecated('claim_list')
def jsonrpc_get_claims_for_name(self, **kwargs):
"""
DEPRECATED. Use `claim_list` instead.
"""
return self.jsonrpc_claim_list(**kwargs)
@AuthJSONRPCServer.deprecated('claim_list')
def jsonrpc_get_claims_for_tx(self, **kwargs):
"""
DEPRECATED. Use `claim_list` instead.
@ -2060,6 +2087,7 @@ class Daemon(AuthJSONRPCServer):
claims = yield self.session.wallet.get_claims_for_name(name)
defer.returnValue(claims)
@AuthJSONRPCServer.deprecated('transaction_list')
@AuthJSONRPCServer.auth_required
def jsonrpc_get_transaction_history(self):
"""
@ -2082,6 +2110,7 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda r: self._render_response(r))
return d
@AuthJSONRPCServer.deprecated('transaction_show')
def jsonrpc_get_transaction(self, txid):
"""
DEPRECATED. Use `transaction_show` instead
@ -2102,6 +2131,7 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda r: self._render_response(r))
return d
@AuthJSONRPCServer.deprecated('wallet_is_address_mine')
@AuthJSONRPCServer.auth_required
def jsonrpc_address_is_mine(self, address):
"""
@ -2124,6 +2154,7 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda is_mine: self._render_response(is_mine))
return d
@AuthJSONRPCServer.deprecated('wallet_public_key')
@AuthJSONRPCServer.auth_required
def jsonrpc_get_public_key_from_wallet(self, wallet):
"""
@ -2163,6 +2194,7 @@ class Daemon(AuthJSONRPCServer):
response = yield self._render_response(addresses)
defer.returnValue(response)
@AuthJSONRPCServer.deprecated('wallet_new_address')
@AuthJSONRPCServer.auth_required
def jsonrpc_get_new_address(self):
"""
@ -2231,6 +2263,7 @@ class Daemon(AuthJSONRPCServer):
self.analytics_manager.send_credits_sent()
defer.returnValue(True)
@AuthJSONRPCServer.deprecated('block_show')
def jsonrpc_get_block(self, **kwargs):
"""
DEPRECATED. Use `block_show` instead
@ -2259,6 +2292,7 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda r: self._render_response(r))
return d
@AuthJSONRPCServer.deprecated('descriptor_get')
@AuthJSONRPCServer.auth_required
def jsonrpc_download_descriptor(self, **kwargs):
"""
@ -2266,6 +2300,7 @@ class Daemon(AuthJSONRPCServer):
"""
return self.jsonrpc_descriptor_get(**kwargs)
@AuthJSONRPCServer.deprecated('blob_get')
@AuthJSONRPCServer.auth_required
def jsonrpc_descriptor_get(self, sd_hash, timeout=None, payment_rate_manager=None):
"""
@ -2345,6 +2380,7 @@ class Daemon(AuthJSONRPCServer):
response = yield self._render_response("Deleted %s" % blob_hash)
defer.returnValue(response)
@AuthJSONRPCServer.deprecated('peer_list')
def jsonrpc_get_peers_for_hash(self, blob_hash):
"""
DEPRECATED. Use `peer_list` instead
@ -2369,6 +2405,7 @@ class Daemon(AuthJSONRPCServer):
d.addCallback(lambda r: self._render_response(r))
return d
@AuthJSONRPCServer.deprecated('blob_announce_all')
def jsonrpc_announce_all_blobs_to_dht(self):
"""
DEPRECATED. Use `blob_announce_all` instead.
@ -2406,6 +2443,7 @@ class Daemon(AuthJSONRPCServer):
yield reupload.reflect_stream(lbry_file)
defer.returnValue("Reflect success")
@AuthJSONRPCServer.deprecated('blob_list')
def jsonrpc_get_blob_hashes(self):
"""
DEPRECATED. Use `blob_list` instead
@ -2461,6 +2499,7 @@ class Daemon(AuthJSONRPCServer):
response = yield self._render_response(blob_hashes_for_return)
defer.returnValue(response)
@AuthJSONRPCServer.deprecated('blob_reflect_all')
def jsonrpc_reflect_all_blobs(self):
"""
DEPRECATED. Use `blob_reflect_all` instead
@ -2554,6 +2593,7 @@ class Daemon(AuthJSONRPCServer):
response = yield self._render_response(mean_availability)
defer.returnValue(response)
@AuthJSONRPCServer.deprecated('status')
def jsonrpc_get_start_notice(self):
"""
DEPRECATED.

View file

@ -110,21 +110,30 @@ def jsonrpc_dumps_pretty(obj, **kwargs):
separators=(',', ': '), **kwargs) + "\n"
class AuthorizedBase(object):
def __init__(self):
self.authorized_functions = []
self.callable_methods = {}
self._call_lock = {}
self._queued_methods = []
class JSONRPCServerType(type):
def __new__(mcs, name, bases, newattrs):
klass = type.__new__(mcs, name, bases, newattrs)
klass.callable_methods = {}
klass.deprecated_methods = {}
klass.authorized_functions = []
klass.queued_methods = []
for methodname in dir(self):
for methodname in dir(klass):
if methodname.startswith("jsonrpc_"):
method = getattr(self, methodname)
self.callable_methods.update({methodname.split("jsonrpc_")[1]: method})
if hasattr(method, '_auth_required'):
self.authorized_functions.append(methodname.split("jsonrpc_")[1])
if hasattr(method, '_queued'):
self._queued_methods.append(methodname.split("jsonrpc_")[1])
method = getattr(klass, methodname)
if not hasattr(method, '_deprecated'):
klass.callable_methods.update({methodname.split("jsonrpc_")[1]: method})
if hasattr(method, '_auth_required'):
klass.authorized_functions.append(methodname.split("jsonrpc_")[1])
if hasattr(method, '_queued'):
klass.queued_methods.append(methodname.split("jsonrpc_")[1])
else:
klass.deprecated_methods.update({methodname.split("jsonrpc_")[1]: method})
return klass
class AuthorizedBase(object):
__metaclass__ = JSONRPCServerType
@staticmethod
def auth_required(f):
@ -136,6 +145,23 @@ class AuthorizedBase(object):
f._queued = True
return f
@staticmethod
def deprecated(new_command=None):
def _deprecated_wrapper(f):
f._new_command = new_command
f._deprecated = True
return f
return _deprecated_wrapper
@staticmethod
def flags(**kwargs):
def _flag_wrapper(f):
f._flags = {}
for k, v in kwargs.iteritems():
f._flags[v] = k
return f
return _flag_wrapper
class AuthJSONRPCServer(AuthorizedBase):
"""Authorized JSONRPC server used as the base class for the LBRY API
@ -164,7 +190,7 @@ class AuthJSONRPCServer(AuthorizedBase):
isLeaf = True
def __init__(self, use_authentication=None):
AuthorizedBase.__init__(self)
self._call_lock = {}
self._use_authentication = (
use_authentication if use_authentication is not None else conf.settings['use_auth_http']
)
@ -263,7 +289,7 @@ class AuthJSONRPCServer(AuthorizedBase):
id_ = None
try:
function_name = parsed.get('method')
is_queued = function_name in self._queued_methods
is_queued = function_name in self.queued_methods
args = parsed.get('params', {})
id_ = parsed.get('id', None)
token = parsed.pop('hmac', None)
@ -337,7 +363,7 @@ class AuthJSONRPCServer(AuthorizedBase):
if is_queued:
d_lock = self._call_lock.get(function_name, False)
if not d_lock:
d = defer.maybeDeferred(function, **args_dict)
d = defer.maybeDeferred(function, self, **args_dict)
self._call_lock[function_name] = finished_deferred
def _del_lock(*args):
@ -352,9 +378,9 @@ class AuthJSONRPCServer(AuthorizedBase):
log.info("queued %s", function_name)
d = d_lock
d.addBoth(lambda _: log.info("running %s from queue", function_name))
d.addCallback(lambda _: defer.maybeDeferred(function, **args_dict))
d.addCallback(lambda _: defer.maybeDeferred(function, self, **args_dict))
else:
d = defer.maybeDeferred(function, **args_dict)
d = defer.maybeDeferred(function, self, **args_dict)
# finished_deferred will callback when the request is finished
# and errback if something went wrong. If the errback is
@ -454,6 +480,16 @@ class AuthJSONRPCServer(AuthorizedBase):
else:
return server_port[0], 80
def _check_deprecated(self, function_path):
if function_path in self.deprecated_methods:
deprecated_fn = self.deprecated_methods[function_path]
deprecated_function_path = function_path
new_function_path = deprecated_fn._new_command
log.warning("\"%s\" is deprecated, please update to use \"%s\"",
deprecated_function_path, new_function_path)
return new_function_path
return function_path
def _verify_method_is_callable(self, function_path):
if function_path not in self.callable_methods:
raise UnknownAPIMethodError(function_path)
@ -462,6 +498,7 @@ class AuthJSONRPCServer(AuthorizedBase):
raise NotAllowedDuringStartupError(function_path)
def _get_jsonrpc_method(self, function_path):
function_path = self._check_deprecated(function_path)
self._verify_method_is_callable(function_path)
return self.callable_methods.get(function_path)