From 919209fbb60ee55d9432ba48710d4ef94e76a39a Mon Sep 17 00:00:00 2001
From: John Gerlock <john.gerlock@gmail.com>
Date: Sat, 21 Oct 2017 19:22:41 -0500
Subject: [PATCH] Inital server update commit

---
 Dockerfile                 |  13 +-
 Makefile                   |   9 +-
 Pipfile                    |  32 +-
 Pipfile.lock               | 621 -------------------------------------
 docker-compose.yml         |   5 +-
 hive/cli.py                |   4 +-
 hive/db/__init__.py        |   4 +-
 hive/db/methods.py         |  43 ++-
 hive/db/schema.py          |   5 +-
 hive/sbds/input_parsers.py |  16 -
 hive/sbds/jsonrpc.py       | 136 --------
 hive/sbds/sbds_json.py     |  24 --
 hive/server/__init__.py    |   5 +-
 hive/server/cli.py         |  27 --
 hive/server/methods.py     |  36 ---
 hive/server/serve.py       | 179 ++++-------
 service/hive-indexer/run   |   2 +-
 service/hive-web/run       |  10 +-
 setup.py                   |   8 +-
 19 files changed, 141 insertions(+), 1038 deletions(-)
 delete mode 100644 Pipfile.lock
 delete mode 100644 hive/sbds/input_parsers.py
 delete mode 100644 hive/sbds/jsonrpc.py
 delete mode 100644 hive/sbds/sbds_json.py
 delete mode 100644 hive/server/methods.py
 mode change 100644 => 100755 service/hive-indexer/run
 mode change 100644 => 100755 service/hive-web/run

diff --git a/Dockerfile b/Dockerfile
index 832b80276..bc8891633 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -5,17 +5,16 @@ ENV ENVIRONMENT DEV
 ENV LOG_LEVEL INFO
 ENV LANG en_US.UTF-8
 ENV LC_ALL en_US.UTF-8
+ENV PIPENV_VENV_IN_PROJECT 1
 ENV APP_ROOT /app
 ENV WSGI_APP ${APP_ROOT}/hive/server/serve.py
-ENV HTTP_SERVER_PORT 8080
-ENV HTTP_SERVER_STATS_PORT 9191
+ENV HTTP_SERVER_PORT 9000
 
 RUN \
     apt-get update && \
     apt-get install -y \
         build-essential \
         daemontools \
-        git \
         libffi-dev \
         libmysqlclient-dev \
         libssl-dev \
@@ -31,8 +30,7 @@ RUN \
         libpcre3-dev
 
 RUN \
-    pip3 install --upgrade pip && \
-    pip3 install uwsgi
+    pip3 install --upgrade pip setuptools
 
 ADD . /app
 
@@ -43,9 +41,7 @@ RUN \
 WORKDIR /app
 
 RUN \
-    pip3 install pipenv && \
-    pip3 install -e git+https://github.com/steemit/steem-python.git#egg=steem && \
-    pip3 install -e . && \
+    pip3 install . && \
     apt-get remove -y \
         build-essential \
         libffi-dev \
@@ -61,4 +57,3 @@ RUN \
         /usr/local/include
 
 EXPOSE ${HTTP_SERVER_PORT}
-EXPOSE ${HTTP_SERVER_STATS_PORT}
diff --git a/Makefile b/Makefile
index 2a0477f70..6190379bd 100644
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,14 @@ compose:
 mysql:
 	docker run -d --name steemit_mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root_password -e MYSQL_DATABASE=testdb mysql
 
+
+serve-local:
+	pipenv run python hive/server/serve.py --port 8080 --database_url='mysql://root:root_password@127.0.0.1:3306/testdb'
+
+.PHONY: db-head-state
+db-head-state:
+	curl -H 'Content-Type: application/json' -d '{"id":1,"jsonrpc":"2.0","method":"db_head_state"}' http://localhost:8080
+
 ipython:
 	docker run -it $(PROJECT_DOCKER_RUN_ARGS) $(PROJECT_DOCKER_TAG) ipython
 
@@ -28,7 +36,6 @@ test: test-without-build build
 
 test-without-build: test-without-lint test-pylint
 
-
 test-without-lint:
 	py.test tests
 
diff --git a/Pipfile b/Pipfile
index 7b54691ee..d176ff0af 100644
--- a/Pipfile
+++ b/Pipfile
@@ -3,32 +3,32 @@ url = "https://pypi.python.org/simple"
 verify_ssl = true
 
 [packages]
-bottle = "*"
-bottle-sqlalchemy = "*"
-bottle_errorsrest = "*"
-SQLAlchemy = "*"
+
+sqlalchemy = "*"
 mysqlclient = "*"
 click = "*"
-click-spinner = "*"
+"click-spinner" = "*"
 funcy = "*"
 toolz = "*"
 maya = "*"
 ujson = "*"
-PrettyTable = "*"
+prettytable = "*"
+jsonrpcserver = "*"
+aiohttp = "*"
+aiomysql = "*"
 
-[requires]
-python_version = "3.5"
 
 [dev-packages]
+
 ipython = "*"
-pep8 = "*"
+"pep8" = "*"
 pytest = "*"
-pytest-console-scripts = "*"
-pytest-docker = "*"
-pytest-pylint = "*"
+"pytest-console-scripts" = "*"
+"pytest-docker" = "*"
+"pytest-pylint" = "*"
 recommonmark = "*"
-sphinxcontrib-programoutput = "*"
-sphinxcontrib-restbuilder = "*"
+"sphinxcontrib-programoutput" = "*"
+"sphinxcontrib-restbuilder" = "*"
 yapf = "*"
