[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 <jkranawetter05@gmail.com>
This commit is contained in:
dni ⚡ 2023-09-12 12:25:05 +02:00 committed by GitHub
parent f19d59d429
commit fee40d7321
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 110 additions and 103 deletions

View File

@ -33,14 +33,11 @@ from lnbits.utils.cache import cache
from lnbits.wallets import get_wallet_class, set_wallet_class from lnbits.wallets import get_wallet_class, set_wallet_class
from .commands import db_versions, load_disabled_extension_list, migrate_databases from .commands import db_versions, load_disabled_extension_list, migrate_databases
from .core import ( from .core import init_core_routers
add_installed_extension, from .core.db import core_app_extra
core_app,
core_app_extra,
update_installed_extension_state,
)
from .core.services import check_admin_settings, check_webpush_settings 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 .extension_manager import Extension, InstallableExtension, get_valid_extensions
from .helpers import template_renderer from .helpers import template_renderer
from .middleware import ( from .middleware import (
@ -257,8 +254,7 @@ async def restore_installed_extension(app: FastAPI, ext: InstallableExtension):
def register_routes(app: FastAPI) -> None: def register_routes(app: FastAPI) -> None:
"""Register FastAPI routes / LNbits extensions.""" """Register FastAPI routes / LNbits extensions."""
app.include_router(core_app) init_core_routers(app)
app.include_router(core_html_routes)
for ext in get_valid_extensions(): for ext in get_valid_extensions():
try: try:

View File

@ -1,15 +1,20 @@
from fastapi.routing import APIRouter from fastapi import APIRouter
from lnbits.core.models import CoreAppExtra from .db import core_app_extra, db
from lnbits.db import Database 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 * def init_core_routers(app):
from .views.api import * app.include_router(core_app)
from .views.generic import * app.include_router(generic_router)
from .views.public_api import * app.include_router(public_router)
app.include_router(api_router)
app.include_router(admin_router)

View File

@ -7,6 +7,7 @@ from uuid import UUID, uuid4
import shortuuid import shortuuid
from lnbits import bolt11 from lnbits import bolt11
from lnbits.core.db import db
from lnbits.core.models import WalletType from lnbits.core.models import WalletType
from lnbits.db import Connection, Database, Filters, Page from lnbits.db import Connection, Database, Filters, Page
from lnbits.extension_manager import InstallableExtension from lnbits.extension_manager import InstallableExtension
@ -18,7 +19,6 @@ from lnbits.settings import (
settings, settings,
) )
from . import db
from .models import ( from .models import (
BalanceCheck, BalanceCheck,
Payment, Payment,

5
lnbits/core/db.py Normal file
View File

@ -0,0 +1,5 @@
from lnbits.core.models import CoreAppExtra
from lnbits.db import Database
db = Database("database")
core_app_extra: CoreAppExtra = CoreAppExtra()

View File

@ -6,11 +6,11 @@ from uuid import UUID
import httpx import httpx
from loguru import logger from loguru import logger
from lnbits.core.db import db as core_db
from lnbits.db import Connection from lnbits.db import Connection
from lnbits.extension_manager import Extension from lnbits.extension_manager import Extension
from lnbits.settings import settings from lnbits.settings import settings
from . import db as core_db
from .crud import update_migration_version from .crud import update_migration_version

View File

@ -15,6 +15,7 @@ from py_vapid import Vapid
from py_vapid.utils import b64urlencode from py_vapid.utils import b64urlencode
from lnbits import bolt11 from lnbits import bolt11
from lnbits.core.db import db
from lnbits.db import Connection from lnbits.db import Connection
from lnbits.decorators import WalletTypeInfo, require_admin_key from lnbits.decorators import WalletTypeInfo, require_admin_key
from lnbits.helpers import url_for 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 import FAKE_WALLET, get_wallet_class, set_wallet_class
from lnbits.wallets.base import PaymentResponse, PaymentStatus from lnbits.wallets.base import PaymentResponse, PaymentStatus
from . import db
from .crud import ( from .crud import (
check_internal, check_internal,
check_internal_pending, check_internal_pending,

View File

@ -4,6 +4,18 @@ from typing import Dict
import httpx import httpx
from loguru import logger 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.settings import get_wallet_class, settings
from lnbits.tasks import ( from lnbits.tasks import (
SseListenersDict, SseListenersDict,
@ -13,15 +25,6 @@ from lnbits.tasks import (
send_push_notification, 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: Dict[str, asyncio.Queue] = SseListenersDict(
"api_invoice_listeners" "api_invoice_listeners"
) )

View File

@ -6,7 +6,7 @@ from subprocess import Popen
from typing import Optional from typing import Optional
from urllib.parse import urlparse from urllib.parse import urlparse
from fastapi import Depends from fastapi import APIRouter, Depends
from fastapi.responses import FileResponse from fastapi.responses import FileResponse
from starlette.exceptions import HTTPException 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.server import server_restart
from lnbits.settings import AdminSettings, UpdateSettings, settings 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 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", "/admin/api/v1/audit",
name="Audit", name="Audit",
description="show the current balance of the node and the LNbits database", 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( async def api_get_settings(
user: User = Depends(check_admin), user: User = Depends(check_admin),
) -> Optional[AdminSettings]: ) -> Optional[AdminSettings]:
@ -54,7 +56,7 @@ async def api_get_settings(
return admin_settings return admin_settings
@core_app.put( @admin_router.put(
"/admin/api/v1/settings/", "/admin/api/v1/settings/",
status_code=HTTPStatus.OK, status_code=HTTPStatus.OK,
) )
@ -67,7 +69,7 @@ async def api_update_settings(data: UpdateSettings, user: User = Depends(check_a
return {"status": "Success"} return {"status": "Success"}
@core_app.delete( @admin_router.delete(
"/admin/api/v1/settings/", "/admin/api/v1/settings/",
status_code=HTTPStatus.OK, status_code=HTTPStatus.OK,
dependencies=[Depends(check_super_user)], dependencies=[Depends(check_super_user)],
@ -77,7 +79,7 @@ async def api_delete_settings() -> None:
server_restart.set() server_restart.set()
@core_app.get( @admin_router.get(
"/admin/api/v1/restart/", "/admin/api/v1/restart/",
status_code=HTTPStatus.OK, status_code=HTTPStatus.OK,
dependencies=[Depends(check_super_user)], dependencies=[Depends(check_super_user)],
@ -87,7 +89,7 @@ async def api_restart_server() -> dict[str, str]:
return {"status": "Success"} return {"status": "Success"}
@core_app.put( @admin_router.put(
"/admin/api/v1/topup/", "/admin/api/v1/topup/",
name="Topup", name="Topup",
status_code=HTTPStatus.OK, status_code=HTTPStatus.OK,
@ -111,7 +113,7 @@ async def api_topup_balance(data: CreateTopup) -> dict[str, str]:
return {"status": "Success"} return {"status": "Success"}
@core_app.get( @admin_router.get(
"/admin/api/v1/backup/", "/admin/api/v1/backup/",
status_code=HTTPStatus.OK, status_code=HTTPStatus.OK,
dependencies=[Depends(check_super_user)], dependencies=[Depends(check_super_user)],

View File

@ -11,6 +11,7 @@ from urllib.parse import ParseResult, parse_qs, unquote, urlencode, urlparse, ur
import httpx import httpx
import pyqrcode import pyqrcode
from fastapi import ( from fastapi import (
APIRouter,
Body, Body,
Depends, Depends,
Header, Header,
@ -25,6 +26,7 @@ from sse_starlette.sse import EventSourceResponse
from starlette.responses import RedirectResponse, StreamingResponse from starlette.responses import RedirectResponse, StreamingResponse
from lnbits import bolt11, lnurl from lnbits import bolt11, lnurl
from lnbits.core.db import core_app_extra, db
from lnbits.core.helpers import ( from lnbits.core.helpers import (
migrate_extension_database, migrate_extension_database,
stop_extension_background_work, stop_extension_background_work,
@ -68,7 +70,6 @@ from lnbits.utils.exchange_rates import (
satoshis_amount_as_fiat, satoshis_amount_as_fiat,
) )
from .. import core_app, core_app_extra, db
from ..crud import ( from ..crud import (
add_installed_extension, add_installed_extension,
create_tinyurl, create_tinyurl,
@ -101,13 +102,15 @@ from ..services import (
) )
from ..tasks import api_invoice_listeners 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(): async def health():
return return
@core_app.get("/api/v1/wallet") @api_router.get("/api/v1/wallet")
async def api_wallet(wallet: WalletTypeInfo = Depends(get_key_type)): async def api_wallet(wallet: WalletTypeInfo = Depends(get_key_type)):
if wallet.wallet_type == WalletType.admin: if wallet.wallet_type == WalletType.admin:
return { 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} 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( async def api_update_wallet_name(
new_name: str, wallet: WalletTypeInfo = Depends(require_admin_key) 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( async def api_update_wallet(
name: Optional[str] = Body(None), name: Optional[str] = Body(None),
currency: 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) return await update_wallet(wallet.wallet.id, name, currency)
@core_app.get( @api_router.get(
"/api/v1/payments", "/api/v1/payments",
name="Payment List", name="Payment List",
summary="get list of payments", summary="get list of payments",
@ -170,7 +173,7 @@ async def api_payments(
) )
@core_app.get( @api_router.get(
"/api/v1/payments/paginated", "/api/v1/payments/paginated",
name="Payment List", name="Payment List",
summary="get paginated list of payments", 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", "/api/v1/payments",
summary="Create or pay an invoice", summary="Create or pay an invoice",
description=""" 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( async def api_payments_pay_lnurl(
data: CreateLnurl, wallet: WalletTypeInfo = Depends(require_admin_key) data: CreateLnurl, wallet: WalletTypeInfo = Depends(require_admin_key)
): ):
@ -455,7 +458,7 @@ async def subscribe_wallet_invoices(request: Request, wallet: Wallet):
return return
@core_app.get("/api/v1/payments/sse") @api_router.get("/api/v1/payments/sse")
async def api_payments_sse( async def api_payments_sse(
request: Request, wallet: WalletTypeInfo = Depends(get_key_type) 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 # 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)): 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 # 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 # 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} 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)): async def api_lnurlscan(code: str, wallet: WalletTypeInfo = Depends(get_key_type)):
try: try:
url = lnurl.decode(code) url = lnurl.decode(code)
@ -627,7 +630,7 @@ async def api_lnurlscan(code: str, wallet: WalletTypeInfo = Depends(get_key_type
return params 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): async def api_payments_decode(data: DecodePayment, response: Response):
payment_str = data.data payment_str = data.data
try: try:
@ -653,7 +656,7 @@ async def api_payments_decode(data: DecodePayment, response: Response):
return {"message": "Failed to decode"} return {"message": "Failed to decode"}
@core_app.post("/api/v1/lnurlauth") @api_router.post("/api/v1/lnurlauth")
async def api_perform_lnurlauth( async def api_perform_lnurlauth(
data: CreateLnurlAuth, wallet: WalletTypeInfo = Depends(require_admin_key) data: CreateLnurlAuth, wallet: WalletTypeInfo = Depends(require_admin_key)
): ):
@ -665,7 +668,7 @@ async def api_perform_lnurlauth(
return "" return ""
@core_app.get("/api/v1/currencies") @api_router.get("/api/v1/currencies")
async def api_list_currencies_available(): async def api_list_currencies_available():
if len(settings.lnbits_allowed_currencies) > 0: if len(settings.lnbits_allowed_currencies) > 0:
return [ return [
@ -676,7 +679,7 @@ async def api_list_currencies_available():
return list(currencies.keys()) return list(currencies.keys())
@core_app.post("/api/v1/conversion") @api_router.post("/api/v1/conversion")
async def api_fiat_as_sats(data: ConversionData): async def api_fiat_as_sats(data: ConversionData):
output = {} output = {}
if data.from_ == "sat": if data.from_ == "sat":
@ -694,7 +697,7 @@ async def api_fiat_as_sats(data: ConversionData):
return output 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): async def img(data):
qr = pyqrcode.create(data) qr = pyqrcode.create(data)
stream = BytesIO() 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): async def websocket_connect(websocket: WebSocket, item_id: str):
await websocketManager.connect(websocket, item_id) await websocketManager.connect(websocket, item_id)
try: try:
@ -725,7 +728,7 @@ async def websocket_connect(websocket: WebSocket, item_id: str):
websocketManager.disconnect(websocket) 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): async def websocket_update_post(item_id: str, data: str):
try: try:
await websocketUpdater(item_id, data) await websocketUpdater(item_id, data)
@ -734,7 +737,7 @@ async def websocket_update_post(item_id: str, data: str):
return {"sent": False, "data": data} 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): async def websocket_update_get(item_id: str, data: str):
try: try:
await websocketUpdater(item_id, data) await websocketUpdater(item_id, data)
@ -743,7 +746,7 @@ async def websocket_update_get(item_id: str, data: str):
return {"sent": False, "data": data} return {"sent": False, "data": data}
@core_app.post("/api/v1/extension") @api_router.post("/api/v1/extension")
async def api_install_extension( async def api_install_extension(
data: CreateExtension, user: User = Depends(check_admin) 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)): async def api_uninstall_extension(ext_id: str, user: User = Depends(check_admin)):
installable_extensions = await InstallableExtension.get_installable_extensions() 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)] "/api/v1/extension/{ext_id}/releases", dependencies=[Depends(check_admin)]
) )
async def get_extension_releases(ext_id: str): 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}", "/api/v1/extension/release/{org}/{repo}/{tag_name}",
dependencies=[Depends(check_admin)], 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", "/api/v1/extension/{ext_id}/db",
dependencies=[Depends(check_admin)], dependencies=[Depends(check_admin)],
) )
@ -909,10 +912,7 @@ async def delete_extension_db(ext_id: str):
) )
# TINYURL @api_router.post(
@core_app.post(
"/api/v1/tinyurl", "/api/v1/tinyurl",
name="Tinyurl", name="Tinyurl",
description="creates a 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}", "/api/v1/tinyurl/{tinyurl_id}",
name="Tinyurl", name="Tinyurl",
description="get a tinyurl by id", 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}", "/api/v1/tinyurl/{tinyurl_id}",
name="Tinyurl", name="Tinyurl",
description="delete a tinyurl by id", description="delete a tinyurl by id",
@ -978,7 +978,7 @@ async def api_delete_tinyurl(
) )
@core_app.get( @api_router.get(
"/t/{tinyurl_id}", "/t/{tinyurl_id}",
name="Tinyurl", name="Tinyurl",
description="redirects a tinyurl by id", description="redirects a tinyurl by id",
@ -994,10 +994,7 @@ async def api_tinyurl(tinyurl_id: str):
) )
############################WEBPUSH################################## @api_router.post("/api/v1/webpush", status_code=HTTPStatus.CREATED)
@core_app.post("/api/v1/webpush", status_code=HTTPStatus.CREATED)
async def api_create_webpush_subscription( async def api_create_webpush_subscription(
request: Request, request: Request,
data: CreateWebPushSubscription, 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( async def api_delete_webpush_subscription(
request: Request, request: Request,
wallet: WalletTypeInfo = Depends(require_admin_key), wallet: WalletTypeInfo = Depends(require_admin_key),

View File

@ -11,7 +11,7 @@ from loguru import logger
from pydantic.types import UUID4 from pydantic.types import UUID4
from starlette.responses import HTMLResponse, JSONResponse 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.helpers import to_valid_user_id
from lnbits.core.models import User from lnbits.core.models import User
from lnbits.decorators import check_admin, check_user_exists from lnbits.decorators import check_admin, check_user_exists
@ -36,24 +36,24 @@ from ..crud import (
) )
from ..services import pay_invoice, redeem_lnurl_withdraw 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 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(): async def favicon():
return FileResponse("lnbits/core/static/favicon.ico") 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 = ""): async def home(request: Request, lightning: str = ""):
return template_renderer().TemplateResponse( return template_renderer().TemplateResponse(
"core/index.html", {"request": request, "lnurl": lightning} "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(): async def robots():
data = """ data = """
User-agent: * User-agent: *
@ -62,7 +62,7 @@ async def robots():
return HTMLResponse(content=data, media_type="text/plain") return HTMLResponse(content=data, media_type="text/plain")
@core_html_routes.get( @generic_router.get(
"/extensions", name="install.extensions", response_class=HTMLResponse "/extensions", name="install.extensions", response_class=HTMLResponse
) )
async def extensions_install( async def extensions_install(
@ -159,7 +159,7 @@ async def extensions_install(
raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e)) raise HTTPException(status_code=HTTPStatus.INTERNAL_SERVER_ERROR, detail=str(e))
@core_html_routes.get( @generic_router.get(
"/wallet", "/wallet",
response_class=HTMLResponse, response_class=HTMLResponse,
description=""" 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): async def lnurl_full_withdraw(request: Request):
user = await get_user(request.query_params.get("usr")) user = await get_user(request.query_params.get("usr"))
if not user: 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): async def lnurl_full_withdraw_callback(request: Request):
user = await get_user(request.query_params.get("usr")) user = await get_user(request.query_params.get("usr"))
if not user: if not user:
@ -295,7 +295,7 @@ async def lnurl_full_withdraw_callback(request: Request):
return {"status": "OK"} 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(...)): async def deletewallet(wal: str = Query(...), usr: str = Query(...)):
user = await get_user(usr) user = await get_user(usr)
if not user: 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): async def lnurl_balance_notify(request: Request, service: str):
bc = await get_balance_check(request.query_params.get("wal"), service) bc = await get_balance_check(request.query_params.get("wal"), service)
if bc: if bc:
await redeem_lnurl_withdraw(bc.wallet, bc.url) await redeem_lnurl_withdraw(bc.wallet, bc.url)
@core_html_routes.get( @generic_router.get(
"/lnurlwallet", response_class=RedirectResponse, name="core.lnurlwallet" "/lnurlwallet", response_class=RedirectResponse, name="core.lnurlwallet"
) )
async def lnurlwallet(request: Request): 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(): async def service_worker():
return FileResponse("lnbits/core/static/js/service-worker.js") 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): async def manifest(request: Request, usr: str):
host = urlparse(str(request.url)).netloc 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)): async def index(request: Request, user: User = Depends(check_admin)):
if not settings.lnbits_admin_ui: if not settings.lnbits_admin_ui:
raise HTTPException(status_code=HTTPStatus.NOT_FOUND) 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): async def hex_to_uuid4(hex_value: str):
try: try:
user_id = to_valid_user_id(hex_value).hex user_id = to_valid_user_id(hex_value).hex

View File

@ -2,17 +2,18 @@ import asyncio
import datetime import datetime
from http import HTTPStatus from http import HTTPStatus
from fastapi import HTTPException from fastapi import APIRouter, HTTPException
from loguru import logger from loguru import logger
from lnbits import bolt11 from lnbits import bolt11
from .. import core_app
from ..crud import get_standalone_payment from ..crud import get_standalone_payment
from ..tasks import api_invoice_listeners 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): async def api_public_payment_longpolling(payment_hash):
payment = await get_standalone_payment(payment_hash) payment = await get_standalone_payment(payment_hash)

View File

@ -10,7 +10,7 @@ from slowapi.middleware import SlowAPIMiddleware
from starlette.middleware.gzip import GZipMiddleware from starlette.middleware.gzip import GZipMiddleware
from starlette.types import ASGIApp, Receive, Scope, Send 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.helpers import template_renderer
from lnbits.settings import settings from lnbits.settings import settings

View File

@ -18,12 +18,11 @@ from lnbits.core.crud import (
get_payments, get_payments,
get_standalone_payment, get_standalone_payment,
) )
from lnbits.core.db import db
from lnbits.core.services import redeem_lnurl_withdraw from lnbits.core.services import redeem_lnurl_withdraw
from lnbits.settings import settings from lnbits.settings import settings
from lnbits.wallets import get_wallet_class from lnbits.wallets import get_wallet_class
from .core import db
tasks: List[asyncio.Task] = [] tasks: List[asyncio.Task] = []

View File

@ -184,7 +184,7 @@ class CoreLightningRestWallet(Wallet):
return PaymentStatus(None) return PaymentStatus(None)
async def get_payment_status(self, checking_id: str) -> PaymentStatus: 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) payment = await get_standalone_payment(checking_id)
if not payment: if not payment:

View File

@ -122,9 +122,7 @@ line-length = 88
# Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default. # Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default.
# (`I`) is for `isort`. # (`I`) is for `isort`.
select = ["E", "F", "I"] select = ["E", "F", "I"]
ignore = [ ignore = []
"E402", # Module level import not at top of file
]
# Allow autofix for all enabled rules (when `--fix`) is provided. # Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"] fixable = ["ALL"]

View File

@ -1,3 +1,4 @@
# ruff: noqa: E402
import asyncio import asyncio
import uvloop import uvloop