Skip to content
This repository has been archived by the owner on Nov 15, 2021. It is now read-only.

Commit

Permalink
Initial Django inspired component loading (#719)
Browse files Browse the repository at this point in the history
  • Loading branch information
ixje authored Nov 19, 2018
1 parent eb6cf86 commit 2a501a1
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 26 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ All notable changes to this project are documented in this file.
- Fix RPC's ``getaccountstate`` response schema to match ``neo-cli`` `#714 </~https://github.com/CityOfZion/neo-python/issues/714>`
- Add fix to ensure tx is saved to wallet when sent using RPC
- Add bad peers to the ``getpeers`` RPC method `#715 </~https://github.com/CityOfZion/neo-python/pull/715>`
- Introduce Django inspired component loading for REST and RPC server
- Allow a raw tx to be build without an active blockchain db in the environment
- Fix unnecessary default bootstrap warning for mainnet showing.

Expand Down
7 changes: 7 additions & 0 deletions neo/Settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ class SettingsHolder:

VERSION_NAME = "/NEO-PYTHON:%s/" % __version__

RPC_SERVER = None
REST_SERVER = None
DEFAULT_RPC_SERVER = 'neo.api.JSONRPC.JsonRpcApi.JsonRpcApi'
DEFAULT_REST_SERVER = 'neo.api.REST.RestApi.RestApi'

# Logging settings
log_level = None
log_smart_contract_events = False
Expand Down Expand Up @@ -211,6 +216,8 @@ def get_config_and_warn(key, default, abort=False):
self.NOTIFICATION_DB_PATH = config.get('NotificationDataPath', 'Chains/notification_data')
self.SERVICE_ENABLED = config.get('ServiceEnabled', False)
self.COMPILER_NEP_8 = config.get('CompilerNep8', False)
self.REST_SERVER = config.get('RestServer', self.DEFAULT_REST_SERVER)
self.RPC_SERVER = config.get('RPCServer', self.DEFAULT_RPC_SERVER)

def setup_mainnet(self):
""" Load settings from the mainnet JSON config file """
Expand Down
29 changes: 29 additions & 0 deletions neo/Utils/plugin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import importlib


def load_class_from_path(path_and_class: str):
"""
Dynamically load a class from a module at the specified path
Args:
path_and_class: relative path where to find the module and its class name
i.e. 'neo.<package>.<package>.<module>.<class name>'
Raises:
ValueError: if the Module or Class is not found.
Returns:
class object
"""
try:
module_path = '.'.join(path_and_class.split('.')[:-1])
module = importlib.import_module(module_path)
except ImportError as err:
raise ValueError(f"Failed to import module {module_path} with error: {err}")

try:
class_name = path_and_class.split('.')[-1]
class_obj = getattr(module, class_name)
return class_obj
except AttributeError as err:
raise ValueError(f"Failed to get class {class_name} with error: {err}")
40 changes: 18 additions & 22 deletions neo/bin/api_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"""
API server to run the JSON-RPC and REST API.
Uses neo.api.JSONRPC.JsonRpcApi or neo.api.JSONRPC.ExtendedJsonRpcApi and neo.api.REST.RestApi
Uses servers specified in protocol.xxx.json files
Print the help and all possible arguments:
Expand Down Expand Up @@ -33,6 +33,7 @@
* https://twistedmatrix.com/documents/17.9.0/api/twisted.logger.STDLibLogObserver.html
"""
import os
import sys
import argparse
import threading
from time import sleep
Expand All @@ -52,16 +53,14 @@
# neo methods and modules
from neo.Core.Blockchain import Blockchain
from neo.Implementations.Blockchains.LevelDB.LevelDBBlockchain import LevelDBBlockchain
from neo.api.JSONRPC.JsonRpcApi import JsonRpcApi
from neo.api.JSONRPC.ExtendedJsonRpcApi import ExtendedJsonRpcApi
from neo.Implementations.Notifications.LevelDB.NotificationDB import NotificationDB
from neo.api.REST.RestApi import RestApi
from neo.Wallets.utils import to_aes_key
from neo.Implementations.Wallets.peewee.UserWallet import UserWallet

from neo.Network.NodeLeader import NodeLeader
from neo.Settings import settings

from neo.Utils.plugin import load_class_from_path
import neo.Settings

# Logfile default settings (only used if --logfile arg is used)
LOGFILE_MAX_BYTES = 5e7 # 50 MB
Expand Down Expand Up @@ -128,9 +127,6 @@ def main():
# host
parser.add_argument("--host", action="store", type=str, help="Hostname ( for example 127.0.0.1)", default="0.0.0.0")

# extended json-rpc api
parser.add_argument("--extended-rpc", action="store_true", default=False, help="Use extended json-rpc api")

# Now parse
args = parser.parse_args()
# print(args)
Expand Down Expand Up @@ -249,28 +245,28 @@ def loopingCallErrorHandler(error):
d.setDaemon(True) # daemonizing the thread will kill it when the main thread is quit
d.start()

if args.port_rpc and args.extended_rpc:
logger.info("Starting extended json-rpc api server on http://%s:%s" % (args.host, args.port_rpc))
api_server_rpc = ExtendedJsonRpcApi(args.port_rpc, wallet=wallet)
endpoint_rpc = "tcp:port={0}:interface={1}".format(args.port_rpc, args.host)
endpoints.serverFromString(reactor, endpoint_rpc).listen(Site(api_server_rpc.app.resource()))
# reactor.listenTCP(int(args.port_rpc), server.Site(api_server_rpc))
# api_server_rpc.app.run(args.host, args.port_rpc)

elif args.port_rpc:
if args.port_rpc:
logger.info("Starting json-rpc api server on http://%s:%s" % (args.host, args.port_rpc))
api_server_rpc = JsonRpcApi(args.port_rpc, wallet=wallet)
try:
rpc_class = load_class_from_path(settings.RPC_SERVER)
except ValueError as err:
logger.error(err)
sys.exit()
api_server_rpc = rpc_class(args.port_rpc, wallet=wallet)

endpoint_rpc = "tcp:port={0}:interface={1}".format(args.port_rpc, args.host)
endpoints.serverFromString(reactor, endpoint_rpc).listen(Site(api_server_rpc.app.resource()))
# reactor.listenTCP(int(args.port_rpc), server.Site(api_server_rpc))
# api_server_rpc.app.run(args.host, args.port_rpc)

if args.port_rest:
logger.info("Starting REST api server on http://%s:%s" % (args.host, args.port_rest))
api_server_rest = RestApi()
try:
rest_api = load_class_from_path(settings.REST_SERVER)
except ValueError as err:
logger.error(err)
sys.exit()
api_server_rest = rest_api()
endpoint_rest = "tcp:port={0}:interface={1}".format(args.port_rest, args.host)
endpoints.serverFromString(reactor, endpoint_rest).listen(Site(api_server_rest.app.resource()))
# api_server_rest.app.run(args.host, args.port_rest)

reactor.run()

Expand Down
4 changes: 3 additions & 1 deletion neo/data/protocol.mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@
"BootstrapFiles": "https://s3.us-east-2.amazonaws.com/cityofzion/bootstrap_latest",
"DebugStorage": 1,
"AcceptIncomingPeers": false,
"CompilerNep8": false
"CompilerNep8": false,
"RestServer": "neo.api.REST.RestApi.RestApi",
"RPCServer": "neo.api.JSONRPC.JsonRpcApi.JsonRpcApi"
}
}
4 changes: 3 additions & 1 deletion neo/data/protocol.privnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@
"BootstrapFiles": "https://s3.us-east-2.amazonaws.com/cityofzion/bootstrap_latest",
"DebugStorage": 1,
"AcceptIncomingPeers": false,
"CompilerNep8":false
"CompilerNep8": false,
"RestServer": "neo.api.REST.RestApi.RestApi",
"RPCServer": "neo.api.JSONRPC.JsonRpcApi.JsonRpcApi"
}
}
4 changes: 3 additions & 1 deletion neo/data/protocol.testnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
"BootstrapFiles": "https://s3.us-east-2.amazonaws.com/cityofzion/bootstrap_latest",
"DebugStorage": 1,
"AcceptIncomingPeers": false,
"CompilerNep8": false
"CompilerNep8": false,
"RestServer": "neo.api.REST.RestApi.RestApi",
"RPCServer": "neo.api.JSONRPC.JsonRpcApi.JsonRpcApi"
},
"ProtocolConfiguration": {
"AddressVersion": 23,
Expand Down
4 changes: 3 additions & 1 deletion neo/data/protocol.unittest-net.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
"AcceptIncomingPeers": false,
"CompilerNep8": true,
"BootstrapName": "fauxnet",
"BootstrapFiles": "this_does_not_exist_for_this_network"
"BootstrapFiles": "this_does_not_exist_for_this_network",
"RestServer": "neo.api.REST.RestApi.RestApi",
"RPCServer": "neo.api.JSONRPC.JsonRpcApi.JsonRpcApi"
}
}

0 comments on commit 2a501a1

Please sign in to comment.