-Sphinx = "*"
-autopep8 = "*"
+sphinx = "*"
+"autopep8" = "*"
\ No newline at end of file
diff --git a/Pipfile.lock b/Pipfile.lock
deleted file mode 100644
index 1689c41f2..000000000
--- a/Pipfile.lock
+++ /dev/null
@@ -1,621 +0,0 @@
-{
-    "_meta": {
-        "hash": {
-            "sha256": "53295d238744428cb8d18d5fa55051b786a833a79910960b68a8d7321a561cc5"
-        },
-        "host-environment-markers": {
-            "implementation_name": "cpython",
-            "implementation_version": "3.6.1",
-            "os_name": "posix",
-            "platform_machine": "x86_64",
-            "platform_python_implementation": "CPython",
-            "platform_release": "16.7.0",
-            "platform_system": "Darwin",
-            "platform_version": "Darwin Kernel Version 16.7.0: Thu Jun 15 17:36:27 PDT 2017; root:xnu-3789.70.16~2/RELEASE_X86_64",
-            "python_full_version": "3.6.1",
-            "python_version": "3.6",
-            "sys_platform": "darwin"
-        },
-        "pipfile-spec": 3,
-        "requires": {
-            "python_version": "3.5"
-        },
-        "sources": [
-            {
-                "url": "https://pypi.python.org/simple",
-                "verify_ssl": true
-            }
-        ]
-    },
-    "default": {
-        "bottle": {
-            "hashes": [
-                "sha256:39b751aee0b167be8dffb63ca81b735bbf1dd0905b3bc42761efedee8f123355"
-            ],
-            "version": "==0.12.13"
-        },
-        "bottle-errorsrest": {
-            "hashes": [
-                "sha256:98a06ac885bda0e8bfcc6e9260c8fbd5a25e25a4805148c5880fa17e715386f5"
-            ],
-            "version": "==0.0.2"
-        },
-        "bottle-sqlalchemy": {
-            "hashes": [
-                "sha256:ba6127f3aff2b78649781adbbee65518233dc481e9f9e32e3b050d1ad9551c17"
-            ],
-            "version": "==0.4.3"
-        },
-        "click": {
-            "hashes": [
-                "sha256:29f99fc6125fbc931b758dc053b3114e55c77a6e4c6c3a2674a2dc986016381d",
-                "sha256:f15516df478d5a56180fbf80e68f206010e6d160fc39fa508b65e035fd75130b"
-            ],
-            "version": "==6.7"
-        },
-        "click-spinner": {
-            "hashes": [
-                "sha256:6e7af5fc2c7fe4a0434f4330c0075f31ea688e680760dcd14594250e8911230f",
-                "sha256:a0703b4a21a1ba377716c5c768928b6c7575c087af926d3d586818426982ea30"
-            ],
-            "version": "==0.1.7"
-        },
-        "dateparser": {
-            "hashes": [
-                "sha256:e2629d2f8361722c6047138ca085256c9f2cf5cc657fd66122aa0564afa4dc33",
-                "sha256:f8c24317120b06f71691d28076764ec084a132be2a250a78fdf54f6b427cac95"
-            ],
-            "version": "==0.6.0"
-        },
-        "funcy": {
-            "hashes": [
-                "sha256:30c0753228b4f1fceb653cccca995166da336680a556d70784dca91a388bd40f"
-            ],
-            "version": "==1.9"
-        },
-        "humanize": {
-            "hashes": [
-                "sha256:a43f57115831ac7c70de098e6ac46ac13be00d69abbf60bdcac251344785bb19"
-            ],
-            "version": "==0.5.1"
-        },
-        "maya": {
-            "hashes": [
-                "sha256:04c5d5380313d9b928746e0f8c1da914d093cd22e0324e48297347b90eb4043f",
-                "sha256:c1eea3fd6a63d17af5c7381c14440768f9b4ef21b3acbfd9e123c7f8ace6d174"
-            ],
-            "version": "==0.3.2"
-        },
-        "mysqlclient": {
-            "hashes": [
-                "sha256:b3b1a7e4468180afb79289b54069d9499242946a4cedf3928cbf6b2a13800016",
-                "sha256:d56e379c03efad746e84705cbb97401f60d1f98b05e11a27f2d9c2d043936974",
-                "sha256:371df79d000af56b4e540b7ce2120d1c9afb04b751bfce25a1eb609c50fd10ff",
-                "sha256:1e85e48b167e2af3bb08f273fdbd1ad6401cbe75057fa6513f97387dc7b282dc",
-                "sha256:2d9ec33de39f4d9c64ad7322ede0521d85829ce36a76f9dd3d6ab76a9c8648e5"
-            ],
-            "version": "==1.3.12"
-        },
-        "pendulum": {
-            "hashes": [
-                "sha256:8e24b9b6651402c9d5241cd09b2df16e8b8c2ee3e61ab0d243f7db81a7f4cc2b",
-                "sha256:dfabd6ebf87ec050214bfa41debf0985a91f98a9f808787272c5ebb56bdf743a",
-                "sha256:3415d9fb4d83e0a4466de24e2edcf385ce0378a5d9c06a4291d1d3411f5c9b4a",
-                "sha256:f47531a76ff67d21c2c0e1503c1bd8e5dbfd0ffb469c6ca8f68b6ef04ed7e8c4",
-                "sha256:8b52d8fc1e7a8b3025e434da351c98c34b478e8818d9fedbffed11ffb7a156cf",
-                "sha256:878072ac65a2d2c9abc5954bb2eda305c7ec3b5430f39cb8819cc4b676dd79a3",
-                "sha256:f00d45f5d4cc57829f778b024af35ce08ca0459993aff92d7606a14d7a872633",
-                "sha256:1f9f4cba0b21beead709a38ea9847e4324f037052bbcfd93147634e9966aaba6"
-            ],
-            "version": "==1.2.5"
-        },
-        "prettytable": {
-            "hashes": [
-                "sha256:853c116513625c738dc3ce1aee148b5b5757a86727e67eff6502c7ca59d43c36",
-                "sha256:2d5460dc9db74a32bcc8f9f67de68b2c4f4d2f01fa3bd518764c69156d9cacd9",
-                "sha256:a53da3b43d7a5c229b5e3ca2892ef982c46b7923b51e98f0db49956531211c4f"
-            ],
-            "version": "==0.7.2"
-        },
-        "python-dateutil": {
-            "hashes": [
-                "sha256:95511bae634d69bc7329ba55e646499a842bc4ec342ad54a8cdb65645a0aad3c",
-                "sha256:891c38b2a02f5bb1be3e4793866c8df49c7d19baabf9c1bad62547e0b4866aca"
-            ],
-            "version": "==2.6.1"
-        },
-        "pytz": {
-            "hashes": [
-                "sha256:c883c2d6670042c7bc1688645cac73dd2b03193d1f7a6847b6154e96890be06d",
-                "sha256:03c9962afe00e503e2d96abab4e8998a0f84d4230fa57afe1e0528473698cdd9",
-                "sha256:487e7d50710661116325747a9cd1744d3323f8e49748e287bc9e659060ec6bf9",
-                "sha256:43f52d4c6a0be301d53ebd867de05e2926c35728b3260157d274635a0a947f1c",
-                "sha256:d1d6729c85acea5423671382868627129432fba9a89ecbb248d8d1c7a9f01c67",
-                "sha256:54a935085f7bf101f86b2aff75bd9672b435f51c3339db2ff616e66845f2b8f9",
-                "sha256:39504670abb5dae77f56f8eb63823937ce727d7cdd0088e6909e6dcac0f89043",
-                "sha256:ddc93b6d41cfb81266a27d23a79e13805d4a5521032b512643af8729041a81b4",
-                "sha256:f5c056e8f62d45ba8215e5cb8f50dfccb198b4b9fbea8500674f3443e4689589"
-            ],
-            "version": "==2017.2"
-        },
-        "pytzdata": {
-            "hashes": [
-                "sha256:bd19fd653f89e498f1d4f9390d96456ce26ecd293a5e7405120a5de875d3314c",
-                "sha256:141c539a6b3f6040ca4728f8a85df598f60adccdfbab3ac1efe110934ce4a331"
-            ],
-            "version": "==2017.2.2"
-        },
-        "regex": {
-            "hashes": [
-                "sha256:1dad6cc413f96eddea48a50c7c039596d6a58af2110a6f19182357833ef83787",
-                "sha256:3f0bbff5e0bb4f9dec8dd57d85c5a4f0ead44cc31f81b104e79d42248a170343",
-                "sha256:c7c7cdae70faf377cc308e6389064379daf53e79c538cd9f085d7fdd754486d8",
-                "sha256:427908c9721581b3548dbee80dea45023db9261ea77c0bf353474d686760113d",
-                "sha256:159d6acb1a7bb05b128f9ca721864f5c394291c032cff6c42cbf6ecbc2d291ef",
-                "sha256:b6591a73146e4207e24c01edab551eb980f81cec1075bab9909cd473a3d6da5d",
-                "sha256:ddcf580827c8f4eb831f9bd547eb2e6b7da43823ceab0744dab3f4a5e131a014",
-                "sha256:f2d6b002a0d4fd4141b92d06899293b7ccab73b8043742e40d11b20c051e209a",
-                "sha256:0905c080f57d35fe34cd38e81f57adc4b2495be794cfa5ac8c74eb0261d84734",
-                "sha256:2012fbcaedf1fc496be147e3f72ca05593f3723a9e156bf170496fe15010ac1a",
-                "sha256:c214a7a3d742dd9e930acb5ff933264de24b2d9adcd7be46bd5baae90cdb9925",
-                "sha256:feca025094e4bc1b0583290b143a7b253b5f0ee21dc3f8e39a8b6c2f317a6833",
-                "sha256:0e529e0fef1456ed0e847b6e9d23a92f1a6c45dd7e22380cc6fa108f3474e2a7",
-                "sha256:f5739e8a1d83be1197363866e2a0b76ef5d472391487d53eb4cef0bcaabb41d2",
-                "sha256:2e6b3740fefe21becc00f3629d11fb8b239c8440c5d8d1d0fff7688a2f03fb96",
-                "sha256:ebc8774912557fd9ba1a2aae0c305a410ec40ae84ca08e6d2549c72ebf517ae0",
-                "sha256:c61a721f083824902d78d10ec109ab74ba978e3b8010a0c5fbd44dab308b9867",
-                "sha256:df270fcadf0872f4e599fce1d355460da0f79097c214a3a4fc09598b41f176fb",
-                "sha256:27ab18243b1a0aa1467027be93b118c9fcd60dd2e4020da579fad3008bc4638f"
-            ],
-            "version": "==2017.7.28"
-        },
-        "ruamel.yaml": {
-            "hashes": [
-                "sha256:4bdec0b1a4a12e4a35b788ef53e0b2efd1e9f815ca48615b5244ccdbc8f0b56b",
-                "sha256:6432088ef1c3cdc4b304dcec6044e560160c1f51dd0360ae3f0887057d310056",
-                "sha256:64868964b64cad9103f37d0b4fc0ec950e5b683bbc47bf4a1ea893fd70aaabf0",
-                "sha256:c8da0ea47df5f2dee58f6f904335ac55098b7e72303b01414ce80f37dd3091df",
-                "sha256:87bdfb04981f1040ec60b1d1bfa8e7e4d89f7d06c86d4b2fa935002c62e43380",
-                "sha256:c20e853cb585167fd5e4ce6e1b57fefe7bd4a61659f8fec5f77e12efa59a7a77",
-                "sha256:e884979944642b4ad3222cb102a0d4c17fed2d37abfffdf0f319fae6e41d436a",
-                "sha256:10493c92c0e5bd57d576d73b708ed900532846ead1b381c5236c41d0c39f5f71",
-                "sha256:3127a87b274e516b3bf2058f64d784089322fddd7322f8e78e9f5380bdfee064",
-                "sha256:530bec874292bacbbb80a9143e5182ce436c2a2434a2ea83dda24d30b8e572df",
-                "sha256:d92d90c9bc0945223e47223a67808dd97ac9390ed914cc6871479b7ba489e607",
-                "sha256:3e87114aac9553c39eea4b88e258eb7fdce39b81a2c399a775efe1f64e4f3d7b",
-                "sha256:dfd14829070728159d0dac55a19e4c77514cb8ad3ae3fc2ed065d7f24038b60f",
-                "sha256:2f28a3b6665697c20d841a4aee21cfb932bb0db91f293ff97daf845b914ddddb",
-                "sha256:2de7bd2d5713c46be9d1d489b028178c9497813f78bd0486a31bbe1c268d7f21",
-                "sha256:ddf0e1277664fafff0ae692e8ea2fca56f1ee4daf686d9be785ccdf3a9542744",
-                "sha256:f1e29054c6e477963e302b007b6cd1d6c7a58c38d78fabe64fde9ce170d2d1fd"
-            ],
-            "version": "==0.15.34"
-        },
-        "six": {
-            "hashes": [
-                "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb",
-                "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9"
-            ],
-            "version": "==1.11.0"
-        },
-        "sqlalchemy": {
-            "hashes": [
-                "sha256:f1191e29e35b6fe1aef7175a09b1707ebb7bd08d0b17cb0feada76c49e5a2d1e"
-            ],
-            "version": "==1.1.14"
-        },
-        "toolz": {
-            "hashes": [
-                "sha256:4a13c90c426001d6299c5568cf5b98e095df9c985df194008a67f84ef4fc6c50"
-            ],
-            "version": "==0.8.2"
-        },
-        "tzlocal": {
-            "hashes": [
-                "sha256:05a2908f7fb1ba8843f03b2360d6ad314dbf2bce4644feb702ccd38527e13059"
-            ],
-            "version": "==1.4"
-        },
-        "ujson": {
-            "hashes": [
-                "sha256:f66073e5506e91d204ab0c614a148d5aa938bdbf104751be66f8ad7a222f5f86"
-            ],
-            "version": "==1.35"
-        }
-    },
-    "develop": {
-        "alabaster": {
-            "hashes": [
-                "sha256:2eef172f44e8d301d25aff8068fddd65f767a3f04b5f15b0f4922f113aa1c732",
-                "sha256:37cdcb9e9954ed60912ebc1ca12a9d12178c26637abdf124e3cde2341c257fe0"
-            ],
-            "version": "==0.7.10"
-        },
-        "appnope": {
-            "hashes": [
-                "sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0",
-                "sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71"
-            ],
-            "version": "==0.1.0"
-        },
-        "astroid": {
-            "hashes": [
-                "sha256:39a21dd2b5d81a6731dc0ac2884fa419532dffd465cdd43ea6c168d36b76efb3",
-                "sha256:492c2a2044adbf6a84a671b7522e9295ad2f6a7c781b899014308db25312dd35"
-            ],
-            "version": "==1.5.3"
-        },
-        "attrs": {
-            "hashes": [
-                "sha256:c59426b15b45e39a7bc408eb6ba7e7188d9532764f873cc691199ddd975c97ef",
-                "sha256:80203177723e36f3bbe15aa8553da6e80d47bfe53647220ccaa9ad7a5e473ccc"
-            ],
-            "version": "==16.3.0"
-        },
-        "autopep8": {
-            "hashes": [
-                "sha256:eb1685527355809967a0363572289303dc05f4b05edbeee4c9051762103e0ee6",
-                "sha256:7e82590bf366b4d891ac5c1535554c46a5f79e4400a190a8493e92e75c5037dd"
-            ],
-            "version": "==1.3.2"
-        },
-        "babel": {
-            "hashes": [
-                "sha256:f20b2acd44f587988ff185d8949c3e208b4b3d5d20fcab7d91fe481ffa435528",
-                "sha256:6007daf714d0cd5524bbe436e2d42b3c20e68da66289559341e48d2cd6d25811"
-            ],
-            "version": "==2.5.1"
-        },
-        "certifi": {
-            "hashes": [
-                "sha256:54a07c09c586b0e4c619f02a5e94e36619da8e2b053e20f594348c0611803704",
-                "sha256:40523d2efb60523e113b44602298f0960e900388cf3bb6043f645cf57ea9e3f5"
-            ],
-            "version": "==2017.7.27.1"
-        },
-        "chardet": {
-            "hashes": [
-                "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691",
-                "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"
-            ],
-            "version": "==3.0.4"
-        },
-        "commonmark": {
-            "hashes": [
-                "sha256:34d73ec8085923c023930dfc0bcd1c4286e28a2a82de094bb72fabcc0281cbe5"
-            ],
-            "version": "==0.5.4"
-        },
-        "decorator": {
-            "hashes": [
-                "sha256:95a26b17806e284452bfd97fa20aa1e8cb4ee23542bda4dbac5e4562aa1642cd",
-                "sha256:7cb64d38cb8002971710c8899fbdfb859a23a364b7c99dab19d1f719c2ba16b5"
-            ],
-            "version": "==4.1.2"
-        },
-        "docutils": {
-            "hashes": [
-                "sha256:7a4bd47eaf6596e1295ecb11361139febe29b084a87bf005bf899f9a42edc3c6",
-                "sha256:02aec4bd92ab067f6ff27a38a38a41173bf01bed8f89157768c1573f53e474a6",
-                "sha256:51e64ef2ebfb29cae1faa133b3710143496eca21c530f3f71424d77687764274"
-            ],
-            "version": "==0.14"
-        },
-        "idna": {
-            "hashes": [
-                "sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4",
-                "sha256:2c6a5de3089009e3da7c5dde64a141dbc8551d5b7f6cf4ed7c2568d0cc520a8f"
-            ],
-            "version": "==2.6"
-        },
-        "imagesize": {
-            "hashes": [
-                "sha256:6ebdc9e0ad188f9d1b2cdd9bc59cbe42bf931875e829e7a595e6b3abdc05cdfb",
-                "sha256:0ab2c62b87987e3252f89d30b7cedbec12a01af9274af9ffa48108f2c13c6062"
-            ],
-            "version": "==0.7.1"
-        },
-        "ipython": {
-            "hashes": [
-                "sha256:0faac098d0e5a79272d1a8dd95d568c7ae7a823c9b21b1bca5800541aa994e6f",
-                "sha256:81b0d6936f87002e6972eccc7e4085f5c2d0673decff22724b53cf34809ffacf"
-            ],
-            "version": "==6.2.0"
-        },
-        "ipython-genutils": {
-            "hashes": [
-                "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8",
-                "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"
-            ],
-            "version": "==0.2.0"
-        },
-        "isort": {
-            "hashes": [
-                "sha256:cd5d3fc2c16006b567a17193edf4ed9830d9454cbeb5a42ac80b36ea00c23db4",
-                "sha256:79f46172d3a4e2e53e7016e663cc7a8b538bec525c36675fcfd2767df30b3983"
-            ],
-            "version": "==4.2.15"
-        },
-        "jedi": {
-            "hashes": [
-                "sha256:96678411f2ffa444da3a5e7fdd4adc513b728a4a4617b30308be5c950722424b",
-                "sha256:7abb618cac6470ebbd142e59c23daec5e6e063bfcecc8a43a037d2ab57276f4e"
-            ],
-            "version": "==0.10.2"
-        },
-        "jinja2": {
-            "hashes": [
-                "sha256:2231bace0dfd8d2bf1e5d7e41239c06c9e0ded46e70cc1094a0aa64b0afeb054",
-                "sha256:ddaa01a212cd6d641401cb01b605f4a4d9f37bfc93043d7f760ec70fb99ff9ff"
-            ],
-            "version": "==2.9.6"
-        },
-        "lazy-object-proxy": {
-            "hashes": [
-                "sha256:209615b0fe4624d79e50220ce3310ca1a9445fd8e6d3572a896e7f9146bbf019",
-                "sha256:1b668120716eb7ee21d8a38815e5eb3bb8211117d9a90b0f8e21722c0758cc39",
-                "sha256:cb924aa3e4a3fb644d0c463cad5bc2572649a6a3f68a7f8e4fbe44aaa6d77e4c",
-                "sha256:2c1b21b44ac9beb0fc848d3993924147ba45c4ebc24be19825e57aabbe74a99e",
-                "sha256:320ffd3de9699d3892048baee45ebfbbf9388a7d65d832d7e580243ade426d2b",
-                "sha256:2df72ab12046a3496a92476020a1a0abf78b2a7db9ff4dc2036b8dd980203ae6",
-                "sha256:27ea6fd1c02dcc78172a82fc37fcc0992a94e4cecf53cb6d73f11749825bd98b",
-                "sha256:e5b9e8f6bda48460b7b143c3821b21b452cb3a835e6bbd5dd33aa0c8d3f5137d",
-                "sha256:7661d401d60d8bf15bb5da39e4dd72f5d764c5aff5a86ef52a042506e3e970ff",
-                "sha256:61a6cf00dcb1a7f0c773ed4acc509cb636af2d6337a08f362413c76b2b47a8dd",
-                "sha256:bd6292f565ca46dee4e737ebcc20742e3b5be2b01556dafe169f6c65d088875f",
-                "sha256:933947e8b4fbe617a51528b09851685138b49d511af0b6c0da2539115d6d4514",
-                "sha256:d0fc7a286feac9077ec52a927fc9fe8fe2fabab95426722be4c953c9a8bede92",
-                "sha256:7f3a2d740291f7f2c111d86a1c4851b70fb000a6c8883a59660d95ad57b9df35",
-                "sha256:5276db7ff62bb7b52f77f1f51ed58850e315154249aceb42e7f4c611f0f847ff",
-                "sha256:94223d7f060301b3a8c09c9b3bc3294b56b2188e7d8179c762a1cda72c979252",
-                "sha256:6ae6c4cb59f199d8827c5a07546b2ab7e85d262acaccaacd49b62f53f7c456f7",
-                "sha256:f460d1ceb0e4a5dcb2a652db0904224f367c9b3c1470d5a7683c0480e582468b",
-                "sha256:e81ebf6c5ee9684be8f2c87563880f93eedd56dd2b6146d8a725b50b7e5adb0f",
-                "sha256:81304b7d8e9c824d058087dcb89144842c8e0dea6d281c031f59f0acf66963d4",
-                "sha256:ddc34786490a6e4ec0a855d401034cbd1242ef186c20d79d2166d6a4bd449577",
-                "sha256:7bd527f36a605c914efca5d3d014170b2cb184723e423d26b1fb2fd9108e264d",
-                "sha256:ab3ca49afcb47058393b0122428358d2fbe0408cf99f1b58b295cfeb4ed39109",
-                "sha256:7cb54db3535c8686ea12e9535eb087d32421184eacc6939ef15ef50f83a5e7e2",
-                "sha256:0ce34342b419bd8f018e6666bfef729aec3edf62345a53b537a4dcc115746a33",
-                "sha256:e34b155e36fa9da7e1b7c738ed7767fc9491a62ec6af70fe9da4a057759edc2d",
-                "sha256:50e3b9a464d5d08cc5227413db0d1c4707b6172e4d4d915c1c70e4de0bbff1f5",
-                "sha256:27bf62cb2b1a2068d443ff7097ee33393f8483b570b475db8ebf7e1cba64f088",
-                "sha256:eb91be369f945f10d3a49f5f9be8b3d0b93a4c2be8f8a5b83b0571b8123e0a7a"
-            ],
-            "version": "==1.3.1"
-        },
-        "markupsafe": {
-            "hashes": [
-                "sha256:a6be69091dac236ea9c6bc7d012beab42010fa914c459791d627dad4910eb665"
-            ],
-            "version": "==1.0"
-        },
-        "mccabe": {
-            "hashes": [
-                "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42",
-                "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"
-            ],
-            "version": "==0.6.1"
-        },
-        "mock": {
-            "hashes": [
-                "sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1",
-                "sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba"
-            ],
-            "version": "==2.0.0"
-        },
-        "pbr": {
-            "hashes": [
-                "sha256:60c25b7dfd054ef9bb0ae327af949dd4676aa09ac3a9471cdc871d8a9213f9ac",
-                "sha256:05f61c71aaefc02d8e37c0a3eeb9815ff526ea28b3b76324769e6158d7f95be1"
-            ],
-            "version": "==3.1.1"
-        },
-        "pep8": {
-            "hashes": [
-                "sha256:4fc2e478addcf17016657dff30b2d8d611e8341fac19ccf2768802f6635d7b8a",
-                "sha256:a113d5f5ad7a7abacef9df5ec3f2af23a20a28005921577b15dd584d099d5900"
-            ],
-            "version": "==1.7.0"
-        },
-        "pexpect": {
-            "hashes": [
-                "sha256:f853b52afaf3b064d29854771e2db509ef80392509bde2dd7a6ecf2dfc3f0018",
-                "sha256:3d132465a75b57aa818341c6521392a06cc660feb3988d7f1074f39bd23c9a92"
-            ],
-            "version": "==4.2.1"
-        },
-        "pickleshare": {
-            "hashes": [
-                "sha256:c9a2541f25aeabc070f12f452e1f2a8eae2abd51e1cd19e8430402bdf4c1d8b5",
-                "sha256:84a9257227dfdd6fe1b4be1319096c20eb85ff1e82c7932f36efccfe1b09737b"
-            ],
-            "version": "==0.7.4"
-        },
-        "prompt-toolkit": {
-            "hashes": [
-                "sha256:3f473ae040ddaa52b52f97f6b4a493cfa9f5920c255a12dc56a7d34397a398a4",
-                "sha256:1df952620eccb399c53ebb359cc7d9a8d3a9538cb34c5a1344bdbeb29fbcc381",
-                "sha256:858588f1983ca497f1cf4ffde01d978a3ea02b01c8a26a8bbc5cd2e66d816917"
-            ],
-            "version": "==1.0.15"
-        },
-        "ptyprocess": {
-            "hashes": [
-                "sha256:e8c43b5eee76b2083a9badde89fd1bbce6c8942d1045146e100b7b5e014f4f1a",
-                "sha256:e64193f0047ad603b71f202332ab5527c5e52aa7c8b609704fc28c0dc20c4365"
-            ],
-            "version": "==0.5.2"
-        },
-        "py": {
-            "hashes": [
-                "sha256:2ccb79b01769d99115aa600d7eed99f524bf752bba8f041dc1c184853514655a",
-                "sha256:0f2d585d22050e90c7d293b6451c83db097df77871974d90efd5a30dc12fcde3"
-            ],
-            "version": "==1.4.34"
-        },
-        "pycodestyle": {
-            "hashes": [
-                "sha256:6c4245ade1edfad79c3446fadfc96b0de2759662dc29d07d80a6f27ad1ca6ba9",
-                "sha256:682256a5b318149ca0d2a9185d365d8864a768a28db66a84a2ea946bcc426766"
-            ],
-            "version": "==2.3.1"
-        },
-        "pygments": {
-            "hashes": [
-                "sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d",
-                "sha256:dbae1046def0efb574852fab9e90209b23f556367b5a320c0bcb871c77c3e8cc"
-            ],
-            "version": "==2.2.0"
-        },
-        "pylint": {
-            "hashes": [
-                "sha256:c7a3ee11db42d00334671b778f042793c837b73f5883132158284b7dbd6f8184",
-                "sha256:ea6afb93a9ed810cf52ff3838eb3a15e2bf6a81b80de0eaede1ce442caa5ca69"
-            ],
-            "version": "==1.7.2"
-        },
-        "pytest": {
-            "hashes": [
-                "sha256:b84f554f8ddc23add65c411bf112b2d88e2489fd45f753b1cae5936358bdf314",
-                "sha256:f46e49e0340a532764991c498244a60e3a37d7424a532b3ff1a6a7653f1a403a"
-            ],
-            "version": "==3.2.2"
-        },
-        "pytest-console-scripts": {
-            "hashes": [
-                "sha256:75188d816f7398956aee48dbff4ce6759d64fbf617f760c8c4cec77608afb8a3"
-            ],
-            "version": "==0.1.3"
-        },
-        "pytest-docker": {
-            "hashes": [
-                "sha256:f5da311c8054f6118b8d6b096c3aed7a57eb4c7c7e947a39c797b48e06412a7a",
-                "sha256:3affb14ddd79c68bfd95b7bbb92b331babcee36229ebe6986144e5d9b5d72155",
-                "sha256:b410a15b8f05a5f2f8d014610eedf4aba4601eee15a33bb9278751e83089c2de"
-            ],
-            "version": "==0.6.0"
-        },
-        "pytest-pylint": {
-            "hashes": [
-                "sha256:9b8ca25823b2f39e89d8170453f5282e57b973395060e838ced5f8c09271ca65",
-                "sha256:2efaf761472637df9a8f4a3f4fac37f8ce433d70957c5f5767c4be322a42a3d2",
-                "sha256:9f38725b22967a56724115c9df0a93dda37fea71dd5495fb1354b82e3d938d0d",
-                "sha256:85da6403c69eb715b9703df640818f337603f2cac947f932b033588851aaaf16",
-                "sha256:b85763dc36757bfb736b07fecb4f67a0892dcb00868e01f150c7424f608bd62e",
-                "sha256:ec63f7c4c05331654ab54fda8e68b8a11512009d506a8e35ee9b6d40a359356d",
-                "sha256:2bb26948f0355d14b274742153a6b4daa51e6d60481143bfd7f025699a27210d"
-            ],
-            "version": "==0.7.1"
-        },
-        "pytz": {
-            "hashes": [
-                "sha256:c883c2d6670042c7bc1688645cac73dd2b03193d1f7a6847b6154e96890be06d",
-                "sha256:03c9962afe00e503e2d96abab4e8998a0f84d4230fa57afe1e0528473698cdd9",
-                "sha256:487e7d50710661116325747a9cd1744d3323f8e49748e287bc9e659060ec6bf9",
-                "sha256:43f52d4c6a0be301d53ebd867de05e2926c35728b3260157d274635a0a947f1c",
-                "sha256:d1d6729c85acea5423671382868627129432fba9a89ecbb248d8d1c7a9f01c67",
-                "sha256:54a935085f7bf101f86b2aff75bd9672b435f51c3339db2ff616e66845f2b8f9",
-                "sha256:39504670abb5dae77f56f8eb63823937ce727d7cdd0088e6909e6dcac0f89043",
-                "sha256:ddc93b6d41cfb81266a27d23a79e13805d4a5521032b512643af8729041a81b4",
-                "sha256:f5c056e8f62d45ba8215e5cb8f50dfccb198b4b9fbea8500674f3443e4689589"
-            ],
-            "version": "==2017.2"
-        },
-        "recommonmark": {
-            "hashes": [
-                "sha256:cd8bf902e469dae94d00367a8197fb7b81fcabc9cfb79d520e0d22d0fbeaa8b7",
-                "sha256:6e29c723abcf5533842376d87c4589e62923ecb6002a8e059eb608345ddaff9d"
-            ],
-            "version": "==0.4.0"
-        },
-        "requests": {
-            "hashes": [
-                "sha256:6a1b267aa90cac58ac3a765d067950e7dbbf75b1da07e895d1f594193a40a38b",
-                "sha256:9c443e7324ba5b85070c4a818ade28bfabedf16ea10206da1132edaa6dda237e"
-            ],
-            "version": "==2.18.4"
-        },
-        "simplegeneric": {
-            "hashes": [
-                "sha256:dc972e06094b9af5b855b3df4a646395e43d1c9d0d39ed345b7393560d0b9173"
-            ],
-            "version": "==0.8.1"
-        },
-        "six": {
-            "hashes": [
-                "sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb",
-                "sha256:70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9"
-            ],
-            "version": "==1.11.0"
-        },
-        "snowballstemmer": {
-            "hashes": [
-                "sha256:9f3bcd3c401c3e862ec0ebe6d2c069ebc012ce142cce209c098ccb5b09136e89",
-                "sha256:919f26a68b2c17a7634da993d91339e288964f93c274f1343e3bbbe2096e1128"
-            ],
-            "version": "==1.2.1"
-        },
-        "sphinx": {
-            "hashes": [
-                "sha256:3ea0faf3e152a0e40372d8495c8cbd59e93f89266231c367d8098ec0dfede98f",
-                "sha256:af8bdb8c714552b77d01d4536e3d6d2879d6cb9d25423d29163d5788e27046e6"
-            ],
-            "version": "==1.6.3"
-        },
-        "sphinxcontrib-programoutput": {
-            "hashes": [
-                "sha256:bd47ff0e1cddec82e1d4501f6f0fa3f77481765fcc7c58ec685ef05b44386c40",
-                "sha256:cbec3ee1c3abd09e105115ab69cb5ade8ca1be9811565a844f973e93e0314837"
-            ],
-            "version": "==0.11"
-        },
-        "sphinxcontrib-restbuilder": {
-            "hashes": [
-                "sha256:8f2d7d73930fdedc3571adab32fbe843b4716829a291dbb27bab56b7c8d1e23d"
-            ],
-            "version": "==0.1"
-        },
-        "sphinxcontrib-websupport": {
-            "hashes": [
-                "sha256:f4932e95869599b89bf4f80fc3989132d83c9faa5bf633e7b5e0c25dffb75da2",
-                "sha256:7a85961326aa3a400cd4ad3c816d70ed6f7c740acd7ce5d78cd0a67825072eb9"
-            ],
-            "version": "==1.0.1"
-        },
-        "traitlets": {
-            "hashes": [
-                "sha256:c6cb5e6f57c5a9bdaa40fa71ce7b4af30298fbab9ece9815b5d995ab6217c7d9",
-                "sha256:9c4bd2d267b7153df9152698efb1050a5d84982d3384a37b2c1f7723ba3e7835"
-            ],
-            "version": "==4.3.2"
-        },
-        "urllib3": {
-            "hashes": [
-                "sha256:06330f386d6e4b195fbfc736b297f58c5a892e4440e54d294d7004e3a9bbea1b",
-                "sha256:cc44da8e1145637334317feebd728bd869a35285b93cbb4cca2577da7e62db4f"
-            ],
-            "version": "==1.22"
-        },
-        "wcwidth": {
-            "hashes": [
-                "sha256:f4ebe71925af7b40a864553f761ed559b43544f8f71746c2d756c7fe788ade7c",
-                "sha256:3df37372226d6e63e1b1e1eda15c594bca98a22d33a23832a90998faa96bc65e"
-            ],
-            "version": "==0.1.7"
-        },
-        "wrapt": {
-            "hashes": [
-                "sha256:d4d560d479f2c21e1b5443bbd15fe7ec4b37fe7e53d335d3b9b0a7b1226fe3c6"
-            ],
-            "version": "==1.10.11"
-        },
-        "yapf": {
-            "hashes": [
-                "sha256:b6a47545511839861ae92108476c119de27a4b137f380f2fd452bcc39bcd6c31",
-                "sha256:c703dbe4ec882061184a4ae128d2fefcae00641bb4c73df9b85fd0ea05294354"
-            ],
-            "version": "==0.18.0"
-        }
-    }
-}
diff --git a/docker-compose.yml b/docker-compose.yml
index f84358395..b4279a9d3 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -17,11 +17,12 @@ services:
     environment:
       DATABASE_URL: mysql://root:root_password@mysql:3306/testdb
       LOG_LEVEL: DEBUG
