diff --git a/Dockerfile b/Dockerfile index 832b8027610b8d5c3d9c9f1f1203ca98158fe180..bc88916330dc735fc723f5a9c818617302cffe7c 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 2a0477f709c951ce1d4f9a309dccece6bcf92e52..6190379bdc3152bc521c2f20c4d9eb9e6d079c5b 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 7b54691ee6afbbc405df827687f88edc9cb2b19f..d176ff0af248ab55b7e2dd358ef9f4bf9bb99b6e 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 1689c41f2ced347831b904228830cdfffbedf646..0000000000000000000000000000000000000000 --- 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 f8435839573b9484f42403e3b61599f7bdeff3c6..b4279a9d35a75038a431e3e5d5ec08a70c9832eb 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 04ef4d6c91de344e9a268e7d4920bb832bb2a748..e3eda14d66f361184114e8af60f77e3c593b4148 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 270bd2a106b48b61ca53f9acc48ef4e144306f4f..a9201d7d65ad1e58f78c550feca3c1e47eb31794 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 c663b091cd55a000f90a77406a95c07eaed9db87..e975acc85eb72e0b1396e971bf1ba21a1a2db2c2 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 09864dd936bec99c91bc9868b4a653565659f90f..cbe7899f2ba404bab912c3e8edc015187ac6b5fa 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 08d47fcd974e7eb171de4074922564a4a35e548f..0000000000000000000000000000000000000000 --- 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 71ee3826b26a74a943238735ff00ff2d73ab0f7f..0000000000000000000000000000000000000000 --- 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 49d52c13a891f667adb0eda923502fc4b60000bc..0000000000000000000000000000000000000000 --- 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 98c8515fb3412194b9a27da0b229c01491c18282..8b137891791fe96927ad78e64b0aad7bded08bdc 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 667182392bcef2db7a2225f5df64f587a831206c..8b137891791fe96927ad78e64b0aad7bded08bdc 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 fea856e091658054397b02660a968cd7c2e56ed0..0000000000000000000000000000000000000000 --- 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 c965b539ee610dc1d33e850273d85750870407cf..6c9bb847700c9ee5fd6d9f686b720cfec93d99d5 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 d4eb13d523ab32bf100a8fda7b482b3b12b65742..c54c312c7f9acc179d341d5cc5525a2342a25ddd --- 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 b1760827cf02ce678098eae28a0de81948029d45..817a5455bb76741b0fd62568b3754080ebed7e96 --- 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 261b2262e2abde8b83c5c8856b782e016860ef7d..9dcd6934c3361b6c213d07efdce4a3fc571aea77 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': [