From d9849d43d24277bbaaa6c6b4c865d3313f423c91 Mon Sep 17 00:00:00 2001 From: Stefan Stammberger Date: Mon, 30 Aug 2021 19:55:02 +0200 Subject: [PATCH] refactor: replace Trio with asyncio/uvloop --- Pipfile | 10 +- Pipfile.lock | 352 ++++++++++++++++++-------------- lnbits/__main__.py | 32 +-- lnbits/app.py | 23 +-- lnbits/commands.py | 4 +- lnbits/core/__init__.py | 6 - lnbits/core/services.py | 4 +- lnbits/core/tasks.py | 22 +- lnbits/core/views/api.py | 72 +++---- lnbits/core/views/generic.py | 14 +- lnbits/core/views/public_api.py | 18 +- lnbits/db.py | 12 +- lnbits/tasks.py | 29 +-- lnbits/utils/exchange_rates.py | 13 +- lnbits/wallets/clightning.py | 4 +- lnbits/wallets/lnbits.py | 4 +- lnbits/wallets/lndrest.py | 4 +- lnbits/wallets/lnpay.py | 9 +- lnbits/wallets/lntxbot.py | 4 +- lnbits/wallets/opennode.py | 9 +- lnbits/wallets/spark.py | 4 +- 21 files changed, 332 insertions(+), 317 deletions(-) diff --git a/Pipfile b/Pipfile index 24e580c88..2b8a67f75 100644 --- a/Pipfile +++ b/Pipfile @@ -16,22 +16,20 @@ pyscss = "*" shortuuid = "*" typing-extensions = "*" httpx = "*" -trio = "==0.16.0" sqlalchemy-aio = "*" embit = "*" pyqrcode = "*" pypng = "*" sqlalchemy = "==1.3.23" psycopg2-binary = "*" -fastapi = {ref = "anyio", git = "https://github.com/graingert/fastapi"} -trio-asyncio = "*" -hypercorn = {extras = ["trio"], version = "*"} aiofiles = "*" +asyncio = "*" +fastapi = "*" +uvicorn = {extras = ["standard"], version = "*"} +sse-starlette = "*" [dev-packages] black = "==20.8b1" pytest = "*" pytest-cov = "*" mypy = "latest" -pytest-trio = "*" -trio-typing = "*" diff --git a/Pipfile.lock b/Pipfile.lock index 470cb2bb5..98d92adb6 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "ff9251889371e0cec0eda7eb792e8618ea84f6c7eb85e9b472eacf3d3552c7c4" + "sha256": "e26f678c4b89a86400e0a62396d06e360bfdf1e0f922d474ded200ee1ffde5c4" }, "pipfile-spec": 6, "requires": { @@ -32,13 +32,23 @@ "markers": "python_full_version >= '3.6.2'", "version": "==3.3.0" }, - "async-generator": { + "asgiref": { "hashes": [ - "sha256:01c7bf666359b4967d2cda0000cc2e4af16a0ae098cbffcb8472fb9e8ad6585b", - "sha256:6ebb3d106c12920aaae42ccb6f787ef5eefdcdd166ea3d628fa8476abe712144" + "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9", + "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214" ], - "markers": "python_version >= '3.5'", - "version": "==1.10" + "markers": "python_version >= '3.6'", + "version": "==3.4.1" + }, + "asyncio": { + "hashes": [ + "sha256:83360ff8bc97980e4ff25c964c7bd3923d333d177aa4f7fb736b019f26c7cb41", + "sha256:b62c9157d36187eca799c378e572c969f0da87cd5fc42ca372d92cdb06e7e1de", + "sha256:c46a87b48213d7464f22d9a497b9eef8c1928b68320a2fa94240f969f6fec08c", + "sha256:c4d18b22701821de07bd6aea8b53d21449ec0ec5680645e5317062ea21817d2d" + ], + "index": "pypi", + "version": "==3.4.3" }, "attrs": { "hashes": [ @@ -87,6 +97,14 @@ "markers": "python_version >= '3.5'", "version": "==2.0.4" }, + "click": { + "hashes": [ + "sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a", + "sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6" + ], + "markers": "python_version >= '3.6'", + "version": "==8.0.1" + }, "ecdsa": { "hashes": [ "sha256:5cf31d5b33743abe0dfc28999036c849a69d548f994b535e527ee3cb7f3ef676", @@ -111,8 +129,12 @@ "version": "==9.3.3" }, "fastapi": { - "git": "https://github.com/graingert/fastapi", - "ref": "ada7c747c05c88d37e012d32e97bcc9579f3f006" + "hashes": [ + "sha256:644bb815bae326575c4b2842469fb83053a4b974b82fa792ff9283d17fbbd99d", + "sha256:94d2820906c36b9b8303796fb7271337ec89c74223229e3cfcf056b5a7d59e23" + ], + "index": "pypi", + "version": "==0.68.1" }, "h11": { "hashes": [ @@ -122,22 +144,6 @@ "markers": "python_version >= '3.6'", "version": "==0.12.0" }, - "h2": { - "hashes": [ - "sha256:ac9e293a1990b339d5d71b19c5fe630e3dd4d768c620d1730d355485323f1b25", - "sha256:bb7ac7099dd67a857ed52c815a6192b6b1f5ba6b516237fc24a085341340593d" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==4.0.0" - }, - "hpack": { - "hashes": [ - "sha256:84a076fad3dc9a9f8063ccb8041ef100867b1878b25ef0ee63847a5d53818a6c", - "sha256:fc41de0c63e687ebffde81187a948221294896f6bdc0ae2312708df339430095" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==4.0.0" - }, "httpcore": { "hashes": [ "sha256:b0d16f0012ec88d8cc848f5a55f8a03158405f4bca02ee49bc4ca2c1fda49f3e", @@ -146,6 +152,26 @@ "markers": "python_version >= '3.6'", "version": "==0.13.6" }, + "httptools": { + "hashes": [ + "sha256:01b392a166adcc8bc2f526a939a8aabf89fe079243e1543fd0e7dc1b58d737cb", + "sha256:200fc1cdf733a9ff554c0bb97a4047785cfaad9875307d6087001db3eb2b417f", + "sha256:3ab1f390d8867f74b3b5ee2a7ecc9b8d7f53750bd45714bf1cb72a953d7dfa77", + "sha256:78d03dd39b09c99ec917d50189e6743adbfd18c15d5944392d2eabda688bf149", + "sha256:79dbc21f3612a78b28384e989b21872e2e3cf3968532601544696e4ed0007ce5", + "sha256:80ffa04fe8c8dfacf6e4cef8277347d35b0442c581f5814f3b0cf41b65c43c6e", + "sha256:813871f961edea6cb2fe312f2d9b27d12a51ba92545380126f80d0de1917ea15", + "sha256:94505026be56652d7a530ab03d89474dc6021019d6b8682281977163b3471ea0", + "sha256:a23166e5ae2775709cf4f7ad4c2048755ebfb272767d244e1a96d55ac775cca7", + "sha256:a289c27ccae399a70eacf32df9a44059ca2ba4ac444604b00a19a6c1f0809943", + "sha256:a7594f9a010cdf1e16a58b3bf26c9da39bbf663e3b8d46d39176999d71816658", + "sha256:b08d00d889a118f68f37f3c43e359aab24ee29eb2e3fe96d64c6a2ba8b9d6557", + "sha256:cc9be041e428c10f8b6ab358c6b393648f9457094e1dcc11b4906026d43cd380", + "sha256:d5682eeb10cca0606c4a8286a3391d4c3c5a36f0c448e71b8bd05be4e1694bfb", + "sha256:fd3b8905e21431ad306eeaf56644a68fdd621bf8f3097eff54d0f6bdf7262065" + ], + "version": "==0.2.0" + }, "httpx": { "hashes": [ "sha256:92ecd2c00c688b529eda11cedb15161eaf02dee9116712f621c70d9a40b2cdd0", @@ -154,25 +180,6 @@ "index": "pypi", "version": "==0.19.0" }, - "hypercorn": { - "extras": [ - "trio" - ], - "hashes": [ - "sha256:5ba1e719c521080abd698ff5781a2331e34ef50fc1c89a50960538115a896a9a", - "sha256:8007c10f81566920f8ae12c0e26e146f94ca70506da964b5a727ad610aa1d821" - ], - "index": "pypi", - "version": "==0.11.2" - }, - "hyperframe": { - "hashes": [ - "sha256:0ec6bafd80d8ad2195c4f03aacba3a8265e57bc4cff261e802bf39970ed02a15", - "sha256:ae510046231dc8e9ecb1a6586f63d2347bf4c8905914aa84ba585ae85f28a914" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==6.0.1" - }, "idna": { "hashes": [ "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a", @@ -180,6 +187,14 @@ ], "version": "==3.2" }, + "importlib-metadata": { + "hashes": [ + "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15", + "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1" + ], + "markers": "python_version < '3.8'", + "version": "==4.8.1" + }, "lnurl": { "hashes": [ "sha256:579982fd8c4d25bc84c61c74ec45cb7999fa1fa2426f5d5aeb0160ba333b9c92", @@ -204,14 +219,6 @@ "markers": "python_version >= '3.6'", "version": "==1.1.0" }, - "priority": { - "hashes": [ - "sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa", - "sha256:c965d54f1b8d0d0b19479db3924c7c36cf672dbf2aec92d43fbdaf4492ba18c0" - ], - "markers": "python_full_version >= '3.6.1'", - "version": "==2.0.0" - }, "psycopg2-binary": { "hashes": [ "sha256:0b7dae87f0b729922e06f85f667de7bf16455d411971b2043bbd9577af9d1975", @@ -305,6 +312,40 @@ "markers": "python_version >= '3.5'", "version": "==0.19.0" }, + "pyyaml": { + "hashes": [ + "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf", + "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696", + "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393", + "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77", + "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922", + "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5", + "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8", + "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10", + "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc", + "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018", + "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e", + "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253", + "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347", + "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183", + "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541", + "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb", + "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185", + "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc", + "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db", + "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa", + "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46", + "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122", + "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b", + "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63", + "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df", + "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc", + "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247", + "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6", + "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0" + ], + "version": "==5.4.1" + }, "represent": { "hashes": [ "sha256:026c0de2ee8385d1255b9c2426cd4f03fe9177ac94c09979bc601946c8493aa0", @@ -347,13 +388,6 @@ "markers": "python_version >= '3.5'", "version": "==1.2.0" }, - "sortedcontainers": { - "hashes": [ - "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", - "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0" - ], - "version": "==2.4.0" - }, "sqlalchemy": { "hashes": [ "sha256:040bdfc1d76a9074717a3f43455685f781c581f94472b010cd6c4754754e1862", @@ -406,46 +440,114 @@ "index": "pypi", "version": "==0.16.0" }, - "toml": { + "sse-starlette": { "hashes": [ - "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", - "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f" - ], - "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==0.10.2" - }, - "trio": { - "hashes": [ - "sha256:451ddb27b4e5215e00646fcbb8028d341fccf284e053dc376506a14bb133dbcf", - "sha256:df067dd0560c321af39d412cd81fc3a7d13f55af9150527daab980683e9fcf3c" + "sha256:1c0cc62cc7d021a386dc06a16a9ddc3e2861d19da6bc2e654e65cc111e820456" ], "index": "pypi", - "version": "==0.16.0" + "version": "==0.6.2" }, - "trio-asyncio": { + "starlette": { "hashes": [ - "sha256:824be23b0c678c0df942816cdb57b92a8b94f264fffa89f04626b0ba2d009768", - "sha256:9bf678f83204ba33c395783681c69af563a84145fad2110a152a81a4a18ae7e4" + "sha256:3c8e48e52736b3161e34c9f0e8153b4f32ec5d8995a3ee1d59410d92f75162ed", + "sha256:7d49f4a27f8742262ef1470608c59ddbc66baf37c148e938c7038e6bc7a998aa" ], - "index": "pypi", - "version": "==0.12.0" + "markers": "python_version >= '3.6'", + "version": "==0.14.2" }, "typing-extensions": { "hashes": [ - "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", - "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", - "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" + "sha256:045dd532231acfa03628df5e0c66dba64e2cc8fc8b844538d4ad6d5dd6cb82dc", + "sha256:83af6730a045fda60f46510f7f1f094776d90321caa4d97d20ef38871bef4bd3", + "sha256:8bbffbd37fbeb9747a0241fdfde5ae99d4531ad1d1a41ccaea62100e15a5814c" ], "index": "pypi", - "version": "==3.10.0.0" + "version": "==3.10.0.1" }, - "wsproto": { - "hashes": [ - "sha256:868776f8456997ad0d9720f7322b746bbe9193751b5b290b7f924659377c8c38", - "sha256:d8345d1808dd599b5ffb352c25a367adb6157e664e140dbecba3f9bc007edb9f" + "uvicorn": { + "extras": [ + "standard" ], - "markers": "python_full_version >= '3.6.1'", - "version": "==1.0.0" + "hashes": [ + "sha256:17f898c64c71a2640514d4089da2689e5db1ce5d4086c2d53699bf99513421c1", + "sha256:d9a3c0dd1ca86728d3e235182683b4cf94cd53a867c288eaeca80ee781b2caff" + ], + "index": "pypi", + "version": "==0.15.0" + }, + "uvloop": { + "hashes": [ + "sha256:04ff57aa137230d8cc968f03481176041ae789308b4d5079118331ab01112450", + "sha256:089b4834fd299d82d83a25e3335372f12117a7d38525217c2258e9b9f4578897", + "sha256:1e5f2e2ff51aefe6c19ee98af12b4ae61f5be456cd24396953244a30880ad861", + "sha256:30ba9dcbd0965f5c812b7c2112a1ddf60cf904c1c160f398e7eed3a6b82dcd9c", + "sha256:3a19828c4f15687675ea912cc28bbcb48e9bb907c801873bd1519b96b04fb805", + "sha256:6224f1401025b748ffecb7a6e2652b17768f30b1a6a3f7b44660e5b5b690b12d", + "sha256:647e481940379eebd314c00440314c81ea547aa636056f554d491e40503c8464", + "sha256:6ccd57ae8db17d677e9e06192e9c9ec4bd2066b77790f9aa7dede2cc4008ee8f", + "sha256:772206116b9b57cd625c8a88f2413df2fcfd0b496eb188b82a43bed7af2c2ec9", + "sha256:8e0d26fa5875d43ddbb0d9d79a447d2ace4180d9e3239788208527c4784f7cab", + "sha256:98d117332cc9e5ea8dfdc2b28b0a23f60370d02e1395f88f40d1effd2cb86c4f", + "sha256:b572256409f194521a9895aef274cea88731d14732343da3ecdb175228881638", + "sha256:bd53f7f5db562f37cd64a3af5012df8cac2c464c97e732ed556800129505bd64", + "sha256:bd8f42ea1ea8f4e84d265769089964ddda95eb2bb38b5cbe26712b0616c3edee", + "sha256:e814ac2c6f9daf4c36eb8e85266859f42174a4ff0d71b99405ed559257750382", + "sha256:f74bc20c7b67d1c27c72601c78cf95be99d5c2cdd4514502b4f3eb0933ff1228" + ], + "version": "==0.16.0" + }, + "watchgod": { + "hashes": [ + "sha256:48140d62b0ebe9dd9cf8381337f06351e1f2e70b2203fa9c6eff4e572ca84f29", + "sha256:d6c1ea21df37847ac0537ca0d6c2f4cdf513562e95f77bb93abbcf05573407b7" + ], + "version": "==0.7" + }, + "websockets": { + "hashes": [ + "sha256:0dd4eb8e0bbf365d6f652711ce21b8fd2b596f873d32aabb0fbb53ec604418cc", + "sha256:1d0971cc7251aeff955aa742ec541ee8aaea4bb2ebf0245748fbec62f744a37e", + "sha256:1d6b4fddb12ab9adf87b843cd4316c4bd602db8d5efd2fb83147f0458fe85135", + "sha256:230a3506df6b5f446fed2398e58dcaafdff12d67fe1397dff196411a9e820d02", + "sha256:276d2339ebf0df4f45df453923ebd2270b87900eda5dfd4a6b0cfa15f82111c3", + "sha256:2cf04601633a4ec176b9cc3d3e73789c037641001dbfaf7c411f89cd3e04fcaf", + "sha256:3ddff38894c7857c476feb3538dd847514379d6dc844961dc99f04b0384b1b1b", + "sha256:48c222feb3ced18f3dc61168ca18952a22fb88e5eb8902d2bf1b50faefdc34a2", + "sha256:51d04df04ed9d08077d10ccbe21e6805791b78eac49d16d30a1f1fe2e44ba0af", + "sha256:597c28f3aa7a09e8c070a86b03107094ee5cdafcc0d55f2f2eac92faac8dc67d", + "sha256:5c8f0d82ea2468282e08b0cf5307f3ad022290ed50c45d5cb7767957ca782880", + "sha256:7189e51955f9268b2bdd6cc537e0faa06f8fffda7fb386e5922c6391de51b077", + "sha256:7df3596838b2a0c07c6f6d67752c53859a54993d4f062689fdf547cb56d0f84f", + "sha256:826ccf85d4514609219725ba4a7abd569228c2c9f1968e8be05be366f68291ec", + "sha256:836d14eb53b500fd92bd5db2fc5894f7c72b634f9c2a28f546f75967503d8e25", + "sha256:85db8090ba94e22d964498a47fdd933b8875a1add6ebc514c7ac8703eb97bbf0", + "sha256:85e701a6c316b7067f1e8675c638036a796fe5116783a4c932e7eb8e305a3ffe", + "sha256:900589e19200be76dd7cbaa95e9771605b5ce3f62512d039fb3bc5da9014912a", + "sha256:9147868bb0cc01e6846606cd65cbf9c58598f187b96d14dd1ca17338b08793bb", + "sha256:9e7fdc775fe7403dbd8bc883ba59576a6232eac96dacb56512daacf7af5d618d", + "sha256:ab5ee15d3462198c794c49ccd31773d8a2b8c17d622aa184f669d2b98c2f0857", + "sha256:ad893d889bc700a5835e0a95a3e4f2c39e91577ab232a3dc03c262a0f8fc4b5c", + "sha256:b2e71c4670ebe1067fa8632f0d081e47254ee2d3d409de54168b43b0ba9147e0", + "sha256:b43b13e5622c5a53ab12f3272e6f42f1ce37cd5b6684b2676cb365403295cd40", + "sha256:b4ad84b156cf50529b8ac5cc1638c2cf8680490e3fccb6121316c8c02620a2e4", + "sha256:be5fd35e99970518547edc906efab29afd392319f020c3c58b0e1a158e16ed20", + "sha256:caa68c95bc1776d3521f81eeb4d5b9438be92514ec2a79fececda814099c8314", + "sha256:d144b350045c53c8ff09aa1cfa955012dd32f00c7e0862c199edcabb1a8b32da", + "sha256:d2c2d9b24d3c65b5a02cac12cbb4e4194e590314519ed49db2f67ef561c3cf58", + "sha256:e9e5fd6dbdf95d99bc03732ded1fc8ef22ebbc05999ac7e0c7bf57fe6e4e5ae2", + "sha256:ebf459a1c069f9866d8569439c06193c586e72c9330db1390af7c6a0a32c4afd", + "sha256:f31722f1c033c198aa4a39a01905951c00bd1c74f922e8afc1b1c62adbcdd56a", + "sha256:f68c352a68e5fdf1e97288d5cec9296664c590c25932a8476224124aaf90dbcd" + ], + "version": "==9.1" + }, + "zipp": { + "hashes": [ + "sha256:957cfda87797e389580cb8b9e3870841ca991e2125350677b2ca83a0e99390a3", + "sha256:f5812b1e007e48cff63449a5e9f4e7ebea716b4111f9c4f9a645f91d579bf0c4" + ], + "markers": "python_version >= '3.6'", + "version": "==3.5.0" } }, "develop": { @@ -456,14 +558,6 @@ ], "version": "==1.4.4" }, - "async-generator": { - "hashes": [ - "sha256:01c7bf666359b4967d2cda0000cc2e4af16a0ae098cbffcb8472fb9e8ad6585b", - "sha256:6ebb3d106c12920aaae42ccb6f787ef5eefdcdd166ea3d628fa8476abe712144" - ], - "markers": "python_version >= '3.5'", - "version": "==1.10" - }, "attrs": { "hashes": [ "sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", @@ -545,20 +639,13 @@ "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'", "version": "==5.5" }, - "idna": { - "hashes": [ - "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a", - "sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3" - ], - "version": "==3.2" - }, "importlib-metadata": { "hashes": [ - "sha256:9e04bf59076a15a9b6dd9c27806e8fcdf15280ba529c6a8cc3f4d5b4875bdd61", - "sha256:c4eb3dec5f697682e383a39701a7de11cd5c02daf8dd93534b69e3e6473f6b1b" + "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15", + "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1" ], "markers": "python_version < '3.8'", - "version": "==4.7.1" + "version": "==4.8.1" }, "iniconfig": { "hashes": [ @@ -603,14 +690,6 @@ ], "version": "==0.4.3" }, - "outcome": { - "hashes": [ - "sha256:c7dd9375cfd3c12db9801d080a3b63d4b0a261aa996c4c13152380587288d958", - "sha256:e862f01d4e626e63e8f92c38d1f8d5546d3f9cce989263c521b2e7990d186967" - ], - "markers": "python_version >= '3.6'", - "version": "==1.1.0" - }, "packaging": { "hashes": [ "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7", @@ -666,15 +745,9 @@ "index": "pypi", "version": "==2.12.1" }, - "pytest-trio": { - "hashes": [ - "sha256:c01b741819aec2c419555f28944e132d3c711dae1e673d63260809bf92c30c31" - ], - "index": "pypi", - "version": "==0.7.0" - }, "regex": { "hashes": [ + "sha256:04f6b9749e335bb0d2f68c707f23bb1773c3fb6ecd10edf0f04df12a8920d468", "sha256:08d74bfaa4c7731b8dac0a992c63673a2782758f7cfad34cf9c1b9184f911354", "sha256:0fc1f8f06977c2d4f5e3d3f0d4a08089be783973fc6b6e278bde01f0544ff308", "sha256:121f4b3185feaade3f85f70294aef3f777199e9b5c0c0245c774ae884b110a2d", @@ -694,12 +767,15 @@ "sha256:8e44769068d33e0ea6ccdf4b84d80c5afffe5207aa4d1881a629cf0ef3ec398f", "sha256:999ad08220467b6ad4bd3dd34e65329dd5d0df9b31e47106105e407954965256", "sha256:9b006628fe43aa69259ec04ca258d88ed19b64791693df59c422b607b6ece8bb", + "sha256:9d05ad5367c90814099000442b2125535e9d77581855b9bee8780f1b41f2b1a2", "sha256:a577a21de2ef8059b58f79ff76a4da81c45a75fe0bfb09bc8b7bb4293fa18983", "sha256:a617593aeacc7a691cc4af4a4410031654f2909053bd8c8e7db837f179a630eb", "sha256:abb48494d88e8a82601af905143e0de838c776c1241d92021e9256d5515b3645", "sha256:ac88856a8cbccfc14f1b2d0b829af354cc1743cb375e7f04251ae73b2af6adf8", + "sha256:b4c220a1fe0d2c622493b0a1fd48f8f991998fb447d3cd368033a4b86cf1127a", "sha256:b844fb09bd9936ed158ff9df0ab601e2045b316b17aa8b931857365ea8586906", "sha256:bdc178caebd0f338d57ae445ef8e9b737ddf8fbc3ea187603f65aec5b041248f", + "sha256:c206587c83e795d417ed3adc8453a791f6d36b67c81416676cad053b4104152c", "sha256:c61dcc1cf9fd165127a2853e2c31eb4fb961a4f26b394ac9fe5669c7a6592892", "sha256:c7cb4c512d2d3b0870e00fbbac2f291d4b4bf2634d59a31176a87afe2777c6f0", "sha256:d4a332404baa6665b54e5d283b4262f41f2103c255897084ec8f5487ce7b9e8e", @@ -707,6 +783,7 @@ "sha256:e1e8406b895aba6caa63d9fd1b6b1700d7e4825f78ccb1e5260551d168db38ed", "sha256:e8690ed94481f219a7a967c118abaf71ccc440f69acd583cab721b90eeedb77c", "sha256:ed283ab3a01d8b53de3a05bfdf4473ae24e43caee7dcb5584e86f3f3e5ab4374", + "sha256:ed4b50355b066796dacdd1cf538f2ce57275d001838f9b132fab80b75e8c84dd", "sha256:ee329d0387b5b41a5dddbb6243a21cb7896587a651bebb957e2d2bb8b63c0791", "sha256:f3bf1bc02bc421047bfec3343729c4bbbea42605bcfd6d6bfe2c07ade8b12d2a", "sha256:f585cbbeecb35f35609edccb95efd95a3e35824cd7752b586503f7e6087303f1", @@ -714,21 +791,6 @@ ], "version": "==2021.8.28" }, - "sniffio": { - "hashes": [ - "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663", - "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de" - ], - "markers": "python_version >= '3.5'", - "version": "==1.2.0" - }, - "sortedcontainers": { - "hashes": [ - "sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88", - "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0" - ], - "version": "==2.4.0" - }, "toml": { "hashes": [ "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", @@ -737,22 +799,6 @@ "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "version": "==0.10.2" }, - "trio": { - "hashes": [ - "sha256:451ddb27b4e5215e00646fcbb8028d341fccf284e053dc376506a14bb133dbcf", - "sha256:df067dd0560c321af39d412cd81fc3a7d13f55af9150527daab980683e9fcf3c" - ], - "index": "pypi", - "version": "==0.16.0" - }, - "trio-typing": { - "hashes": [ - "sha256:3eae317514ca18af158bd14ec55ccf20e8b1461efc3a431b87c337a9ca97180b", - "sha256:c3717f097eab29f8deb58a6976da366bd98adb81d90f38002b564932839eaa84" - ], - "index": "pypi", - "version": "==0.5.1" - }, "typed-ast": { "hashes": [ "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace", @@ -791,12 +837,12 @@ }, "typing-extensions": { "hashes": [ - "sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", - "sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", - "sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" + "sha256:045dd532231acfa03628df5e0c66dba64e2cc8fc8b844538d4ad6d5dd6cb82dc", + "sha256:83af6730a045fda60f46510f7f1f094776d90321caa4d97d20ef38871bef4bd3", + "sha256:8bbffbd37fbeb9747a0241fdfde5ae99d4531ad1d1a41ccaea62100e15a5814c" ], "index": "pypi", - "version": "==3.10.0.0" + "version": "==3.10.0.1" }, "zipp": { "hashes": [ diff --git a/lnbits/__main__.py b/lnbits/__main__.py index bd564787d..186b29014 100644 --- a/lnbits/__main__.py +++ b/lnbits/__main__.py @@ -1,28 +1,21 @@ -from hypercorn.trio import serve -import trio -import trio_asyncio -from hypercorn.config import Config +import asyncio -from .commands import migrate_databases, transpile_scss, bundle_vendored +import uvloop +from starlette.requests import Request -trio.run(migrate_databases) +from .commands import bundle_vendored, migrate_databases, transpile_scss +from .settings import (DEBUG, LNBITS_COMMIT, LNBITS_DATA_FOLDER, + LNBITS_SITE_TITLE, PORT, SERVICE_FEE, WALLET) + +uvloop.install() + +asyncio.create_task(migrate_databases()) transpile_scss() bundle_vendored() from .app import create_app -app = trio.run(create_app) - -from .settings import ( - LNBITS_SITE_TITLE, - SERVICE_FEE, - DEBUG, - LNBITS_DATA_FOLDER, - WALLET, - LNBITS_COMMIT, - HOST, - PORT -) +app = create_app() print( f"""Starting LNbits with @@ -35,6 +28,3 @@ print( """ ) -config = Config() -config.bind = [f"{HOST}:{PORT}"] -trio_asyncio.run(serve, app, config) diff --git a/lnbits/app.py b/lnbits/app.py index 177785bf4..7e53c0e14 100644 --- a/lnbits/app.py +++ b/lnbits/app.py @@ -1,9 +1,10 @@ +import asyncio import importlib +from lnbits.core.tasks import register_task_listeners import sys import traceback import warnings -import trio from fastapi import FastAPI, Request from fastapi.exceptions import RequestValidationError from fastapi.middleware.cors import CORSMiddleware @@ -19,11 +20,11 @@ from .helpers import (get_css_vendored, get_js_vendored, get_valid_extensions, template_renderer, url_for_vendored) from .requestvars import g from .settings import WALLET -from .tasks import (check_pending_payments, internal_invoice_listener, +from .tasks import (catch_everything_and_restart, check_pending_payments, internal_invoice_listener, invoice_listener, run_deferred_async, webhook_handler) -async def create_app(config_object="lnbits.settings") -> FastAPI: +def create_app(config_object="lnbits.settings") -> FastAPI: """Create application factory. :param config_object: The configuration object to use. """ @@ -128,16 +129,12 @@ def register_async_tasks(app): @app.on_event("startup") async def listeners(): - run_deferred_async() - trio.open_process(check_pending_payments) - trio.open_process(invoice_listener) - trio.open_process(internal_invoice_listener) - - async with trio.open_nursery() as n: - pass - # n.start_soon(catch_everything_and_restart, check_pending_payments) - # n.start_soon(catch_everything_and_restart, invoice_listener) - # n.start_soon(catch_everything_and_restart, internal_invoice_listener) + loop = asyncio.get_event_loop() + loop.create_task(catch_everything_and_restart(check_pending_payments)) + loop.create_task(catch_everything_and_restart(invoice_listener)) + loop.create_task(catch_everything_and_restart(internal_invoice_listener)) + await register_task_listeners() + await run_deferred_async() @app.on_event("shutdown") async def stop_listeners(): diff --git a/lnbits/commands.py b/lnbits/commands.py index 021d26dcd..0a48e05f9 100644 --- a/lnbits/commands.py +++ b/lnbits/commands.py @@ -1,4 +1,4 @@ -import trio +import asyncio import warnings import click import importlib @@ -18,7 +18,7 @@ from .settings import LNBITS_PATH @click.command("migrate") def db_migrate(): - trio.run(migrate_databases) + asyncio.create_task(migrate_databases()) @click.command("assets") diff --git a/lnbits/core/__init__.py b/lnbits/core/__init__.py index d988d5731..e632fba83 100644 --- a/lnbits/core/__init__.py +++ b/lnbits/core/__init__.py @@ -6,14 +6,8 @@ db = Database("database") core_app: APIRouter = APIRouter() -from lnbits.tasks import record_async - -from .tasks import register_listeners from .views.api import * # noqa from .views.generic import * # noqa from .views.public_api import * # noqa -@core_app.on_event("startup") -def do_startup(): - record_async(register_listeners) diff --git a/lnbits/core/services.py b/lnbits/core/services.py index 4fa75f9d9..ee83b3389 100644 --- a/lnbits/core/services.py +++ b/lnbits/core/services.py @@ -1,4 +1,4 @@ -import trio +import asyncio import json import httpx from io import BytesIO @@ -211,7 +211,7 @@ async def redeem_lnurl_withdraw( return None if wait_seconds: - await trio.sleep(wait_seconds) + await asyncio.sleep(wait_seconds) params = { "k1": res["k1"], diff --git a/lnbits/core/tasks.py b/lnbits/core/tasks.py index fa2df9645..c75fbac84 100644 --- a/lnbits/core/tasks.py +++ b/lnbits/core/tasks.py @@ -1,4 +1,4 @@ -import trio +import asyncio import httpx from typing import List @@ -8,17 +8,19 @@ from . import db from .crud import get_balance_notify from .models import Payment -api_invoice_listeners: List[trio.MemorySendChannel] = [] +api_invoice_listeners: List[asyncio.Queue] = [] -async def register_listeners(): - invoice_paid_chan_send, invoice_paid_chan_recv = trio.open_memory_channel(5) - register_invoice_listener(invoice_paid_chan_send) - await wait_for_paid_invoices(invoice_paid_chan_recv) +async def register_task_listeners(): + invoice_paid_queue = asyncio.Queue(5) + register_invoice_listener(invoice_paid_queue) + asyncio.create_task(wait_for_paid_invoices(invoice_paid_queue)) -async def wait_for_paid_invoices(invoice_paid_chan: trio.MemoryReceiveChannel): - async for payment in invoice_paid_chan: +async def wait_for_paid_invoices(invoice_paid_queue: asyncio.Queue): + while True: + payment = await invoice_paid_queue.get() + # send information to sse channel await dispatch_invoice_listener(payment) @@ -43,8 +45,8 @@ async def wait_for_paid_invoices(invoice_paid_chan: trio.MemoryReceiveChannel): async def dispatch_invoice_listener(payment: Payment): for send_channel in api_invoice_listeners: try: - send_channel.send_nowait(payment) - except trio.WouldBlock: + send_channel.put_nowait(payment) + except asyncio.QueueFull: print("removing sse listener", send_channel) api_invoice_listeners.remove(send_channel) diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index f277e6cc4..12c3e0a79 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -1,3 +1,4 @@ +import asyncio import hashlib import json from binascii import unhexlify @@ -6,15 +7,15 @@ from typing import Dict, Optional, Union from urllib.parse import ParseResult, parse_qs, urlencode, urlparse, urlunparse import httpx -import trio -from fastapi import Query, security +from fastapi import Query, Request from fastapi.exceptions import HTTPException from fastapi.param_functions import Depends from fastapi.params import Body +from sse_starlette.sse import EventSourceResponse from pydantic import BaseModel from lnbits import bolt11, lnurl -from lnbits.core.models import Wallet +from lnbits.core.models import Payment, Wallet from lnbits.decorators import (WalletAdminKeyChecker, WalletInvoiceKeyChecker, WalletTypeInfo, get_key_type) from lnbits.helpers import url_for @@ -251,57 +252,42 @@ async def api_payments_pay_lnurl(data: CreateLNURLData): HTTPStatus.CREATED, ) -@core_app.get("/api/v1/payments/sse") -async def api_payments_sse(wallet: WalletTypeInfo = Depends(get_key_type)): +async def subscribe(request: Request, wallet: Wallet): this_wallet_id = wallet.wallet.id - send_payment, receive_payment = trio.open_memory_channel(0) + payment_queue = asyncio.Queue(0) - print("adding sse listener", send_payment) - api_invoice_listeners.append(send_payment) + print("adding sse listener", payment_queue) + api_invoice_listeners.append(payment_queue) - send_event, event_to_send = trio.open_memory_channel(0) + send_queue = asyncio.Queue(0) async def payment_received() -> None: - async for payment in receive_payment: - if payment.wallet_id == this_wallet_id: - await send_event.send(("payment-received", payment)) - - async def repeat_keepalive(): - await trio.sleep(1) while True: - await send_event.send(("keepalive", "")) - await trio.sleep(25) + payment: Payment = await payment_queue.get() + if payment.wallet_id == this_wallet_id: + await send_queue.put(("payment-received", payment)) - async with trio.open_nursery() as nursery: - nursery.start_soon(payment_received) - nursery.start_soon(repeat_keepalive) - - async def send_events(): - try: - async for typ, data in event_to_send: - message = [f"event: {typ}".encode("utf-8")] + asyncio.create_task(payment_received()) - if data: - jdata = json.dumps(dict(data._asdict(), pending=False)) - message.append(f"data: {jdata}".encode("utf-8")) + try: + while True: + typ, data = await send_queue.get() + message = [f"event: {typ}".encode("utf-8")] - yield b"\n".join(message) + b"\r\n\r\n" - except trio.Cancelled: - return + if data: + jdata = json.dumps(dict(data.dict(), pending=False)) + message.append(f"data: {jdata}".encode("utf-8")) + + yield dict(data=jdata.encode("utf-8"), event=typ.encode("utf-8")) + except asyncio.CancelledError: + return + + +@core_app.get("/api/v1/payments/sse") +async def api_payments_sse(request: Request, wallet: WalletTypeInfo = Depends(get_key_type)): + return EventSourceResponse(subscribe(request, wallet)) - response = await make_response( - send_events(), - { - "Content-Type": "text/event-stream", - "Cache-Control": "no-cache", - "X-Accel-Buffering": "no", - "Connection": "keep-alive", - "Transfer-Encoding": "chunked", - }, - ) - response.timeout = None - return response @core_app.get("/api/v1/payments/{payment_hash}") async def api_payment(payment_hash, wallet: WalletTypeInfo = Depends(get_key_type)): diff --git a/lnbits/core/views/generic.py b/lnbits/core/views/generic.py index d628e6990..2e041802f 100644 --- a/lnbits/core/views/generic.py +++ b/lnbits/core/views/generic.py @@ -1,3 +1,5 @@ +import asyncio + from http import HTTPStatus from typing import Optional @@ -9,7 +11,6 @@ from fastapi.responses import FileResponse, RedirectResponse from fastapi.routing import APIRouter from pydantic.types import UUID4 from starlette.responses import HTMLResponse -import trio from lnbits.core import db from lnbits.helpers import template_renderer, url_for @@ -142,8 +143,7 @@ async def lnurl_full_withdraw_callback(request: Request): except: pass - async with trio.open_nursery() as n: - n.start_soon(pay) + asyncio.create_task(pay()) balance_notify = request.args.get("balanceNotify") if balance_notify: @@ -187,14 +187,14 @@ async def lnurlwallet(request: Request): user = await get_user(account.id, conn=conn) wallet = await create_wallet(user_id=user.id, conn=conn) - async with trio.open_nursery() as n: - n.start_soon( - redeem_lnurl_withdraw, + asyncio.create_task( + redeem_lnurl_withdraw( wallet.id, request.args.get("lightning"), "LNbits initial funding: voucher redeem.", {"tag": "lnurlwallet"}, - 5, # wait 5 seconds before sending the invoice to the service + 5 # wait 5 seconds before sending the invoice to the service + ) ) return RedirectResponse(f"/wallet?usr={user.id}&wal={wallet.id}", status_code=status.HTTP_307_TEMPORARY_REDIRECT) diff --git a/lnbits/core/views/public_api.py b/lnbits/core/views/public_api.py index 9cf7b6cf8..027585219 100644 --- a/lnbits/core/views/public_api.py +++ b/lnbits/core/views/public_api.py @@ -1,4 +1,4 @@ -import trio +import asyncio import datetime from http import HTTPStatus @@ -26,27 +26,27 @@ async def api_public_payment_longpolling(payment_hash): except: return {"message": "Invalid bolt11 invoice."}, HTTPStatus.BAD_REQUEST - send_payment, receive_payment = trio.open_memory_channel(0) + payment_queue = asyncio.Queue(0) - print("adding standalone invoice listener", payment_hash, send_payment) - api_invoice_listeners.append(send_payment) + print("adding standalone invoice listener", payment_hash, payment_queue) + api_invoice_listeners.append(payment_queue) response = None async def payment_info_receiver(cancel_scope): - async for payment in receive_payment: + async for payment in payment_queue.get(): if payment.payment_hash == payment_hash: nonlocal response response = ({"status": "paid"}, HTTPStatus.OK) cancel_scope.cancel() async def timeouter(cancel_scope): - await trio.sleep(45) + await asyncio.sleep(45) cancel_scope.cancel() - async with trio.open_nursery() as nursery: - nursery.start_soon(payment_info_receiver, nursery.cancel_scope) - nursery.start_soon(timeouter, nursery.cancel_scope) + + asyncio.create_task(payment_info_receiver()) + asyncio.create_task(timeouter()) if response: return response diff --git a/lnbits/db.py b/lnbits/db.py index f5009463c..6142952dd 100644 --- a/lnbits/db.py +++ b/lnbits/db.py @@ -1,12 +1,12 @@ import os -import trio +import asyncio import time import datetime from typing import Optional from contextlib import asynccontextmanager -from sqlalchemy import create_engine # type: ignore -from sqlalchemy_aio import TRIO_STRATEGY # type: ignore -from sqlalchemy_aio.base import AsyncConnection # type: ignore +from sqlalchemy import create_engine +from sqlalchemy_aio.base import AsyncConnection +from sqlalchemy_aio.strategy import ASYNCIO_STRATEGY # type: ignore from .settings import LNBITS_DATA_FOLDER, LNBITS_DATABASE_URL @@ -132,8 +132,8 @@ class Database(Compat): else: self.schema = None - self.engine = create_engine(database_uri, strategy=TRIO_STRATEGY) - self.lock = trio.StrictFIFOLock() + self.engine = create_engine(database_uri, strategy=ASYNCIO_STRATEGY) + self.lock = asyncio.Lock() @asynccontextmanager async def connect(self): diff --git a/lnbits/tasks.py b/lnbits/tasks.py index b6facd603..ab1ebc46b 100644 --- a/lnbits/tasks.py +++ b/lnbits/tasks.py @@ -1,5 +1,5 @@ import time -import trio +import asyncio import traceback from http import HTTPStatus from typing import List, Callable @@ -24,21 +24,21 @@ def record_async(func: Callable) -> Callable: return recorder -def run_deferred_async(): +async def run_deferred_async(): for func in deferred_async: - current_app.nursery.start_soon(catch_everything_and_restart, func) + asyncio.create_task(catch_everything_and_restart(func)) async def catch_everything_and_restart(func): try: await func() - except trio.Cancelled: + except asyncio.CancelledError: raise # because we must pass this up except Exception as exc: print("caught exception in background task:", exc) print(traceback.format_exc()) print("will restart the task in 5 seconds.") - await trio.sleep(5) + await asyncio.sleep(5) await catch_everything_and_restart(func) @@ -46,10 +46,10 @@ async def send_push_promise(a, b) -> None: pass -invoice_listeners: List[trio.MemorySendChannel] = [] +invoice_listeners: List[asyncio.Queue] = [] -def register_invoice_listener(send_chan: trio.MemorySendChannel): +def register_invoice_listener(send_chan: asyncio.Queue): """ A method intended for extensions to call when they want to be notified about new invoice payments incoming. @@ -64,18 +64,19 @@ async def webhook_handler(): return "", HTTPStatus.NO_CONTENT -internal_invoice_paid, internal_invoice_received = trio.open_memory_channel(0) +internal_invoice_queue = asyncio.Queue(0) async def internal_invoice_listener(): - async for checking_id in internal_invoice_received: - current_app.nursery.start_soon(invoice_callback_dispatcher, checking_id) + while True: + checking_id = await internal_invoice_queue.get() + asyncio.create_task(invoice_callback_dispatcher(checking_id)) async def invoice_listener(): async for checking_id in WALLET.paid_invoices_stream(): print("> got a payment notification", checking_id) - current_app.nursery.start_soon(invoice_callback_dispatcher, checking_id) + asyncio.create_task(invoice_callback_dispatcher(checking_id)) async def check_pending_payments(): @@ -99,7 +100,7 @@ async def check_pending_payments(): # that will be handled by the global invoice listeners, hopefully incoming = False - await trio.sleep(60 * 30) # every 30 minutes + await asyncio.sleep(60 * 30) # every 30 minutes async def perform_balance_checks(): @@ -107,7 +108,7 @@ async def perform_balance_checks(): for bc in await get_balance_checks(): redeem_lnurl_withdraw(bc.wallet, bc.url) - await trio.sleep(60 * 60 * 6) # every 6 hours + await asyncio.sleep(60 * 60 * 6) # every 6 hours async def invoice_callback_dispatcher(checking_id: str): @@ -115,4 +116,4 @@ async def invoice_callback_dispatcher(checking_id: str): if payment and payment.is_in: await payment.set_pending(False) for send_chan in invoice_listeners: - await send_chan.send(payment) + await send_chan.put(payment) diff --git a/lnbits/utils/exchange_rates.py b/lnbits/utils/exchange_rates.py index 801994bef..14e912fcb 100644 --- a/lnbits/utils/exchange_rates.py +++ b/lnbits/utils/exchange_rates.py @@ -1,4 +1,4 @@ -import trio +import asyncio import httpx from typing import Callable, NamedTuple @@ -219,12 +219,12 @@ async def btc_price(currency: str) -> float: "to": currency.lower(), } rates = [] - send_channel, receive_channel = trio.open_memory_channel(0) + send_channel = asyncio.Queue(0) async def controller(nursery): failures = 0 while True: - rate = await receive_channel.receive() + rate = await send_channel.get() if rate: rates.append(rate) else: @@ -248,10 +248,9 @@ async def btc_price(currency: str) -> float: except Exception: await send_channel.send(None) - async with trio.open_nursery() as nursery: - nursery.start_soon(controller, nursery) - for key, provider in exchange_rate_providers.items(): - nursery.start_soon(fetch_price, key, provider) + # asyncio.create_task(controller, nursery) + for key, provider in exchange_rate_providers.items(): + asyncio.create_task(fetch_price(key, provider)) if not rates: return 9999999999 diff --git a/lnbits/wallets/clightning.py b/lnbits/wallets/clightning.py index bd6921938..0780776fc 100644 --- a/lnbits/wallets/clightning.py +++ b/lnbits/wallets/clightning.py @@ -3,7 +3,7 @@ try: except ImportError: # pragma: nocover LightningRpc = None -import trio +import asyncio import random import json @@ -116,7 +116,7 @@ class CLightningWallet(Wallet): raise KeyError("supplied an invalid checking_id") async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: - stream = await trio.open_unix_socket(self.rpc) + stream = await asyncio.open_unix_socket(self.rpc) i = 0 while True: diff --git a/lnbits/wallets/lnbits.py b/lnbits/wallets/lnbits.py index e6ded79d1..b262cb1ed 100644 --- a/lnbits/wallets/lnbits.py +++ b/lnbits/wallets/lnbits.py @@ -1,4 +1,4 @@ -import trio +import asyncio import json import httpx from os import getenv @@ -146,4 +146,4 @@ class LNbitsWallet(Wallet): pass print("lost connection to lnbits /payments/sse, retrying in 5 seconds") - await trio.sleep(5) + await asyncio.sleep(5) diff --git a/lnbits/wallets/lndrest.py b/lnbits/wallets/lndrest.py index c0310e772..4b31c7260 100644 --- a/lnbits/wallets/lndrest.py +++ b/lnbits/wallets/lndrest.py @@ -1,4 +1,4 @@ -import trio +import asyncio import httpx import json import base64 @@ -183,4 +183,4 @@ class LndRestWallet(Wallet): pass print("lost connection to lnd invoices stream, retrying in 5 seconds") - await trio.sleep(5) + await asyncio.sleep(5) diff --git a/lnbits/wallets/lnpay.py b/lnbits/wallets/lnpay.py index 034d1529e..305400df4 100644 --- a/lnbits/wallets/lnpay.py +++ b/lnbits/wallets/lnpay.py @@ -1,5 +1,5 @@ import json -import trio +import asyncio import httpx from os import getenv from http import HTTPStatus @@ -116,8 +116,9 @@ class LNPayWallet(Wallet): return PaymentStatus(statuses[r.json()["settled"]]) async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: - self.send, receive = trio.open_memory_channel(0) - async for value in receive: + self.queue = asyncio.Queue(0) + while True: + value = await self.queue.get() yield value async def webhook_listener(self): @@ -142,6 +143,6 @@ class LNPayWallet(Wallet): ) data = r.json() if data["settled"]: - await self.send.send(lntx_id) + await self.queue.put(lntx_id) return "", HTTPStatus.NO_CONTENT diff --git a/lnbits/wallets/lntxbot.py b/lnbits/wallets/lntxbot.py index e5e1cf158..c804542a5 100644 --- a/lnbits/wallets/lntxbot.py +++ b/lnbits/wallets/lntxbot.py @@ -1,4 +1,4 @@ -import trio +import asyncio import json import httpx from os import getenv @@ -150,4 +150,4 @@ class LntxbotWallet(Wallet): pass print("lost connection to lntxbot /payments/stream, retrying in 5 seconds") - await trio.sleep(5) + await asyncio.sleep(5) diff --git a/lnbits/wallets/opennode.py b/lnbits/wallets/opennode.py index ba315503a..d955cc0ba 100644 --- a/lnbits/wallets/opennode.py +++ b/lnbits/wallets/opennode.py @@ -1,5 +1,5 @@ +import asyncio from lnbits.helpers import url_for -import trio import hmac import httpx from http import HTTPStatus @@ -125,8 +125,9 @@ class OpenNodeWallet(Wallet): return PaymentStatus(statuses[r.json()["data"]["status"]]) async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: - self.send, receive = trio.open_memory_channel(0) - async for value in receive: + self.queue = asyncio.Queue(0) + while True: + value = await self.queue.get() yield value async def webhook_listener(self): @@ -141,5 +142,5 @@ class OpenNodeWallet(Wallet): print("invalid webhook, not from opennode") return "", HTTPStatus.NO_CONTENT - await self.send.send(charge_id) + await self.queue.put(charge_id) return "", HTTPStatus.NO_CONTENT diff --git a/lnbits/wallets/spark.py b/lnbits/wallets/spark.py index 770d5777d..ca8f6efe8 100644 --- a/lnbits/wallets/spark.py +++ b/lnbits/wallets/spark.py @@ -1,4 +1,4 @@ -import trio +import asyncio import json import httpx import random @@ -199,4 +199,4 @@ class SparkWallet(Wallet): pass print("lost connection to spark /stream, retrying in 5 seconds") - await trio.sleep(5) + await asyncio.sleep(5)