-      STEEMD_URL: https://api.steemitdev.com
+      JUSSI_URL: https://api.steemit.com
+      STEEMD_URL: https://api.steemit.com
     links:
       - mysql:db
     ports:
-      - 8080:8080
+      - 9000:9000
     volumes:
       - .:/app
     restart: always
diff --git a/hive/cli.py b/hive/cli.py
index 04ef4d6c9..e3eda14d6 100644
--- a/hive/cli.py
+++ b/hive/cli.py
@@ -1,7 +1,7 @@
 import click
 from hive.db.cli import db
 from hive.indexer.cli import indexer
-from hive.server.cli import server
+
 
 context_settings = dict(help_option_names=['-h', '--help'])
 
@@ -21,4 +21,4 @@ def cli():
 
 cli.add_command(db)
 cli.add_command(indexer)
-cli.add_command(server)
+
diff --git a/hive/db/__init__.py b/hive/db/__init__.py
index 270bd2a10..a9201d7d6 100644
--- a/hive/db/__init__.py
+++ b/hive/db/__init__.py
@@ -1,3 +1,3 @@
-from hive.db.schema import connect
+from hive.db.schema import engine
+
 
-conn = connect(echo=False)
diff --git a/hive/db/methods.py b/hive/db/methods.py
index c663b091c..e975acc85 100644
--- a/hive/db/methods.py
+++ b/hive/db/methods.py
@@ -1,5 +1,6 @@
+import logging
 from funcy.seqs import first
