From fee40d7321961caac44375b1a239ebe1ede9e85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Tue, 12 Sep 2023 12:25:05 +0200 Subject: [PATCH] [REFACTOR] core/__init__ to not have circular import issues (#1876) * F541 fix remove unused workflow and combine linters into one add lnbits/static to ruff ignore remote setupnode ignore upgrades for mypy ignore F401 for __init__ files unused noqa ignore upgrades for black F821: undefine name disabled and logged webhook_listener for opennode and lnpay because they are obvisouly not working E402: module level import not at top of file fixup revert breaking changes wait for PR #1876 https://github.com/lnbits/lnbits/pull/1876 E721 fixes, only popped up for python3.9 not 3.10 [REFACTOR] core/__init__ to not have circular import issues WIP add db for backwards compat fix pyright make mypy happy again pyright did not catch those, i think mypy got confused with relative imports. maybe we should use absolute ones everywhere E402: module level import not at top of file dont forget to add core_app rebase on ruff pr f remo format * fix clnrest * ignore E402 in conftest * refactoring issues --------- Co-authored-by: jacksn --- lnbits/app.py | 14 ++---- lnbits/core/__init__.py | 25 ++++++---- lnbits/core/crud.py | 2 +- lnbits/core/db.py | 5 ++ lnbits/core/helpers.py | 2 +- lnbits/core/services.py | 2 +- lnbits/core/tasks.py | 21 +++++---- lnbits/core/views/admin_api.py | 20 ++++---- lnbits/core/views/api.py | 71 ++++++++++++++--------------- lnbits/core/views/generic.py | 32 ++++++------- lnbits/core/views/public_api.py | 7 +-- lnbits/middleware.py | 2 +- lnbits/tasks.py | 3 +- lnbits/wallets/corelightningrest.py | 2 +- pyproject.toml | 4 +- tests/conftest.py | 1 + 16 files changed, 110 insertions(+), 103 deletions(-) create mode 100644 lnbits/core/db.py diff --git a/lnbits/app.py b/lnbits/app.py index d89f87b10..be2baf5c3 100644 --- a/lnbits/app.py +++ b/lnbits/app.py @@ -33,14 +33,11 @@ from lnbits.utils.cache import cache from lnbits.wallets import get_wallet_class, set_wallet_class from .commands import db_versions, load_disabled_extension_list, migrate_databases -from .core import ( - add_installed_extension, - core_app, - core_app_extra, - update_installed_extension_state, -) +from .core import init_core_routers +from .core.db import core_app_extra from .core.services import check_admin_settings, check_webpush_settings -from .core.views.generic import core_html_routes +from .core.views.api import add_installed_extension +from .core.views.generic import update_installed_extension_state from .extension_manager import Extension, InstallableExtension, get_valid_extensions from .helpers import template_renderer from .middleware import ( @@ -257,8 +254,7 @@ async def restore_installed_extension(app: FastAPI, ext: InstallableExtension): def register_routes(app: FastAPI) -> None: """Register FastAPI routes / LNbits extensions.""" - app.include_router(core_app) - app.include_router(core_html_routes) + init_core_routers(app) for ext in get_valid_extensions(): try: diff --git a/lnbits/core/__init__.py b/lnbits/core/__init__.py index 718bbd0ca..c981d2f2b 100644 --- a/lnbits/core/__init__.py +++ b/lnbits/core/__init__.py @@ -1,15 +1,20 @@ -from fastapi.routing import APIRouter +from fastapi import APIRouter -from lnbits.core.models import CoreAppExtra -from lnbits.db import Database +from .db import core_app_extra, db +from .views.admin_api import admin_router +from .views.api import api_router -db = Database("database") +# this compat is needed for usermanager extension +from .views.generic import generic_router, update_user_extension +from .views.public_api import public_router -core_app: APIRouter = APIRouter(tags=["Core"]) +# backwards compatibility for extensions +core_app = APIRouter(tags=["Core"]) -core_app_extra: CoreAppExtra = CoreAppExtra() -from .views.admin_api import * -from .views.api import * -from .views.generic import * -from .views.public_api import * +def init_core_routers(app): + app.include_router(core_app) + app.include_router(generic_router) + app.include_router(public_router) + app.include_router(api_router) + app.include_router(admin_router) diff --git a/lnbits/core/crud.py b/lnbits/core/crud.py index 1f7cd045d..33077ae8c 100644 --- a/lnbits/core/crud.py +++ b/lnbits/core/crud.py @@ -7,6 +7,7 @@ from uuid import UUID, uuid4 import shortuuid from lnbits import bolt11 +from lnbits.core.db import db from lnbits.core.models import WalletType from lnbits.db import Connection, Database, Filters, Page from lnbits.extension_manager import InstallableExtension @@ -18,7 +19,6 @@ from lnbits.settings import ( settings, ) -from . import db from .models import ( BalanceCheck, Payment, diff --git a/lnbits/core/db.py b/lnbits/core/db.py new file mode 100644 index 000000000..4c014d079 --- /dev/null +++ b/lnbits/core/db.py @@ -0,0 +1,5 @@ +from lnbits.core.models import CoreAppExtra +from lnbits.db import Database + +db = Database("database") +core_app_extra: CoreAppExtra = CoreAppExtra() diff --git a/lnbits/core/helpers.py b/lnbits/core/helpers.py index 12eb97a1c..feb2d4dac 100644 --- a/lnbits/core/helpers.py +++ b/lnbits/core/helpers.py @@ -6,11 +6,11 @@ from uuid import UUID import httpx from loguru import logger +from lnbits.core.db import db as core_db from lnbits.db import Connection from lnbits.extension_manager import Extension from lnbits.settings import settings -from . import db as core_db from .crud import update_migration_version diff --git a/lnbits/core/services.py b/lnbits/core/services.py index 6c534cc65..e0fac460f 100644 --- a/lnbits/core/services.py +++ b/lnbits/core/services.py @@ -15,6 +15,7 @@ from py_vapid import Vapid from py_vapid.utils import b64urlencode from lnbits import bolt11 +from lnbits.core.db import db from lnbits.db import Connection from lnbits.decorators import WalletTypeInfo, require_admin_key from lnbits.helpers import url_for @@ -29,7 +30,6 @@ from lnbits.utils.exchange_rates import fiat_amount_as_satoshis, satoshis_amount from lnbits.wallets import FAKE_WALLET, get_wallet_class, set_wallet_class from lnbits.wallets.base import PaymentResponse, PaymentStatus -from . import db from .crud import ( check_internal, check_internal_pending, diff --git a/lnbits/core/tasks.py b/lnbits/core/tasks.py index 79405af47..08f7a1e96 100644 --- a/lnbits/core/tasks.py +++ b/lnbits/core/tasks.py @@ -4,6 +4,18 @@ from typing import Dict import httpx from loguru import logger +from lnbits.core.crud import ( + get_balance_notify, + get_wallet, + get_webpush_subscriptions_for_user, +) +from lnbits.core.db import db +from lnbits.core.models import Payment +from lnbits.core.services import ( + get_balance_delta, + send_payment_notification, + switch_to_voidwallet, +) from lnbits.settings import get_wallet_class, settings from lnbits.tasks import ( SseListenersDict, @@ -13,15 +25,6 @@ from lnbits.tasks import ( send_push_notification, ) -from . import db -from .crud import ( - get_balance_notify, - get_wallet, - get_webpush_subscriptions_for_user, -) -from .models import Payment -from .services import get_balance_delta, send_payment_notification, switch_to_voidwallet - api_invoice_listeners: Dict[str, asyncio.Queue] = SseListenersDict( "api_invoice_listeners" ) diff --git a/lnbits/core/views/admin_api.py b/lnbits/core/views/admin_api.py index d88af231c..3f6a38944 100644 --- a/lnbits/core/views/admin_api.py +++ b/lnbits/core/views/admin_api.py @@ -6,7 +6,7 @@ from subprocess import Popen from typing import Optional from urllib.parse import urlparse -from fastapi import Depends +from fastapi import APIRouter, Depends from fastapi.responses import FileResponse from starlette.exceptions import HTTPException @@ -21,11 +21,13 @@ from lnbits.decorators import check_admin, check_super_user from lnbits.server import server_restart from lnbits.settings import AdminSettings, UpdateSettings, settings -from .. import core_app, core_app_extra +from .. import core_app_extra from ..crud import delete_admin_settings, get_admin_settings, update_admin_settings +admin_router = APIRouter() -@core_app.get( + +@admin_router.get( "/admin/api/v1/audit", name="Audit", description="show the current balance of the node and the LNbits database", @@ -46,7 +48,7 @@ async def api_auditor(): ) -@core_app.get("/admin/api/v1/settings/") +@admin_router.get("/admin/api/v1/settings/") async def api_get_settings( user: User = Depends(check_admin), ) -> Optional[AdminSettings]: @@ -54,7 +56,7 @@ async def api_get_settings( return admin_settings -@core_app.put( +@admin_router.put( "/admin/api/v1/settings/", status_code=HTTPStatus.OK, ) @@ -67,7 +69,7 @@ async def api_update_settings(data: UpdateSettings, user: User = Depends(check_a return {"status": "Success"} -@core_app.delete( +@admin_router.delete( "/admin/api/v1/settings/", status_code=HTTPStatus.OK, dependencies=[Depends(check_super_user)], @@ -77,7 +79,7 @@ async def api_delete_settings() -> None: server_restart.set() -@core_app.get( +@admin_router.get( "/admin/api/v1/restart/", status_code=HTTPStatus.OK, dependencies=[Depends(check_super_user)], @@ -87,7 +89,7 @@ async def api_restart_server() -> dict[str, str]: return {"status": "Success"} -@core_app.put( +@admin_router.put( "/admin/api/v1/topup/", name="Topup", status_code=HTTPStatus.OK, @@ -111,7 +113,7 @@ async def api_topup_balance(data: CreateTopup) -> dict[str, str]: return {"status": "Success"} -@core_app.get( +@admin_router.get( "/admin/api/v1/backup/", status_code=HTTPStatus.OK, dependencies=[Depends(check_super_user)], diff --git a/lnbits/core/views/api.py b/lnbits/core/views/api.py index fbabf1166..98cafc62e 100644 --- a/lnbits/core/views/api.py +++ b/lnbits/core/views/api.py @@ -11,6 +11,7 @@ from urllib.parse import ParseResult, parse_qs, unquote, urlencode, urlparse, ur import httpx import pyqrcode from fastapi import ( + APIRouter, Body, Depends, Header, @@ -25,6 +26,7 @@ from sse_starlette.sse import EventSourceResponse from starlette.responses import RedirectResponse, StreamingResponse from lnbits import bolt11, lnurl +from lnbits.core.db import core_app_extra, db from lnbits.core.helpers import ( migrate_extension_database, stop_extension_background_work, @@ -68,7 +70,6 @@ from lnbits.utils.exchange_rates import ( satoshis_amount_as_fiat, ) -from .. import core_app, core_app_extra, db from ..crud import ( add_installed_extension, create_tinyurl, @@ -101,13 +102,15 @@ from ..services import ( ) from ..tasks import api_invoice_listeners +api_router = APIRouter() -@core_app.get("/api/v1/health", status_code=HTTPStatus.OK) + +@api_router.get("/api/v1/health", status_code=HTTPStatus.OK) async def health(): return -@core_app.get("/api/v1/wallet") +@api_router.get("/api/v1/wallet") async def api_wallet(wallet: WalletTypeInfo = Depends(get_key_type)): if wallet.wallet_type == WalletType.admin: return { @@ -119,7 +122,7 @@ async def api_wallet(wallet: WalletTypeInfo = Depends(get_key_type)): return {"name": wallet.wallet.name, "balance": wallet.wallet.balance_msat} -@core_app.put("/api/v1/wallet/{new_name}") +@api_router.put("/api/v1/wallet/{new_name}") async def api_update_wallet_name( new_name: str, wallet: WalletTypeInfo = Depends(require_admin_key) ): @@ -131,7 +134,7 @@ async def api_update_wallet_name( } -@core_app.patch("/api/v1/wallet", response_model=Wallet) +@api_router.patch("/api/v1/wallet", response_model=Wallet) async def api_update_wallet( name: Optional[str] = Body(None), currency: Optional[str] = Body(None), @@ -140,7 +143,7 @@ async def api_update_wallet( return await update_wallet(wallet.wallet.id, name, currency) -@core_app.get( +@api_router.get( "/api/v1/payments", name="Payment List", summary="get list of payments", @@ -170,7 +173,7 @@ async def api_payments( ) -@core_app.get( +@api_router.get( "/api/v1/payments/paginated", name="Payment List", summary="get paginated list of payments", @@ -312,7 +315,7 @@ async def api_payments_pay_invoice(bolt11: str, wallet: Wallet): } -@core_app.post( +@api_router.post( "/api/v1/payments", summary="Create or pay an invoice", description=""" @@ -348,7 +351,7 @@ async def api_payments_create( ) -@core_app.post("/api/v1/payments/lnurl") +@api_router.post("/api/v1/payments/lnurl") async def api_payments_pay_lnurl( data: CreateLnurl, wallet: WalletTypeInfo = Depends(require_admin_key) ): @@ -455,7 +458,7 @@ async def subscribe_wallet_invoices(request: Request, wallet: Wallet): return -@core_app.get("/api/v1/payments/sse") +@api_router.get("/api/v1/payments/sse") async def api_payments_sse( request: Request, wallet: WalletTypeInfo = Depends(get_key_type) ): @@ -467,7 +470,7 @@ async def api_payments_sse( # TODO: refactor this route into a public and admin one -@core_app.get("/api/v1/payments/{payment_hash}") +@api_router.get("/api/v1/payments/{payment_hash}") async def api_payment(payment_hash, X_Api_Key: Optional[str] = Header(None)): # We use X_Api_Key here because we want this call to work with and without keys # If a valid key is given, we also return the field "details", otherwise not @@ -512,7 +515,7 @@ async def api_payment(payment_hash, X_Api_Key: Optional[str] = Header(None)): return {"paid": not payment.pending, "preimage": payment.preimage} -@core_app.get("/api/v1/lnurlscan/{code}") +@api_router.get("/api/v1/lnurlscan/{code}") async def api_lnurlscan(code: str, wallet: WalletTypeInfo = Depends(get_key_type)): try: url = lnurl.decode(code) @@ -627,7 +630,7 @@ async def api_lnurlscan(code: str, wallet: WalletTypeInfo = Depends(get_key_type return params -@core_app.post("/api/v1/payments/decode", status_code=HTTPStatus.OK) +@api_router.post("/api/v1/payments/decode", status_code=HTTPStatus.OK) async def api_payments_decode(data: DecodePayment, response: Response): payment_str = data.data try: @@ -653,7 +656,7 @@ async def api_payments_decode(data: DecodePayment, response: Response): return {"message": "Failed to decode"} -@core_app.post("/api/v1/lnurlauth") +@api_router.post("/api/v1/lnurlauth") async def api_perform_lnurlauth( data: CreateLnurlAuth, wallet: WalletTypeInfo = Depends(require_admin_key) ): @@ -665,7 +668,7 @@ async def api_perform_lnurlauth( return "" -@core_app.get("/api/v1/currencies") +@api_router.get("/api/v1/currencies") async def api_list_currencies_available(): if len(settings.lnbits_allowed_currencies) > 0: return [ @@ -676,7 +679,7 @@ async def api_list_currencies_available(): return list(currencies.keys()) -@core_app.post("/api/v1/conversion") +@api_router.post("/api/v1/conversion") async def api_fiat_as_sats(data: ConversionData): output = {} if data.from_ == "sat": @@ -694,7 +697,7 @@ async def api_fiat_as_sats(data: ConversionData): return output -@core_app.get("/api/v1/qrcode/{data}", response_class=StreamingResponse) +@api_router.get("/api/v1/qrcode/{data}", response_class=StreamingResponse) async def img(data): qr = pyqrcode.create(data) stream = BytesIO() @@ -715,7 +718,7 @@ async def img(data): ) -@core_app.websocket("/api/v1/ws/{item_id}") +@api_router.websocket("/api/v1/ws/{item_id}") async def websocket_connect(websocket: WebSocket, item_id: str): await websocketManager.connect(websocket, item_id) try: @@ -725,7 +728,7 @@ async def websocket_connect(websocket: WebSocket, item_id: str): websocketManager.disconnect(websocket) -@core_app.post("/api/v1/ws/{item_id}") +@api_router.post("/api/v1/ws/{item_id}") async def websocket_update_post(item_id: str, data: str): try: await websocketUpdater(item_id, data) @@ -734,7 +737,7 @@ async def websocket_update_post(item_id: str, data: str): return {"sent": False, "data": data} -@core_app.get("/api/v1/ws/{item_id}/{data}") +@api_router.get("/api/v1/ws/{item_id}/{data}") async def websocket_update_get(item_id: str, data: str): try: await websocketUpdater(item_id, data) @@ -743,7 +746,7 @@ async def websocket_update_get(item_id: str, data: str): return {"sent": False, "data": data} -@core_app.post("/api/v1/extension") +@api_router.post("/api/v1/extension") async def api_install_extension( data: CreateExtension, user: User = Depends(check_admin) ): @@ -802,7 +805,7 @@ async def api_install_extension( ) -@core_app.delete("/api/v1/extension/{ext_id}") +@api_router.delete("/api/v1/extension/{ext_id}") async def api_uninstall_extension(ext_id: str, user: User = Depends(check_admin)): installable_extensions = await InstallableExtension.get_installable_extensions() @@ -845,7 +848,7 @@ async def api_uninstall_extension(ext_id: str, user: User = Depends(check_admin) ) -@core_app.get( +@api_router.get( "/api/v1/extension/{ext_id}/releases", dependencies=[Depends(check_admin)] ) async def get_extension_releases(ext_id: str): @@ -862,7 +865,7 @@ async def get_extension_releases(ext_id: str): ) -@core_app.get( +@api_router.get( "/api/v1/extension/release/{org}/{repo}/{tag_name}", dependencies=[Depends(check_admin)], ) @@ -883,7 +886,7 @@ async def get_extension_release(org: str, repo: str, tag_name: str): ) -@core_app.delete( +@api_router.delete( "/api/v1/extension/{ext_id}/db", dependencies=[Depends(check_admin)], ) @@ -909,10 +912,7 @@ async def delete_extension_db(ext_id: str): ) -# TINYURL - - -@core_app.post( +@api_router.post( "/api/v1/tinyurl", name="Tinyurl", description="creates a tinyurl", @@ -933,7 +933,7 @@ async def api_create_tinyurl( ) -@core_app.get( +@api_router.get( "/api/v1/tinyurl/{tinyurl_id}", name="Tinyurl", description="get a tinyurl by id", @@ -955,7 +955,7 @@ async def api_get_tinyurl( ) -@core_app.delete( +@api_router.delete( "/api/v1/tinyurl/{tinyurl_id}", name="Tinyurl", description="delete a tinyurl by id", @@ -978,7 +978,7 @@ async def api_delete_tinyurl( ) -@core_app.get( +@api_router.get( "/t/{tinyurl_id}", name="Tinyurl", description="redirects a tinyurl by id", @@ -994,10 +994,7 @@ async def api_tinyurl(tinyurl_id: str): ) -############################WEBPUSH################################## - - -@core_app.post("/api/v1/webpush", status_code=HTTPStatus.CREATED) +@api_router.post("/api/v1/webpush", status_code=HTTPStatus.CREATED) async def api_create_webpush_subscription( request: Request, data: CreateWebPushSubscription, @@ -1019,7 +1016,7 @@ async def api_create_webpush_subscription( ) -@core_app.delete("/api/v1/webpush", status_code=HTTPStatus.OK) +@api_router.delete("/api/v1/webpush", status_code=HTTPStatus.OK) async def api_delete_webpush_subscription( request: Request, wallet: WalletTypeInfo = Depends(require_admin_key), diff --git a/lnbits/core/views/generic.py b/lnbits/core/views/generic.py index 630158f47..9f3cc5ede 100644 --- a/lnbits/core/views/generic.py +++ b/lnbits/core/views/generic.py @@ -11,7 +11,7 @@ from loguru import logger from pydantic.types import UUID4 from starlette.responses import HTMLResponse, JSONResponse -from lnbits.core import db +from lnbits.core.db import db from lnbits.core.helpers import to_valid_user_id from lnbits.core.models import User from lnbits.decorators import check_admin, check_user_exists @@ -36,24 +36,24 @@ from ..crud import ( ) from ..services import pay_invoice, redeem_lnurl_withdraw -core_html_routes: APIRouter = APIRouter( +generic_router = APIRouter( tags=["Core NON-API Website Routes"], include_in_schema=False ) -@core_html_routes.get("/favicon.ico", response_class=FileResponse) +@generic_router.get("/favicon.ico", response_class=FileResponse) async def favicon(): return FileResponse("lnbits/core/static/favicon.ico") -@core_html_routes.get("/", response_class=HTMLResponse) +@generic_router.get("/", response_class=HTMLResponse) async def home(request: Request, lightning: str = ""): return template_renderer().TemplateResponse( "core/index.html", {"request": request, "lnurl": lightning} ) -@core_html_routes.get("/robots.txt", response_class=HTMLResponse) +@generic_router.get("/robots.txt", response_class=HTMLResponse) async def robots(): data = """ User-agent: * @@ -62,7 +62,7 @@ async def robots(): return HTMLResponse(content=data, media_type="text/plain") -@core_html_routes.get( +@generic_router.get( "/extensions", name="install.extensions", response_class=HTMLResponse ) async def extensions_install( @@ -159,7 +159,7 @@ async def extensions_install( raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)) -@core_html_routes.get( +@generic_router.get( "/wallet", response_class=HTMLResponse, description=""" @@ -245,7 +245,7 @@ async def wallet( ) -@core_html_routes.get("/withdraw", response_class=JSONResponse) +@generic_router.get("/withdraw", response_class=JSONResponse) async def lnurl_full_withdraw(request: Request): user = await get_user(request.query_params.get("usr")) if not user: @@ -268,7 +268,7 @@ async def lnurl_full_withdraw(request: Request): } -@core_html_routes.get("/withdraw/cb", response_class=JSONResponse) +@generic_router.get("/withdraw/cb", response_class=JSONResponse) async def lnurl_full_withdraw_callback(request: Request): user = await get_user(request.query_params.get("usr")) if not user: @@ -295,7 +295,7 @@ async def lnurl_full_withdraw_callback(request: Request): return {"status": "OK"} -@core_html_routes.get("/deletewallet", response_class=RedirectResponse) +@generic_router.get("/deletewallet", response_class=RedirectResponse) async def deletewallet(wal: str = Query(...), usr: str = Query(...)): user = await get_user(usr) if not user: @@ -321,14 +321,14 @@ async def deletewallet(wal: str = Query(...), usr: str = Query(...)): ) -@core_html_routes.get("/withdraw/notify/{service}") +@generic_router.get("/withdraw/notify/{service}") async def lnurl_balance_notify(request: Request, service: str): bc = await get_balance_check(request.query_params.get("wal"), service) if bc: await redeem_lnurl_withdraw(bc.wallet, bc.url) -@core_html_routes.get( +@generic_router.get( "/lnurlwallet", response_class=RedirectResponse, name="core.lnurlwallet" ) async def lnurlwallet(request: Request): @@ -354,12 +354,12 @@ async def lnurlwallet(request: Request): ) -@core_html_routes.get("/service-worker.js", response_class=FileResponse) +@generic_router.get("/service-worker.js", response_class=FileResponse) async def service_worker(): return FileResponse("lnbits/core/static/js/service-worker.js") -@core_html_routes.get("/manifest/{usr}.webmanifest") +@generic_router.get("/manifest/{usr}.webmanifest") async def manifest(request: Request, usr: str): host = urlparse(str(request.url)).netloc @@ -400,7 +400,7 @@ async def manifest(request: Request, usr: str): } -@core_html_routes.get("/admin", response_class=HTMLResponse) +@generic_router.get("/admin", response_class=HTMLResponse) async def index(request: Request, user: User = Depends(check_admin)): if not settings.lnbits_admin_ui: raise HTTPException(status_code=HTTPStatus.NOT_FOUND) @@ -420,7 +420,7 @@ async def index(request: Request, user: User = Depends(check_admin)): ) -@core_html_routes.get("/uuidv4/{hex_value}") +@generic_router.get("/uuidv4/{hex_value}") async def hex_to_uuid4(hex_value: str): try: user_id = to_valid_user_id(hex_value).hex diff --git a/lnbits/core/views/public_api.py b/lnbits/core/views/public_api.py index bbc33195a..44d1495b4 100644 --- a/lnbits/core/views/public_api.py +++ b/lnbits/core/views/public_api.py @@ -2,17 +2,18 @@ import asyncio import datetime from http import HTTPStatus -from fastapi import HTTPException +from fastapi import APIRouter, HTTPException from loguru import logger from lnbits import bolt11 -from .. import core_app from ..crud import get_standalone_payment from ..tasks import api_invoice_listeners +public_router = APIRouter() -@core_app.get("/public/v1/payment/{payment_hash}") + +@public_router.get("/public/v1/payment/{payment_hash}") async def api_public_payment_longpolling(payment_hash): payment = await get_standalone_payment(payment_hash) diff --git a/lnbits/middleware.py b/lnbits/middleware.py index 83b2dcd1b..65ca76986 100644 --- a/lnbits/middleware.py +++ b/lnbits/middleware.py @@ -10,7 +10,7 @@ from slowapi.middleware import SlowAPIMiddleware from starlette.middleware.gzip import GZipMiddleware from starlette.types import ASGIApp, Receive, Scope, Send -from lnbits.core import core_app_extra +from lnbits.core.db import core_app_extra from lnbits.helpers import template_renderer from lnbits.settings import settings diff --git a/lnbits/tasks.py b/lnbits/tasks.py index 6026b1a5a..a9b97f8a2 100644 --- a/lnbits/tasks.py +++ b/lnbits/tasks.py @@ -18,12 +18,11 @@ from lnbits.core.crud import ( get_payments, get_standalone_payment, ) +from lnbits.core.db import db from lnbits.core.services import redeem_lnurl_withdraw from lnbits.settings import settings from lnbits.wallets import get_wallet_class -from .core import db - tasks: List[asyncio.Task] = [] diff --git a/lnbits/wallets/corelightningrest.py b/lnbits/wallets/corelightningrest.py index 3e8e2a39b..0aff63d2e 100644 --- a/lnbits/wallets/corelightningrest.py +++ b/lnbits/wallets/corelightningrest.py @@ -184,7 +184,7 @@ class CoreLightningRestWallet(Wallet): return PaymentStatus(None) async def get_payment_status(self, checking_id: str) -> PaymentStatus: - from lnbits.core import get_standalone_payment + from lnbits.core.services import get_standalone_payment payment = await get_standalone_payment(checking_id) if not payment: diff --git a/pyproject.toml b/pyproject.toml index 1db1d03fb..f11b2ce2e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -122,9 +122,7 @@ line-length = 88 # Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default. # (`I`) is for `isort`. select = ["E", "F", "I"] -ignore = [ - "E402", # Module level import not at top of file -] +ignore = [] # Allow autofix for all enabled rules (when `--fix`) is provided. fixable = ["ALL"] diff --git a/tests/conftest.py b/tests/conftest.py index b5fd07ce6..117c0560a 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,3 +1,4 @@ +# ruff: noqa: E402 import asyncio import uvloop