refactor: replace Trio with asyncio/uvloop

This commit is contained in:
Stefan Stammberger 2021-08-30 19:55:02 +02:00
parent fe79709698
commit d9849d43d2
No known key found for this signature in database
GPG key ID: 645FA807E935D9D5
21 changed files with 332 additions and 317 deletions

10
Pipfile
View file

@ -16,22 +16,20 @@ pyscss = "*"
shortuuid = "*" shortuuid = "*"
typing-extensions = "*" typing-extensions = "*"
httpx = "*" httpx = "*"
trio = "==0.16.0"
sqlalchemy-aio = "*" sqlalchemy-aio = "*"
embit = "*" embit = "*"
pyqrcode = "*" pyqrcode = "*"
pypng = "*" pypng = "*"
sqlalchemy = "==1.3.23" sqlalchemy = "==1.3.23"
psycopg2-binary = "*" psycopg2-binary = "*"
fastapi = {ref = "anyio", git = "https://github.com/graingert/fastapi"}
trio-asyncio = "*"
hypercorn = {extras = ["trio"], version = "*"}
aiofiles = "*" aiofiles = "*"
asyncio = "*"
fastapi = "*"
uvicorn = {extras = ["standard"], version = "*"}
sse-starlette = "*"
[dev-packages] [dev-packages]
black = "==20.8b1" black = "==20.8b1"
pytest = "*" pytest = "*"
pytest-cov = "*" pytest-cov = "*"
mypy = "latest" mypy = "latest"
pytest-trio = "*"
trio-typing = "*"