-from hive.db import conn
+from hive.db import engine
 from hive.db.schema import (
     hive_follows,
 )
@@ -9,17 +10,26 @@ from decimal import Decimal
 import time
 import re
 
+logger = logging.getLogger(__name__)
+
 # generic
 # -------
 def query(sql, **kwargs):
     ti = time.time()
     query = text(sql).execution_options(autocommit=False)
-    res = conn.execute(query, **kwargs)
-    ms = int((time.time() - ti) * 1000)
-    if ms > 100:
-        disp = re.sub('\s+', ' ', sql).strip()[:250]
-        print("\033[93m[SQL][{}ms] {}\033[0m".format(ms, disp))
-    return res
+    conn = engine.connect()
+    try:
+        res = conn.execute(query, **kwargs)
+        ms = int((time.time() - ti) * 1000)
+        if ms > 100:
+            disp = re.sub('\s+', ' ', sql).strip()[:250]
+            print("\033[93m[SQL][{}ms] {}\033[0m".format(ms, disp))
+        logger.debug(res)
+        return res
+    except Exception as e:
+        conn.close()
+        logger.exception(e)
+        raise e
 
 # n*m
 def query_all(sql, **kwargs):
@@ -43,20 +53,21 @@ def query_one(sql, **kwargs):
         return first(row)
 
 
-def db_head_state():
+async def db_head_state():
     sql = "SELECT num,created_at,UNIX_TIMESTAMP(CONVERT_TZ(created_at, '+00:00', 'SYSTEM')) ts FROM hive_blocks ORDER BY num DESC LIMIT 1"
     row = query_row(sql)
     return dict(db_head_block = row['num'],
                 db_head_time = row['created_at'],
                 db_head_age = int(time.time() - row['ts']))
 
-def db_last_block():
+
+async def db_last_block():
     return query_one("SELECT MAX(num) FROM hive_blocks") or 0
 
 
 # api specific
 # ------------
-def get_followers(account: str, skip: int, limit: int):
+async def get_followers(account: str, skip: int, limit: int):
     sql = """
     SELECT follower, created_at FROM hive_follows WHERE following = :account
     AND state = 1 ORDER BY created_at DESC LIMIT :limit OFFSET :skip
@@ -65,7 +76,7 @@ def get_followers(account: str, skip: int, limit: int):
     return [[r[0],r[1]] for r in res.fetchall()]
 
 
-def get_following(account: str, skip: int, limit: int):
+async def get_following(account: str, skip: int, limit: int):
     sql = """
     SELECT following, created_at FROM hive_follows WHERE follower = :account
     AND state = 1 ORDER BY created_at DESC LIMIT :limit OFFSET :skip