352
Pipfile.lock generated
View file

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "ff9251889371e0cec0eda7eb792e8618ea84f6c7eb85e9b472eacf3d3552c7c4" "sha256": "e26f678c4b89a86400e0a62396d06e360bfdf1e0f922d474ded200ee1ffde5c4"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": { "requires": {
@ -32,13 +32,23 @@
"markers": "python_full_version >= '3.6.2'", "markers": "python_full_version >= '3.6.2'",
"version": "==3.3.0" "version": "==3.3.0"
}, },
"async-generator": { "asgiref": {
"hashes": [ "hashes": [
"sha256:01c7bf666359b4967d2cda0000cc2e4af16a0ae098cbffcb8472fb9e8ad6585b", "sha256:4ef1ab46b484e3c706329cedeff284a5d40824200638503f5768edb6de7d58e9",
"sha256:6ebb3d106c12920aaae42ccb6f787ef5eefdcdd166ea3d628fa8476abe712144" "sha256:ffc141aa908e6f175673e7b1b3b7af4fdb0ecb738fc5c8b88f69f055c2415214"
], ],
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.6'",
"version": "==1.10" "version": "==3.4.1"
},
"asyncio": {
"hashes": [
"sha256:83360ff8bc97980e4ff25c964c7bd3923d333d177aa4f7fb736b019f26c7cb41",
"sha256:b62c9157d36187eca799c378e572c969f0da87cd5fc42ca372d92cdb06e7e1de",
"sha256:c46a87b48213d7464f22d9a497b9eef8c1928b68320a2fa94240f969f6fec08c",
"sha256:c4d18b22701821de07bd6aea8b53d21449ec0ec5680645e5317062ea21817d2d"
],
"index": "pypi",
"version": "==3.4.3"
}, },
"attrs": { "attrs": {
"hashes": [ "hashes": [
@ -87,6 +97,14 @@
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.5'",
"version": "==2.0.4" "version": "==2.0.4"
}, },
"click": {
"hashes": [
"sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a",
"sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6"
],
"markers": "python_version >= '3.6'",
"version": "==8.0.1"
},
"ecdsa": { "ecdsa": {
"hashes": [ "hashes": [
"sha256:5cf31d5b33743abe0dfc28999036c849a69d548f994b535e527ee3cb7f3ef676", "sha256:5cf31d5b33743abe0dfc28999036c849a69d548f994b535e527ee3cb7f3ef676",
@ -111,8 +129,12 @@
"version": "==9.3.3" "version": "==9.3.3"
}, },
"fastapi": { "fastapi": {
"git": "https://github.com/graingert/fastapi", "hashes": [
"ref": "ada7c747c05c88d37e012d32e97bcc9579f3f006" "sha256:644bb815bae326575c4b2842469fb83053a4b974b82fa792ff9283d17fbbd99d",
"sha256:94d2820906c36b9b8303796fb7271337ec89c74223229e3cfcf056b5a7d59e23"
],
"index": "pypi",
"version": "==0.68.1"
}, },
"h11": { "h11": {
"hashes": [ "hashes": [
@ -122,22 +144,6 @@
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==0.12.0" "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": { "httpcore": {
"hashes": [ "hashes": [
"sha256:b0d16f0012ec88d8cc848f5a55f8a03158405f4bca02ee49bc4ca2c1fda49f3e", "sha256:b0d16f0012ec88d8cc848f5a55f8a03158405f4bca02ee49bc4ca2c1fda49f3e",
@ -146,6 +152,26 @@
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==0.13.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": { "httpx": {
"hashes": [ "hashes": [
"sha256:92ecd2c00c688b529eda11cedb15161eaf02dee9116712f621c70d9a40b2cdd0", "sha256:92ecd2c00c688b529eda11cedb15161eaf02dee9116712f621c70d9a40b2cdd0",
@ -154,25 +180,6 @@
"index": "pypi", "index": "pypi",
"version": "==0.19.0" "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": { "idna": {
"hashes": [ "hashes": [
"sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a", "sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a",
@ -180,6 +187,14 @@
], ],
"version": "==3.2" "version": "==3.2"
}, },
"importlib-metadata": {
"hashes": [
"sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15",
"sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"
],
"markers": "python_version < '3.8'",
"version": "==4.8.1"
},
"lnurl": { "lnurl": {
"hashes": [ "hashes": [
"sha256:579982fd8c4d25bc84c61c74ec45cb7999fa1fa2426f5d5aeb0160ba333b9c92", "sha256:579982fd8c4d25bc84c61c74ec45cb7999fa1fa2426f5d5aeb0160ba333b9c92",
@ -204,14 +219,6 @@
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==1.1.0" "version": "==1.1.0"
}, },
"priority": {
"hashes": [
"sha256:6f8eefce5f3ad59baf2c080a664037bb4725cd0a790d53d59ab4059288faf6aa",
"sha256:c965d54f1b8d0d0b19479db3924c7c36cf672dbf2aec92d43fbdaf4492ba18c0"
],
"markers": "python_full_version >= '3.6.1'",
"version": "==2.0.0"
},
"psycopg2-binary": { "psycopg2-binary": {
"hashes": [ "hashes": [
"sha256:0b7dae87f0b729922e06f85f667de7bf16455d411971b2043bbd9577af9d1975", "sha256:0b7dae87f0b729922e06f85f667de7bf16455d411971b2043bbd9577af9d1975",
@ -305,6 +312,40 @@
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.5'",
"version": "==0.19.0" "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": { "represent": {
"hashes": [ "hashes": [
"sha256:026c0de2ee8385d1255b9c2426cd4f03fe9177ac94c09979bc601946c8493aa0", "sha256:026c0de2ee8385d1255b9c2426cd4f03fe9177ac94c09979bc601946c8493aa0",
@ -347,13 +388,6 @@
"markers": "python_version >= '3.5'", "markers": "python_version >= '3.5'",
"version": "==1.2.0" "version": "==1.2.0"
}, },
"sortedcontainers": {
"hashes": [
"sha256:25caa5a06cc30b6b83d11423433f65d1f9d76c4c6a0c90e3379eaa43b9bfdb88",
"sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0"
],
"version": "==2.4.0"
},
"sqlalchemy": { "sqlalchemy": {
"hashes": [ "hashes": [
"sha256:040bdfc1d76a9074717a3f43455685f781c581f94472b010cd6c4754754e1862", "sha256:040bdfc1d76a9074717a3f43455685f781c581f94472b010cd6c4754754e1862",
@ -406,46 +440,114 @@
"index": "pypi", "index": "pypi",
"version": "==0.16.0" "version": "==0.16.0"
}, },
"toml": { "sse-starlette": {
"hashes": [ "hashes": [
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:1c0cc62cc7d021a386dc06a16a9ddc3e2861d19da6bc2e654e65cc111e820456"
"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"
], ],
"index": "pypi", "index": "pypi",
"version": "==0.16.0" "version": "==0.6.2"
}, },
"trio-asyncio": { "starlette": {
"hashes": [ "hashes": [
"sha256:824be23b0c678c0df942816cdb57b92a8b94f264fffa89f04626b0ba2d009768", "sha256:3c8e48e52736b3161e34c9f0e8153b4f32ec5d8995a3ee1d59410d92f75162ed",
"sha256:9bf678f83204ba33c395783681c69af563a84145fad2110a152a81a4a18ae7e4" "sha256:7d49f4a27f8742262ef1470608c59ddbc66baf37c148e938c7038e6bc7a998aa"
], ],
"index": "pypi", "markers": "python_version >= '3.6'",
"version": "==0.12.0" "version": "==0.14.2"
}, },
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [
"sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", "sha256:045dd532231acfa03628df5e0c66dba64e2cc8fc8b844538d4ad6d5dd6cb82dc",
"sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", "sha256:83af6730a045fda60f46510f7f1f094776d90321caa4d97d20ef38871bef4bd3",
"sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" "sha256:8bbffbd37fbeb9747a0241fdfde5ae99d4531ad1d1a41ccaea62100e15a5814c"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.10.0.0" "version": "==3.10.0.1"
}, },
"wsproto": { "uvicorn": {
"hashes": [ "extras": [
"sha256:868776f8456997ad0d9720f7322b746bbe9193751b5b290b7f924659377c8c38", "standard"
"sha256:d8345d1808dd599b5ffb352c25a367adb6157e664e140dbecba3f9bc007edb9f"
], ],
"markers": "python_full_version >= '3.6.1'", "hashes": [
"version": "==1.0.0" "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": { "develop": {
@ -456,14 +558,6 @@
], ],
"version": "==1.4.4" "version": "==1.4.4"
}, },
"async-generator": {
"hashes": [
"sha256:01c7bf666359b4967d2cda0000cc2e4af16a0ae098cbffcb8472fb9e8ad6585b",
"sha256:6ebb3d106c12920aaae42ccb6f787ef5eefdcdd166ea3d628fa8476abe712144"
],
"markers": "python_version >= '3.5'",
"version": "==1.10"
},
"attrs": { "attrs": {
"hashes": [ "hashes": [
"sha256:149e90d6d8ac20db7a955ad60cf0e6881a3f20d37096140088356da6c716b0b1", "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'", "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" "version": "==5.5"
}, },
"idna": {
"hashes": [
"sha256:14475042e284991034cb48e06f6851428fb14c4dc953acd9be9a5e95c7b6dd7a",
"sha256:467fbad99067910785144ce333826c71fb0e63a425657295239737f7ecd125f3"
],
"version": "==3.2"
},
"importlib-metadata": { "importlib-metadata": {
"hashes": [ "hashes": [
"sha256:9e04bf59076a15a9b6dd9c27806e8fcdf15280ba529c6a8cc3f4d5b4875bdd61", "sha256:b618b6d2d5ffa2f16add5697cf57a46c76a56229b0ed1c438322e4e95645bd15",
"sha256:c4eb3dec5f697682e383a39701a7de11cd5c02daf8dd93534b69e3e6473f6b1b" "sha256:f284b3e11256ad1e5d03ab86bb2ccd6f5339688ff17a4d797a0fe7df326f23b1"
], ],
"markers": "python_version < '3.8'", "markers": "python_version < '3.8'",
"version": "==4.7.1" "version": "==4.8.1"
}, },
"iniconfig": { "iniconfig": {
"hashes": [ "hashes": [
@ -603,14 +690,6 @@
], ],
"version": "==0.4.3" "version": "==0.4.3"
}, },
"outcome": {
"hashes": [
"sha256:c7dd9375cfd3c12db9801d080a3b63d4b0a261aa996c4c13152380587288d958",
"sha256:e862f01d4e626e63e8f92c38d1f8d5546d3f9cce989263c521b2e7990d186967"
],
"markers": "python_version >= '3.6'",
"version": "==1.1.0"
},
"packaging": { "packaging": {
"hashes": [ "hashes": [
"sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7", "sha256:7dc96269f53a4ccec5c0670940a4281106dd0bb343f47b7471f779df49c2fbe7",
@ -666,15 +745,9 @@
"index": "pypi", "index": "pypi",
"version": "==2.12.1" "version": "==2.12.1"
}, },
"pytest-trio": {
"hashes": [
"sha256:c01b741819aec2c419555f28944e132d3c711dae1e673d63260809bf92c30c31"
],
"index": "pypi",
"version": "==0.7.0"
},
"regex": { "regex": {
"hashes": [ "hashes": [
"sha256:04f6b9749e335bb0d2f68c707f23bb1773c3fb6ecd10edf0f04df12a8920d468",
"sha256:08d74bfaa4c7731b8dac0a992c63673a2782758f7cfad34cf9c1b9184f911354", "sha256:08d74bfaa4c7731b8dac0a992c63673a2782758f7cfad34cf9c1b9184f911354",
"sha256:0fc1f8f06977c2d4f5e3d3f0d4a08089be783973fc6b6e278bde01f0544ff308", "sha256:0fc1f8f06977c2d4f5e3d3f0d4a08089be783973fc6b6e278bde01f0544ff308",
"sha256:121f4b3185feaade3f85f70294aef3f777199e9b5c0c0245c774ae884b110a2d", "sha256:121f4b3185feaade3f85f70294aef3f777199e9b5c0c0245c774ae884b110a2d",
@ -694,12 +767,15 @@
"sha256:8e44769068d33e0ea6ccdf4b84d80c5afffe5207aa4d1881a629cf0ef3ec398f", "sha256:8e44769068d33e0ea6ccdf4b84d80c5afffe5207aa4d1881a629cf0ef3ec398f",
"sha256:999ad08220467b6ad4bd3dd34e65329dd5d0df9b31e47106105e407954965256", "sha256:999ad08220467b6ad4bd3dd34e65329dd5d0df9b31e47106105e407954965256",
"sha256:9b006628fe43aa69259ec04ca258d88ed19b64791693df59c422b607b6ece8bb", "sha256:9b006628fe43aa69259ec04ca258d88ed19b64791693df59c422b607b6ece8bb",
"sha256:9d05ad5367c90814099000442b2125535e9d77581855b9bee8780f1b41f2b1a2",
"sha256:a577a21de2ef8059b58f79ff76a4da81c45a75fe0bfb09bc8b7bb4293fa18983", "sha256:a577a21de2ef8059b58f79ff76a4da81c45a75fe0bfb09bc8b7bb4293fa18983",
"sha256:a617593aeacc7a691cc4af4a4410031654f2909053bd8c8e7db837f179a630eb", "sha256:a617593aeacc7a691cc4af4a4410031654f2909053bd8c8e7db837f179a630eb",
"sha256:abb48494d88e8a82601af905143e0de838c776c1241d92021e9256d5515b3645", "sha256:abb48494d88e8a82601af905143e0de838c776c1241d92021e9256d5515b3645",
"sha256:ac88856a8cbccfc14f1b2d0b829af354cc1743cb375e7f04251ae73b2af6adf8", "sha256:ac88856a8cbccfc14f1b2d0b829af354cc1743cb375e7f04251ae73b2af6adf8",
"sha256:b4c220a1fe0d2c622493b0a1fd48f8f991998fb447d3cd368033a4b86cf1127a",
"sha256:b844fb09bd9936ed158ff9df0ab601e2045b316b17aa8b931857365ea8586906", "sha256:b844fb09bd9936ed158ff9df0ab601e2045b316b17aa8b931857365ea8586906",
"sha256:bdc178caebd0f338d57ae445ef8e9b737ddf8fbc3ea187603f65aec5b041248f", "sha256:bdc178caebd0f338d57ae445ef8e9b737ddf8fbc3ea187603f65aec5b041248f",
"sha256:c206587c83e795d417ed3adc8453a791f6d36b67c81416676cad053b4104152c",
"sha256:c61dcc1cf9fd165127a2853e2c31eb4fb961a4f26b394ac9fe5669c7a6592892", "sha256:c61dcc1cf9fd165127a2853e2c31eb4fb961a4f26b394ac9fe5669c7a6592892",
"sha256:c7cb4c512d2d3b0870e00fbbac2f291d4b4bf2634d59a31176a87afe2777c6f0", "sha256:c7cb4c512d2d3b0870e00fbbac2f291d4b4bf2634d59a31176a87afe2777c6f0",
"sha256:d4a332404baa6665b54e5d283b4262f41f2103c255897084ec8f5487ce7b9e8e", "sha256:d4a332404baa6665b54e5d283b4262f41f2103c255897084ec8f5487ce7b9e8e",
@ -707,6 +783,7 @@
"sha256:e1e8406b895aba6caa63d9fd1b6b1700d7e4825f78ccb1e5260551d168db38ed", "sha256:e1e8406b895aba6caa63d9fd1b6b1700d7e4825f78ccb1e5260551d168db38ed",
"sha256:e8690ed94481f219a7a967c118abaf71ccc440f69acd583cab721b90eeedb77c", "sha256:e8690ed94481f219a7a967c118abaf71ccc440f69acd583cab721b90eeedb77c",
"sha256:ed283ab3a01d8b53de3a05bfdf4473ae24e43caee7dcb5584e86f3f3e5ab4374", "sha256:ed283ab3a01d8b53de3a05bfdf4473ae24e43caee7dcb5584e86f3f3e5ab4374",
"sha256:ed4b50355b066796dacdd1cf538f2ce57275d001838f9b132fab80b75e8c84dd",
"sha256:ee329d0387b5b41a5dddbb6243a21cb7896587a651bebb957e2d2bb8b63c0791", "sha256:ee329d0387b5b41a5dddbb6243a21cb7896587a651bebb957e2d2bb8b63c0791",
"sha256:f3bf1bc02bc421047bfec3343729c4bbbea42605bcfd6d6bfe2c07ade8b12d2a", "sha256:f3bf1bc02bc421047bfec3343729c4bbbea42605bcfd6d6bfe2c07ade8b12d2a",
"sha256:f585cbbeecb35f35609edccb95efd95a3e35824cd7752b586503f7e6087303f1", "sha256:f585cbbeecb35f35609edccb95efd95a3e35824cd7752b586503f7e6087303f1",
@ -714,21 +791,6 @@
], ],
"version": "==2021.8.28" "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": { "toml": {
"hashes": [ "hashes": [
"sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b", "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b",
@ -737,22 +799,6 @@
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'", "markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==0.10.2" "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": { "typed-ast": {
"hashes": [ "hashes": [
"sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace", "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace",
@ -791,12 +837,12 @@
}, },
"typing-extensions": { "typing-extensions": {
"hashes": [ "hashes": [
"sha256:0ac0f89795dd19de6b97debb0c6af1c70987fd80a2d62d1958f7e56fcc31b497", "sha256:045dd532231acfa03628df5e0c66dba64e2cc8fc8b844538d4ad6d5dd6cb82dc",
"sha256:50b6f157849174217d0656f99dc82fe932884fb250826c18350e159ec6cdf342", "sha256:83af6730a045fda60f46510f7f1f094776d90321caa4d97d20ef38871bef4bd3",
"sha256:779383f6086d90c99ae41cf0ff39aac8a7937a9283ce0a414e5dd782f4c94a84" "sha256:8bbffbd37fbeb9747a0241fdfde5ae99d4531ad1d1a41ccaea62100e15a5814c"
], ],
"index": "pypi", "index": "pypi",
"version": "==3.10.0.0" "version": "==3.10.0.1"
}, },
"zipp": { "zipp": {
"hashes": [ "hashes": [

View file

@ -1,28 +1,21 @@
from hypercorn.trio import serve import asyncio
import trio
import trio_asyncio
from hypercorn.config import Config
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() transpile_scss()
bundle_vendored() bundle_vendored()
from .app import create_app from .app import create_app
app = trio.run(create_app) app = create_app()
from .settings import (
LNBITS_SITE_TITLE,
SERVICE_FEE,
DEBUG,
LNBITS_DATA_FOLDER,
WALLET,
LNBITS_COMMIT,
HOST,
PORT
)
print( print(
f"""Starting LNbits with f"""Starting LNbits with
@ -35,6 +28,3 @@ print(
""" """
) )
config = Config()
config.bind = [f"{HOST}:{PORT}"]
trio_asyncio.run(serve, app, config)

View file

@ -1,9 +1,10 @@
import asyncio
import importlib import importlib
from lnbits.core.tasks import register_task_listeners
import sys import sys
import traceback import traceback
import warnings import warnings
import trio
from fastapi import FastAPI, Request from fastapi import FastAPI, Request
from fastapi.exceptions import RequestValidationError from fastapi.exceptions import RequestValidationError
from fastapi.middleware.cors import CORSMiddleware 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) template_renderer, url_for_vendored)
from .requestvars import g from .requestvars import g
from .settings import WALLET 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) 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. """Create application factory.
:param config_object: The configuration object to use. :param config_object: The configuration object to use.
""" """
@ -128,16 +129,12 @@ def register_async_tasks(app):
@app.on_event("startup") @app.on_event("startup")
async def listeners(): async def listeners():
run_deferred_async() loop = asyncio.get_event_loop()
trio.open_process(check_pending_payments) loop.create_task(catch_everything_and_restart(check_pending_payments))
trio.open_process(invoice_listener) loop.create_task(catch_everything_and_restart(invoice_listener))
trio.open_process(internal_invoice_listener) loop.create_task(catch_everything_and_restart(internal_invoice_listener))
await register_task_listeners()
async with trio.open_nursery() as n: await run_deferred_async()
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)
@app.on_event("shutdown") @app.on_event("shutdown")
async def stop_listeners(): async def stop_listeners():

View file

@ -1,4 +1,4 @@
import trio import asyncio
import warnings import warnings
import click import click
import importlib import importlib
@ -18,7 +18,7 @@ from .settings import LNBITS_PATH
@click.command("migrate") @click.command("migrate")
def db_migrate(): def db_migrate():
trio.run(migrate_databases) asyncio.create_task(migrate_databases())
@click.command("assets") @click.command("assets")

View file

@ -6,14 +6,8 @@ db = Database("database")
core_app: APIRouter = APIRouter() core_app: APIRouter = APIRouter()
from lnbits.tasks import record_async
from .tasks import register_listeners
from .views.api import * # noqa from .views.api import * # noqa
from .views.generic import * # noqa from .views.generic import * # noqa
from .views.public_api import * # noqa from .views.public_api import * # noqa
@core_app.on_event("startup")
def do_startup():
record_async(register_listeners)

View file

@ -1,4 +1,4 @@
import trio import asyncio
import json import json
import httpx import httpx
from io import BytesIO from io import BytesIO
@ -211,7 +211,7 @@ async def redeem_lnurl_withdraw(
return None return None
if wait_seconds: if wait_seconds:
await trio.sleep(wait_seconds) await asyncio.sleep(wait_seconds)
params = { params = {
"k1": res["k1"], "k1": res["k1"],

View file

@ -1,4 +1,4 @@
import trio import asyncio
import httpx import httpx
from typing import List from typing import List
@ -8,17 +8,19 @@ from . import db
from .crud import get_balance_notify from .crud import get_balance_notify
from .models import Payment from .models import Payment
api_invoice_listeners: List[trio.MemorySendChannel] = [] api_invoice_listeners: List[asyncio.Queue] = []
async def register_listeners(): async def register_task_listeners():
invoice_paid_chan_send, invoice_paid_chan_recv = trio.open_memory_channel(5) invoice_paid_queue = asyncio.Queue(5)
register_invoice_listener(invoice_paid_chan_send) register_invoice_listener(invoice_paid_queue)
await wait_for_paid_invoices(invoice_paid_chan_recv) asyncio.create_task(wait_for_paid_invoices(invoice_paid_queue))
async def wait_for_paid_invoices(invoice_paid_chan: trio.MemoryReceiveChannel): async def wait_for_paid_invoices(invoice_paid_queue: asyncio.Queue):
async for payment in invoice_paid_chan: while True:
payment = await invoice_paid_queue.get()
# send information to sse channel # send information to sse channel
await dispatch_invoice_listener(payment) 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): async def dispatch_invoice_listener(payment: Payment):
for send_channel in api_invoice_listeners: for send_channel in api_invoice_listeners:
try: try:
send_channel.send_nowait(payment) send_channel.put_nowait(payment)
except trio.WouldBlock: except asyncio.QueueFull:
print("removing sse listener", send_channel) print("removing sse listener", send_channel)
api_invoice_listeners.remove(send_channel) api_invoice_listeners.remove(send_channel)

View file

@ -1,3 +1,4 @@
import asyncio
import hashlib import hashlib
import json import json
from binascii import unhexlify from binascii import unhexlify
@ -6,15 +7,15 @@ from typing import Dict, Optional, Union
from urllib.parse import ParseResult, parse_qs, urlencode, urlparse, urlunparse from urllib.parse import ParseResult, parse_qs, urlencode, urlparse, urlunparse
import httpx import httpx
import trio from fastapi import Query, Request
from fastapi import Query, security
from fastapi.exceptions import HTTPException from fastapi.exceptions import HTTPException
from fastapi.param_functions import Depends from fastapi.param_functions import Depends
from fastapi.params import Body from fastapi.params import Body
from sse_starlette.sse import EventSourceResponse
from pydantic import BaseModel from pydantic import BaseModel
from lnbits import bolt11, lnurl from lnbits import bolt11, lnurl
from lnbits.core.models import Wallet from lnbits.core.models import Payment, Wallet
from lnbits.decorators import (WalletAdminKeyChecker, WalletInvoiceKeyChecker, from lnbits.decorators import (WalletAdminKeyChecker, WalletInvoiceKeyChecker,
WalletTypeInfo, get_key_type) WalletTypeInfo, get_key_type)
from lnbits.helpers import url_for from lnbits.helpers import url_for
@ -251,57 +252,42 @@ async def api_payments_pay_lnurl(data: CreateLNURLData):
HTTPStatus.CREATED, HTTPStatus.CREATED,
) )
@core_app.get("/api/v1/payments/sse") async def subscribe(request: Request, wallet: Wallet):
async def api_payments_sse(wallet: WalletTypeInfo = Depends(get_key_type)):
this_wallet_id = wallet.wallet.id 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) print("adding sse listener", payment_queue)
api_invoice_listeners.append(send_payment) 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 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: while True:
await send_event.send(("keepalive", "")) payment: Payment = await payment_queue.get()
await trio.sleep(25) if payment.wallet_id == this_wallet_id:
await send_queue.put(("payment-received", payment))
async with trio.open_nursery() as nursery: asyncio.create_task(payment_received())
nursery.start_soon(payment_received)
nursery.start_soon(repeat_keepalive)
async def send_events():
try: try:
async for typ, data in event_to_send: while True:
typ, data = await send_queue.get()
message = [f"event: {typ}".encode("utf-8")] message = [f"event: {typ}".encode("utf-8")]
if data: if data:
jdata = json.dumps(dict(data._asdict(), pending=False)) jdata = json.dumps(dict(data.dict(), pending=False))
message.append(f"data: {jdata}".encode("utf-8")) message.append(f"data: {jdata}".encode("utf-8"))
yield b"\n".join(message) + b"\r\n\r\n" yield dict(data=jdata.encode("utf-8"), event=typ.encode("utf-8"))
except trio.Cancelled: except asyncio.CancelledError:
return return
response = await make_response(
send_events(), @core_app.get("/api/v1/payments/sse")
{ async def api_payments_sse(request: Request, wallet: WalletTypeInfo = Depends(get_key_type)):
"Content-Type": "text/event-stream", return EventSourceResponse(subscribe(request, wallet))
"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}") @core_app.get("/api/v1/payments/{payment_hash}")
async def api_payment(payment_hash, wallet: WalletTypeInfo = Depends(get_key_type)): async def api_payment(payment_hash, wallet: WalletTypeInfo = Depends(get_key_type)):

View file

@ -1,3 +1,5 @@
import asyncio
from http import HTTPStatus from http import HTTPStatus
from typing import Optional from typing import Optional
@ -9,7 +11,6 @@ from fastapi.responses import FileResponse, RedirectResponse
from fastapi.routing import APIRouter from fastapi.routing import APIRouter
from pydantic.types import UUID4 from pydantic.types import UUID4
from starlette.responses import HTMLResponse from starlette.responses import HTMLResponse
import trio
from lnbits.core import db from lnbits.core import db
from lnbits.helpers import template_renderer, url_for from lnbits.helpers import template_renderer, url_for
@ -142,8 +143,7 @@ async def lnurl_full_withdraw_callback(request: Request):
except: except:
pass pass
async with trio.open_nursery() as n: asyncio.create_task(pay())
n.start_soon(pay)
balance_notify = request.args.get("balanceNotify") balance_notify = request.args.get("balanceNotify")
if balance_notify: if balance_notify:
@ -187,14 +187,14 @@ async def lnurlwallet(request: Request):
user = await get_user(account.id, conn=conn) user = await get_user(account.id, conn=conn)
wallet = await create_wallet(user_id=user.id, conn=conn) wallet = await create_wallet(user_id=user.id, conn=conn)
async with trio.open_nursery() as n: asyncio.create_task(
n.start_soon( redeem_lnurl_withdraw(
redeem_lnurl_withdraw,
wallet.id, wallet.id,
request.args.get("lightning"), request.args.get("lightning"),
"LNbits initial funding: voucher redeem.", "LNbits initial funding: voucher redeem.",
{"tag": "lnurlwallet"}, {"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) return RedirectResponse(f"/wallet?usr={user.id}&wal={wallet.id}", status_code=status.HTTP_307_TEMPORARY_REDIRECT)

View file

@ -1,4 +1,4 @@
import trio import asyncio
import datetime import datetime
from http import HTTPStatus from http import HTTPStatus
@ -26,27 +26,27 @@ async def api_public_payment_longpolling(payment_hash):
except: except:
return {"message": "Invalid bolt11 invoice."}, HTTPStatus.BAD_REQUEST 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) print("adding standalone invoice listener", payment_hash, payment_queue)
api_invoice_listeners.append(send_payment) api_invoice_listeners.append(payment_queue)
response = None response = None
async def payment_info_receiver(cancel_scope): 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: if payment.payment_hash == payment_hash:
nonlocal response nonlocal response
response = ({"status": "paid"}, HTTPStatus.OK) response = ({"status": "paid"}, HTTPStatus.OK)
cancel_scope.cancel() cancel_scope.cancel()
async def timeouter(cancel_scope): async def timeouter(cancel_scope):
await trio.sleep(45) await asyncio.sleep(45)
cancel_scope.cancel() cancel_scope.cancel()
async with trio.open_nursery() as nursery:
nursery.start_soon(payment_info_receiver, nursery.cancel_scope) asyncio.create_task(payment_info_receiver())
nursery.start_soon(timeouter, nursery.cancel_scope) asyncio.create_task(timeouter())
if response: if response:
return response return response

View file

@ -1,12 +1,12 @@
import os import os
import trio import asyncio
import time import time
import datetime import datetime
from typing import Optional from typing import Optional
from contextlib import asynccontextmanager from contextlib import asynccontextmanager
from sqlalchemy import create_engine # type: ignore from sqlalchemy import create_engine
from sqlalchemy_aio import TRIO_STRATEGY # type: ignore from sqlalchemy_aio.base import AsyncConnection
from sqlalchemy_aio.base import AsyncConnection # type: ignore from sqlalchemy_aio.strategy import ASYNCIO_STRATEGY # type: ignore
from .settings import LNBITS_DATA_FOLDER, LNBITS_DATABASE_URL from .settings import LNBITS_DATA_FOLDER, LNBITS_DATABASE_URL
@ -132,8 +132,8 @@ class Database(Compat):
else: else:
self.schema = None self.schema = None
self.engine = create_engine(database_uri, strategy=TRIO_STRATEGY) self.engine = create_engine(database_uri, strategy=ASYNCIO_STRATEGY)
self.lock = trio.StrictFIFOLock() self.lock = asyncio.Lock()
@asynccontextmanager @asynccontextmanager
async def connect(self): async def connect(self):

View file

@ -1,5 +1,5 @@
import time import time
import trio import asyncio
import traceback import traceback
from http import HTTPStatus from http import HTTPStatus
from typing import List, Callable from typing import List, Callable
@ -24,21 +24,21 @@ def record_async(func: Callable) -> Callable:
return recorder return recorder
def run_deferred_async(): async def run_deferred_async():
for func in 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): async def catch_everything_and_restart(func):
try: try:
await func() await func()
except trio.Cancelled: except asyncio.CancelledError:
raise # because we must pass this up raise # because we must pass this up
except Exception as exc: except Exception as exc:
print("caught exception in background task:", exc) print("caught exception in background task:", exc)
print(traceback.format_exc()) print(traceback.format_exc())
print("will restart the task in 5 seconds.") print("will restart the task in 5 seconds.")
await trio.sleep(5) await asyncio.sleep(5)
await catch_everything_and_restart(func) await catch_everything_and_restart(func)
@ -46,10 +46,10 @@ async def send_push_promise(a, b) -> None:
pass 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 A method intended for extensions to call when they want to be notified about
new invoice payments incoming. new invoice payments incoming.
@ -64,18 +64,19 @@ async def webhook_handler():
return "", HTTPStatus.NO_CONTENT 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 def internal_invoice_listener():
async for checking_id in internal_invoice_received: while True:
current_app.nursery.start_soon(invoice_callback_dispatcher, checking_id) checking_id = await internal_invoice_queue.get()
asyncio.create_task(invoice_callback_dispatcher(checking_id))
async def invoice_listener(): async def invoice_listener():
async for checking_id in WALLET.paid_invoices_stream(): async for checking_id in WALLET.paid_invoices_stream():
print("> got a payment notification", checking_id) 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(): async def check_pending_payments():
@ -99,7 +100,7 @@ async def check_pending_payments():
# that will be handled by the global invoice listeners, hopefully # that will be handled by the global invoice listeners, hopefully
incoming = False incoming = False
await trio.sleep(60 * 30) # every 30 minutes await asyncio.sleep(60 * 30) # every 30 minutes
async def perform_balance_checks(): async def perform_balance_checks():
@ -107,7 +108,7 @@ async def perform_balance_checks():
for bc in await get_balance_checks(): for bc in await get_balance_checks():
redeem_lnurl_withdraw(bc.wallet, bc.url) 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): 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: if payment and payment.is_in:
await payment.set_pending(False) await payment.set_pending(False)
for send_chan in invoice_listeners: for send_chan in invoice_listeners:
await send_chan.send(payment) await send_chan.put(payment)

View file

@ -1,4 +1,4 @@
import trio import asyncio
import httpx import httpx
from typing import Callable, NamedTuple from typing import Callable, NamedTuple
@ -219,12 +219,12 @@ async def btc_price(currency: str) -> float:
"to": currency.lower(), "to": currency.lower(),
} }
rates = [] rates = []
send_channel, receive_channel = trio.open_memory_channel(0) send_channel = asyncio.Queue(0)
async def controller(nursery): async def controller(nursery):
failures = 0 failures = 0
while True: while True:
rate = await receive_channel.receive() rate = await send_channel.get()
if rate: if rate:
rates.append(rate) rates.append(rate)
else: else:
@ -248,10 +248,9 @@ async def btc_price(currency: str) -> float:
except Exception: except Exception:
await send_channel.send(None) await send_channel.send(None)
async with trio.open_nursery() as nursery: # asyncio.create_task(controller, nursery)
nursery.start_soon(controller, nursery)
for key, provider in exchange_rate_providers.items(): for key, provider in exchange_rate_providers.items():
nursery.start_soon(fetch_price, key, provider) asyncio.create_task(fetch_price(key, provider))
if not rates: if not rates:
return 9999999999 return 9999999999

View file

@ -3,7 +3,7 @@ try:
except ImportError: # pragma: nocover except ImportError: # pragma: nocover
LightningRpc = None LightningRpc = None
import trio import asyncio
import random import random
import json import json
@ -116,7 +116,7 @@ class CLightningWallet(Wallet):
raise KeyError("supplied an invalid checking_id") raise KeyError("supplied an invalid checking_id")
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: 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 i = 0
while True: while True:

View file

@ -1,4 +1,4 @@
import trio import asyncio
import json import json
import httpx import httpx
from os import getenv from os import getenv
@ -146,4 +146,4 @@ class LNbitsWallet(Wallet):
pass pass
print("lost connection to lnbits /payments/sse, retrying in 5 seconds") print("lost connection to lnbits /payments/sse, retrying in 5 seconds")
await trio.sleep(5) await asyncio.sleep(5)

View file

@ -1,4 +1,4 @@
import trio import asyncio
import httpx import httpx
import json import json
import base64 import base64
@ -183,4 +183,4 @@ class LndRestWallet(Wallet):
pass pass
print("lost connection to lnd invoices stream, retrying in 5 seconds") print("lost connection to lnd invoices stream, retrying in 5 seconds")
await trio.sleep(5) await asyncio.sleep(5)

View file

@ -1,5 +1,5 @@
import json import json
import trio import asyncio
import httpx import httpx
from os import getenv from os import getenv
from http import HTTPStatus from http import HTTPStatus
@ -116,8 +116,9 @@ class LNPayWallet(Wallet):
return PaymentStatus(statuses[r.json()["settled"]]) return PaymentStatus(statuses[r.json()["settled"]])
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
self.send, receive = trio.open_memory_channel(0) self.queue = asyncio.Queue(0)
async for value in receive: while True:
value = await self.queue.get()
yield value yield value
async def webhook_listener(self): async def webhook_listener(self):
@ -142,6 +143,6 @@ class LNPayWallet(Wallet):
) )
data = r.json() data = r.json()
if data["settled"]: if data["settled"]:
await self.send.send(lntx_id) await self.queue.put(lntx_id)
return "", HTTPStatus.NO_CONTENT return "", HTTPStatus.NO_CONTENT

View file

@ -1,4 +1,4 @@
import trio import asyncio
import json import json
import httpx import httpx
from os import getenv from os import getenv
@ -150,4 +150,4 @@ class LntxbotWallet(Wallet):
pass pass
print("lost connection to lntxbot /payments/stream, retrying in 5 seconds") print("lost connection to lntxbot /payments/stream, retrying in 5 seconds")
await trio.sleep(5) await asyncio.sleep(5)

View file

@ -1,5 +1,5 @@
import asyncio
from lnbits.helpers import url_for from lnbits.helpers import url_for
import trio
import hmac import hmac
import httpx import httpx
from http import HTTPStatus from http import HTTPStatus
@ -125,8 +125,9 @@ class OpenNodeWallet(Wallet):
return PaymentStatus(statuses[r.json()["data"]["status"]]) return PaymentStatus(statuses[r.json()["data"]["status"]])
async def paid_invoices_stream(self) -> AsyncGenerator[str, None]: async def paid_invoices_stream(self) -> AsyncGenerator[str, None]:
self.send, receive = trio.open_memory_channel(0) self.queue = asyncio.Queue(0)
async for value in receive: while True:
value = await self.queue.get()
yield value yield value
async def webhook_listener(self): async def webhook_listener(self):
@ -141,5 +142,5 @@ class OpenNodeWallet(Wallet):
print("invalid webhook, not from opennode") print("invalid webhook, not from opennode")
return "", HTTPStatus.NO_CONTENT return "", HTTPStatus.NO_CONTENT
await self.send.send(charge_id) await self.queue.put(charge_id)
return "", HTTPStatus.NO_CONTENT return "", HTTPStatus.NO_CONTENT

View file

@ -1,4 +1,4 @@
import trio import asyncio
import json import json
import httpx import httpx
import random import random
@ -199,4 +199,4 @@ class SparkWallet(Wallet):
pass pass
print("lost connection to spark /stream, retrying in 5 seconds") print("lost connection to spark /stream, retrying in 5 seconds")
await trio.sleep(5) await asyncio.sleep(5)