@@ -74,18 +85,18 @@ def get_following(account: str, skip: int, limit: int):
     return [[r[0],r[1]] for r in res.fetchall()]
 
 
-def following_count(account: str):
+async def following_count(account: str):
     sql = "SELECT COUNT(*) FROM hive_follows WHERE follower = :a AND state = 1"
     return query_one(sql, a=account)
 
 
-def follower_count(account: str):
+async def follower_count(account: str):
     sql = "SELECT COUNT(*) FROM hive_follows WHERE following = :a AND state = 1"
     return query_one(sql, a=account)
 
 
 # evaluate replacing two above methods with this
-def follow_stats(account: str):
+async def follow_stats(account: str):
     sql = """
     SELECT SUM(IF(follower  = :account, 1, 0)) following,
            SUM(IF(following = :account, 1, 0)) followers
@@ -95,7 +106,7 @@ def follow_stats(account: str):
     return first(query(sql))
 
 # all completed payouts
-def payouts_total():
+async def payouts_total():
     # memoized historical sum. To update:
     #  SELECT SUM(payout) FROM hive_posts_cache
     #  WHERE is_paidout = 1 AND payout_at <= precalc_date
@@ -111,7 +122,7 @@ def payouts_total():
     return precalc_sum + query_one(sql)
 
 # sum of completed payouts last 24 hrs
-def payouts_last_24h():
+async def payouts_last_24h():
     sql = """
       SELECT SUM(payout) FROM hive_posts_cache
       WHERE is_paidout = 1 AND payout_at > DATE_SUB(NOW(), INTERVAL 24 HOUR)
diff --git a/hive/db/schema.py b/hive/db/schema.py
index 09864dd93..cbe7899f2 100644
--- a/hive/db/schema.py
+++ b/hive/db/schema.py
@@ -231,8 +231,9 @@ logging.basicConfig()
 logging.getLogger('sqlalchemy.engine').setLevel(logging.WARNING)
 
 
-def connect(connection_url=_url, **kwargs):
-    return sa.create_engine(connection_url + "?charset=utf8mb4", isolation_level="READ UNCOMMITTED", pool_recycle=3600, **kwargs).connect()
+engine = sa.create_engine(_url + "?charset=utf8mb4", isolation_level="READ UNCOMMITTED", pool_recycle=3600)
+
+
 
 
 def setup(connection_url=_url):
diff --git a/hive/sbds/input_parsers.py b/hive/sbds/input_parsers.py
deleted file mode 100644
index 08d47fcd9..000000000
--- a/hive/sbds/input_parsers.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- coding: utf-8 -*-
-import logging
-from functools import singledispatch
-
-import funcy
-
-logger = logging.getLogger(__name__)
-
-
-@funcy.log_calls(logger.debug, errors=True)
-@singledispatch
-def parse_params(params):
-    if not params:
-        return
-    else:
-        raise ValueError('params must be dict or list')
diff --git a/hive/sbds/jsonrpc.py b/hive/sbds/jsonrpc.py
deleted file mode 100644
index 71ee3826b..000000000
--- a/hive/sbds/jsonrpc.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# -*- coding: utf-8 -*-
-import bottle
-import funcy
-from bottle import request
-from hive.sbds.input_parsers import parse_params
-
-jsonrpc_error_code_map = {
-    'parse_error': {
-        'code': -32700,
-        'message': 'Parse error'
-    },
-    'invalid_request': {
-        'code': -32600,
-        'message': 'Invalid Request'
-    },
-    'method_not_found': {
-        'code': -32601,
-        'message': 'Method not found'
-    },
-    'invalid_params': {
-        'code': -32602,
-        'message': 'Invalid params'
-    },
-    'internal_error': {
-        'code': -32603,
-        'message': 'Internal error'
-    },
-}
-
-
-def generate_json_rpc_error(code, data=None):
-    error_dict = dict(jsonrpc_error_code_map[code])
-    if data:
-        error_dict.update(data=data)
-    return error_dict
-
-
-def error(code, req_id, data=None):
-    json_rpc_error = generate_json_rpc_error(code, data=data)
-    json_rpc_error_dict = {
-        'jsonrpc': '2.0',
-        'id': req_id,
-        'error': json_rpc_error
-    }
-    return json_rpc_error_dict
-
-
-class JSONRPC(object):
-    def __init__(self, path, app, namespace):
-
-        self.path = path
-        self.app = app
-        self.methods = {}
-        self.logger = app.config['hive.logger']
-        self.namespace = namespace
-        self.make_endpoint()
-
-    # pylint: disable=unused-variable, too-many-return-statements,unsubscriptable-object,assignment-from-none
-    def make_endpoint(self):
-        @funcy.log_calls(self.logger.debug, errors=True)
-        @self.app.post(self.path)
-        def rpc():
-            if not request.json:
-                self.logger.error('Parse Error, Not JSON', extra=request.body.read())
-                return error('parse_error', 0)
-
-            # parse json-rpc request envelope and params
-            try:
-                json_rpc_request = request.json
-                json_rpc_version = json_rpc_request['jsonrpc']
-                json_rpc_method = json_rpc_request['method']
-                json_rpc_id = json_rpc_request['id']
-            except KeyError as e:
-                data = 'Bad or missing json-rpc field %s' % e
-                return error('invalid_request',
-                             json_rpc_request.get('id', 'missing'), data)
-            except AssertionError:
-                return error(
-                    'invalid_request',
-                    json_rpc_request.get('id', 'missing'),
-                    data='jsonrpc version must equal "2.0"')
-            # unanticipated errors should be logged with more detail
-            except Exception as e:
-                self.logger.exception(e)
-                return error('internal_error', 'missing')
-
-            # parse json-rpc params
-            try:
-                # pylint: disable=no-member
-                params = parse_params(json_rpc_request.get('params', None))
-            except ValueError as e:
-                data = 'Bad or missing json-rpc param %s' % e
-                return error('invalid_params', json_rpc_id, data)
-            # unanticipated errors should be logged with more detail
-            except Exception as e:
-                self.logger.exception(e)
-                return error('internal_error', json_rpc_id)
-
-            # lookup json-rpc method
-            try:
-                func = self.methods[json_rpc_method]
-            except KeyError as e:
-                data = 'Bad json-rpc method %s' % e
-                return error('method_not_found', json_rpc_id, data)
-            except Exception as e:
-                self.logger.exception(e)
-                return error('internal_error', json_rpc_id)
-
-            # execute json-rpc method
-            try:
-                result = func(bottle, self.app, params)
-                return {'jsonrpc': '2.0', 'id': json_rpc_id, 'result': result}
-            except Exception as e:
-                self.logger.exception(e)
-                return error('internal_error', json_rpc_id)
-
-    def register_method(self, method=None, method_name=None):
-        method_name = method_name or method.__name__
-        namespaced_method_name = self.namespaced_method(method_name)
-        self.methods[namespaced_method_name] = method
-        self.logger.debug('registered method %s under namespace %s as %s',
-                          method_name, self.namespace, namespaced_method_name)
-
-    def namespaced_method(self, method_name):
-        if method_name.startswith('%s.' % self.namespace):
-            return method_name
-        else:
-            return '.'.join([self.namespace, method_name])
-
-    def __call__(self, func):
-        self.methods[func.__name__] = func
-        self.logger.debug('registered methods: %s', self.methods.keys())
-
-
-# pylint: disable=invalid-name
-register_endpoint = JSONRPC
diff --git a/hive/sbds/sbds_json.py b/hive/sbds/sbds_json.py
deleted file mode 100644
index 49d52c13a..000000000
--- a/hive/sbds/sbds_json.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-import json
-from functools import partial
-
-
-class ToStringJSONEncoder(json.JSONEncoder):
-    """This encoder handles date, time, datetime, timedelta, and anything else
-    with a __str__ method"""
-
-    # pylint: disable=method-hidden
-    def default(self, obj):
-        # pylint: disable=bare-except
-        try:
-            return str(obj)
-        except:
-            return super(ToStringJSONEncoder, self).default(obj)
-
-    # pylint: enable=method-hidden
-
-
-dump = partial(json.dump, cls=ToStringJSONEncoder)
-dumps = partial(json.dumps, cls=ToStringJSONEncoder)
-load = json.load
-loads = json.loads
diff --git a/hive/server/__init__.py b/hive/server/__init__.py
index 98c8515fb..8b1378917 100644
--- a/hive/server/__init__.py
+++ b/hive/server/__init__.py
@@ -1,4 +1 @@
-# put in function to import at runtime, avoiding db config/creation on import
-def lazy_load_dev_server():
-    from .serve import _dev_server
-    return _dev_server
+
diff --git a/hive/server/cli.py b/hive/server/cli.py
index 667182392..8b1378917 100644
--- a/hive/server/cli.py
+++ b/hive/server/cli.py
@@ -1,28 +1 @@
-# -*- coding: utf-8 -*-
-import click
-import logging
 
-from hive.server import lazy_load_dev_server
-
-logger = logging.getLogger(__name__)
-
-
-@click.group()
-def server():
-    """HTTP server for answering DB queries"""
-    pass
-
-
-# Development server
-@server.command(name='dev-server')
-@click.option(
-    '--port',
-    type=click.INT,
-    default=8080,
-    help='localhost TCP port for server')
-@click.option('--no_debug', is_flag=True)
-def dev_server_command(port, no_debug):
-    """development server"""
-    debug = not no_debug
-    dev_server = lazy_load_dev_server()
-    dev_server(port, debug)
diff --git a/hive/server/methods.py b/hive/server/methods.py
deleted file mode 100644
index fea856e09..000000000
--- a/hive/server/methods.py
+++ /dev/null
@@ -1,36 +0,0 @@
-from hive.db.methods import (
-    get_followers,
-    get_following,
-    following_count,
-    follower_count,
-)
-
-
-# follow plugin
-# -------------
-def api_get_followers(bottle, app, params):
-    _ = bottle, app
-    return get_followers(
-        account=params.get('account'),
-        skip=params.get('skip'),
-        limit=params.get('limit'),
-    )
-
-
-def api_get_following(bottle, app, params):
-    _ = bottle, app
-    return get_following(
-        account=params.get('account'),
-        skip=params.get('skip'),
-        limit=params.get('limit'),
-    )
-
-
-def api_get_follow_count(bottle, app, params):
-    _ = bottle, app
-    return following_count(params.get('account'))
-
-
-def api_get_follower_count(bottle, app, params):
-    _ = bottle, app
-    return follower_count(params.get('account'))
diff --git a/hive/server/serve.py b/hive/server/serve.py
index c965b539e..6c9bb8477 100644
--- a/hive/server/serve.py
+++ b/hive/server/serve.py
@@ -1,21 +1,17 @@
 # -*- coding: utf-8 -*-
-import json
 import logging
-import os
 from datetime import datetime
 
-import bottle
-import hive.server.methods as rpcmethods
-from bottle import abort, request
-from bottle_errorsrest import ErrorsRestPlugin
-from bottle_sqlalchemy import Plugin
-from hive.db.schema import metadata as hive_metadata
-#from hive.indexer.core import db_last_block, head_state
-from hive.sbds.jsonrpc import register_endpoint
-from hive.sbds.sbds_json import ToStringJSONEncoder
-from sqlalchemy import create_engine
-
+import sqlalchemy as sa
+from sqlalchemy.engine.url import make_url
+from aiohttp import web
+from aiomysql.sa import create_engine
+from jsonrpcserver.aio import methods
+from jsonrpcserver import config
+config.debug = True
 
+logging.basicConfig(level=logging.DEBUG)
+logger = logging.getLogger(__name__)
 
 from hive.db.methods import (
     db_head_state,
@@ -28,119 +24,80 @@ from hive.db.methods import (
     get_discussions_by_sort_and_tag,
     get_related_posts,
     payouts_total,
-    payouts_last_24h,
+    payouts_last_24h
 )
 
+jrpc_methods = (
+    db_head_state,
+    get_followers,
+    get_following,
+    following_count,
+    follower_count,
+    get_user_feed,
+    get_blog_feed,
+    get_discussions_by_sort_and_tag,
+    get_related_posts,
+    payouts_total,
+    payouts_last_24h
+)
 
-logger = logging.getLogger(__name__)
+for m in jrpc_methods:
+    methods.add(m)
+
+app = web.Application()
+app['config'] = dict()
 
-app = bottle.Bottle()
-app.config['hive.MAX_BLOCK_NUM_DIFF'] = 10
-app.config['hive.MAX_DB_ROW_RESULTS'] = 100000
-app.config['hive.DB_QUERY_LIMIT'] = app.config['hive.MAX_DB_ROW_RESULTS'] + 1
-app.config['hive.logger'] = logger
+app['config']['hive.MAX_BLOCK_NUM_DIFF'] = 10
+app['config']['hive.MAX_DB_ROW_RESULTS'] = 100000
+app['config']['hive.DB_QUERY_LIMIT'] = app['config']['hive.MAX_DB_ROW_RESULTS'] + 1
+app['config']['hive.logger'] = logger
 
-app.install(
-    bottle.JSONPlugin(json_dumps=lambda s: json.dumps(s, cls=ToStringJSONEncoder)))
-app.install(ErrorsRestPlugin())
+async def init_db(app):
+    args = app['config']['args']
+    db = make_url(args.database_url)
+    engine = await create_engine(user=db.username,
+                                 db=db.database,
+                                 password=db.password,
+                                 host=db.host,
+                                 port=db.port,
+                                 **db.query)
+    app['db'] = engine
+
+async def close_db(app):
+    app['db'].close()
+    await app['db'].wait_closed()
 
 
 # Non JSON-RPC routes
 # -------------------
-@app.get('/health')
-def health():
+async def health(request):
     state = db_head_state()
-    if state['db_head_age'] > app.config['hive.MAX_BLOCK_NUM_DIFF'] * 3:
-        abort(
-            500,
-            'head block age (%s) > max allowable (%s); head block num: %s'
-            % (state['db_head_age'], app.config['hive.MAX_BLOCK_NUM_DIFF'] * 3,
-                state['db_head_block']))
+    if state['db_head_age'] > app['config']['hive.MAX_BLOCK_NUM_DIFF'] * 3:
+        return web.json_response(data=dict(result='head block age (%s) > max allowable (%s); head block num: %s' % (
+            state['db_head_age'],
+            app['config']['hive.MAX_BLOCK_NUM_DIFF'] * 3,
+            state['db_head_block'])), status=500)
     else:
-        return dict(
-            state=state,
-            timestamp=datetime.utcnow().isoformat())
-
-#@app.get('/head_state')
-#def callback():
-#    return head_state()
-
-@app.get('/stats/payouts')
-def callback():
-    return dict(total = payouts_total(), last_24h = payouts_last_24h())
-
-
-# discussions
-# -----------
-
-def get_context():
-    if 'context' in request.query:
-        return request.query['context']
-
-@app.get('/blog/<user>/<skip>')
-def callback(user, skip):
-    return dict(user = user, posts = get_blog_feed(user, int(skip), 20, get_context()))
-
-@app.get('/feed/<user>/<skip>')
-def callback(user, skip):
-    return dict(user = user, posts = get_user_feed(user, int(skip), 20, get_context()))
-
-@app.get('/discussions/sort/<sort>/<skip>')
-def callback(sort, skip):
-    return dict(posts = get_discussions_by_sort_and_tag(sort, None, int(skip), 20, get_context()))
-
-@app.get('/discussions/tag/<tag>/sort/<sort>/<skip>')
-def callback(tag, sort, skip):
-    return dict(posts = get_discussions_by_sort_and_tag(sort, tag, int(skip), 20, get_context()))
-
-@app.get('/related/<account>/<permlink>')
-def callback(account, permlink):
-    return dict(posts = get_related_posts(account, permlink))
-
-
-# follows
-# -------
-
-@app.get('/followers/<user>')
-def callback(user):
-    return dict(user = user, followers = get_followers(user))
-
-@app.get('/followers/<user>/<skip>/<limit>')
-def callback(user, skip, limit):
-    return dict(user = user, followers = get_followers(user, skip, limit))
-
-
-
-# JSON-RPC route
-# --------------
-jsonrpc = register_endpoint(path='/', app=app, namespace='hive')
+        return web.json_response(data=dict(state=state, timestamp=datetime.utcnow().isoformat()))
 
-json_rpc_methods = {
-#    'head_state': head_state,
-    'get_followers': rpcmethods.get_followers,
-    'get_following': rpcmethods.get_following,
-}
-for method_name, fn_call in json_rpc_methods.items():
-    jsonrpc.register_method(method=fn_call, method_name=method_name)
 
-# WSGI application
-# ----------------
-application = app
+async def jsonrpc_handler(request):
+    request = await request.text()
+    response = await methods.dispatch(request)
+    return web.json_response(response, status=200)
 
 
-# dev/debug server
-# ----------------
-def _dev_server(port=8081, debug=True):
-    # pylint: disable=bare-except
-    try:
-        print("Launch hive server.")
-        app.run(port=port, debug=debug)
-    except:
-        logger.exception('HTTP Server Exception')
-    finally:
-        app.close()
+app.on_startup.append(init_db)
+app.on_cleanup.append(close_db)
+app.router.add_get('/health', health)
+app.router.add_post('/', jsonrpc_handler)
 
 
-# For pdb debug only
 if __name__ == '__main__':
-    _dev_server()
+    import argparse
+    parser = argparse.ArgumentParser(description="hivemind jsonrpc server")
+    parser.add_argument('--database_url',type=str, default='mysql://root:root_password@127.0.0.1:3306/testdb')
+    parser.add_argument('--port', type=int, default=9000)
+    args = parser.parse_args()
+    app['config']['args'] = args
+    web.run_app(app, port=args.port)
diff --git a/service/hive-indexer/run b/service/hive-indexer/run
old mode 100644
new mode 100755
index d4eb13d52..c54c312c7
--- a/service/hive-indexer/run
+++ b/service/hive-indexer/run
@@ -2,4 +2,4 @@
 
 POPULATE_CMD="$(which hive)"
 
-exec python3.5 -u "${POPULATE_CMD}" indexer run
+exec "${POPULATE_CMD}" indexer run
diff --git a/service/hive-web/run b/service/hive-web/run
old mode 100644
new mode 100755
index b1760827c..817a5455b
--- a/service/hive-web/run
+++ b/service/hive-web/run
@@ -1,11 +1,5 @@
 #!/bin/bash
 
+POPULATE_CMD="$(which hive)"
 
-exec uwsgi \
- --master \
- --http :"${HTTP_SERVER_PORT}" \
- --wsgi-file "${WSGI_APP}" \
- --processes "${HTTP_SERVER_PROCESSES:-8}" \
- --threads "${HTTP_SERVER_THREADS:-1}" \
- --stats 0.0.0.0:"${HTTP_SERVER_STATS_PORT}" \
- --stats-http
+python3 /app/hive/server/serve.py --database_url="${DATABASE_URL}" --port="${HTTP_SERVER_PORT}"
diff --git a/setup.py b/setup.py
index 261b2262e..9dcd6934c 100644
--- a/setup.py
+++ b/setup.py
@@ -25,9 +25,9 @@ setup(
                    'pytest-console-scripts'],
 
     install_requires=[
-        'bottle',
-        'bottle_sqlalchemy',
-        'bottle_errorsrest',
+        'aiomysql',
+        'jsonrpcserver',
+        'aiohttp',
         'certifi',
         'sqlalchemy',
         'mysqlclient',
@@ -38,7 +38,7 @@ setup(
         'ujson',
         'urllib3',
         'PrettyTable',
-        'progressbar2',
+        'progressbar2'
     ],
     entry_points={
         'console_scripts': [
-- 
GitLab