From cef6382e7abed59bb1eeff515d80e0d22e2dddcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?dni=20=E2=9A=A1?= Date: Wed, 4 Jan 2023 12:21:12 +0100 Subject: [PATCH] fix mypy offlineshop issues --- lnbits/extensions/offlineshop/lnurl.py | 44 ++++++++++++---------- lnbits/extensions/offlineshop/models.py | 12 +++--- lnbits/extensions/offlineshop/views.py | 17 ++++++--- lnbits/extensions/offlineshop/views_api.py | 20 +++++----- pyproject.toml | 1 - 5 files changed, 51 insertions(+), 43 deletions(-) diff --git a/lnbits/extensions/offlineshop/lnurl.py b/lnbits/extensions/offlineshop/lnurl.py index f6ff0c368..4efc5dc89 100644 --- a/lnbits/extensions/offlineshop/lnurl.py +++ b/lnbits/extensions/offlineshop/lnurl.py @@ -1,15 +1,17 @@ -import hashlib - -from fastapi.params import Query -from lnurl import ( # type: ignore +from fastapi import Query +from lnurl import ( LnurlErrorResponse, LnurlPayActionResponse, LnurlPayResponse, ) +from lnurl.models import ( + LightningInvoice, + ClearnetUrl, + MilliSatoshi +) from starlette.requests import Request from lnbits.core.services import create_invoice -from lnbits.extensions.offlineshop.models import Item from lnbits.utils.exchange_rates import fiat_amount_as_satoshis from . import offlineshop_ext @@ -17,8 +19,8 @@ from .crud import get_item, get_shop @offlineshop_ext.get("/lnurl/{item_id}", name="offlineshop.lnurl_response") -async def lnurl_response(req: Request, item_id: int = Query(...)): - item = await get_item(item_id) # type: Item +async def lnurl_response(req: Request, item_id: int = Query(...)) -> dict: + item = await get_item(item_id) if not item: return {"status": "ERROR", "reason": "Item not found."} @@ -32,9 +34,9 @@ async def lnurl_response(req: Request, item_id: int = Query(...)): ) * 1000 resp = LnurlPayResponse( - callback=req.url_for("offlineshop.lnurl_callback", item_id=item.id), - min_sendable=price_msat, - max_sendable=price_msat, + callback=ClearnetUrl(req.url_for("offlineshop.lnurl_callback", item_id=item.id), scheme="https"), + minSendable=MilliSatoshi(price_msat), + maxSendable=MilliSatoshi(price_msat), metadata=await item.lnurlpay_metadata(), ) @@ -43,7 +45,7 @@ async def lnurl_response(req: Request, item_id: int = Query(...)): @offlineshop_ext.get("/lnurl/cb/{item_id}", name="offlineshop.lnurl_callback") async def lnurl_callback(request: Request, item_id: int): - item = await get_item(item_id) # type: Item + item = await get_item(item_id) if not item: return {"status": "ERROR", "reason": "Couldn't find item."} @@ -67,6 +69,7 @@ async def lnurl_callback(request: Request, item_id: int): ).dict() shop = await get_shop(item.shop) + assert shop try: payment_hash, payment_request = await create_invoice( @@ -77,14 +80,15 @@ async def lnurl_callback(request: Request, item_id: int): extra={"tag": "offlineshop", "item": item.id}, ) except Exception as exc: - return LnurlErrorResponse(reason=exc.message).dict() + return LnurlErrorResponse(reason=str(exc)).dict() - resp = LnurlPayActionResponse( - pr=payment_request, - success_action=item.success_action(shop, payment_hash, request) - if shop.method - else None, - routes=[], - ) + if shop.method: + success_action = item.success_action(shop, payment_hash, request) + assert success_action + resp = LnurlPayActionResponse( + pr=LightningInvoice(payment_request), + successAction=success_action, + routes=[], + ) - return resp.dict() + return resp.dict() diff --git a/lnbits/extensions/offlineshop/models.py b/lnbits/extensions/offlineshop/models.py index ca5c73a55..b5880cc10 100644 --- a/lnbits/extensions/offlineshop/models.py +++ b/lnbits/extensions/offlineshop/models.py @@ -5,9 +5,9 @@ from collections import OrderedDict from sqlite3 import Row from typing import Dict, List, Optional -from lnurl import encode as lnurl_encode # type: ignore -from lnurl.models import LnurlPaySuccessAction, UrlAction # type: ignore -from lnurl.types import LnurlPayMetadata # type: ignore +from lnurl import encode as lnurl_encode +from lnurl.models import UrlAction, Max144Str, ClearnetUrl +from lnurl.types import LnurlPayMetadata from pydantic import BaseModel from starlette.requests import Request @@ -119,11 +119,11 @@ class Item(BaseModel): def success_action( self, shop: Shop, payment_hash: str, req: Request - ) -> Optional[LnurlPaySuccessAction]: + ) -> Optional[UrlAction]: if not shop.wordlist: return None return UrlAction( - url=req.url_for("offlineshop.confirmation_code", p=payment_hash), - description="Open to get the confirmation code for your purchase.", + url=ClearnetUrl(req.url_for("offlineshop.confirmation_code", p=payment_hash), scheme="https"), + description=Max144Str("Open to get the confirmation code for your purchase."), ) diff --git a/lnbits/extensions/offlineshop/views.py b/lnbits/extensions/offlineshop/views.py index 34bb7a03e..f4b88f02d 100644 --- a/lnbits/extensions/offlineshop/views.py +++ b/lnbits/extensions/offlineshop/views.py @@ -3,8 +3,7 @@ from datetime import datetime from http import HTTPStatus from typing import List -from fastapi import HTTPException, Request -from fastapi.params import Depends, Query +from fastapi import HTTPException, Request, Depends, Query from starlette.responses import HTMLResponse from lnbits.core.crud import get_standalone_payment @@ -25,10 +24,10 @@ async def index(request: Request, user: User = Depends(check_user_exists)): @offlineshop_ext.get("/print", response_class=HTMLResponse) -async def print_qr_codes(request: Request, items: List[int] = None): +async def print_qr_codes(request: Request): items = [] for item_id in request.query_params.get("items").split(","): - item = await get_item(item_id) # type: Item + item = await get_item(item_id) if item: items.append( { @@ -53,7 +52,8 @@ async def confirmation_code(p: str = Query(...)): payment_hash = p await api_payment(payment_hash) - payment: Payment = await get_standalone_payment(payment_hash) + + payment = await get_standalone_payment(payment_hash) if not payment: raise HTTPException( status_code=HTTPStatus.NOT_FOUND, @@ -72,8 +72,13 @@ async def confirmation_code(p: str = Query(...)): detail="Too much time has passed." + style, ) - item = await get_item(payment.extra.get("item")) + assert payment.extra + item_id = payment.extra.get("item") + assert item_id + item = await get_item(item_id) + assert item shop = await get_shop(item.shop) + assert shop return ( f""" diff --git a/lnbits/extensions/offlineshop/views_api.py b/lnbits/extensions/offlineshop/views_api.py index 71583b9e2..c5ef6361a 100644 --- a/lnbits/extensions/offlineshop/views_api.py +++ b/lnbits/extensions/offlineshop/views_api.py @@ -1,13 +1,10 @@ from http import HTTPStatus from typing import Optional -from fastapi import Query -from fastapi.params import Depends +from pydantic import BaseModel +from fastapi import Query, Depends, Request, HTTPException, Response + from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl -from pydantic.main import BaseModel -from starlette.exceptions import HTTPException -from starlette.requests import Request -from starlette.responses import HTMLResponse # type: ignore from lnbits.decorators import WalletTypeInfo, get_key_type from lnbits.utils.exchange_rates import currencies @@ -34,6 +31,7 @@ async def api_shop_from_wallet( r: Request, wallet: WalletTypeInfo = Depends(get_key_type) ): shop = await get_or_create_shop_by_wallet(wallet.wallet.id) + assert shop items = await get_items(shop.id) try: return { @@ -62,6 +60,7 @@ async def api_add_or_update_item( data: CreateItemsData, item_id=None, wallet: WalletTypeInfo = Depends(get_key_type) ): shop = await get_or_create_shop_by_wallet(wallet.wallet.id) + assert shop if data.unit != "sat": data.price = data.price * 100 if item_id == None: @@ -71,11 +70,11 @@ async def api_add_or_update_item( data.name, data.description, data.image, - data.price, + int(data.price), data.unit, data.fiat_base_multiplier, ) - return HTMLResponse(status_code=HTTPStatus.CREATED) + return Response(status_code=HTTPStatus.CREATED) else: await update_item( shop.id, @@ -83,7 +82,7 @@ async def api_add_or_update_item( data.name, data.description, data.image, - data.price, + int(data.price), data.unit, data.fiat_base_multiplier, ) @@ -92,6 +91,7 @@ async def api_add_or_update_item( @offlineshop_ext.delete("/api/v1/offlineshop/items/{item_id}") async def api_delete_item(item_id, wallet: WalletTypeInfo = Depends(get_key_type)): shop = await get_or_create_shop_by_wallet(wallet.wallet.id) + assert shop await delete_item_from_shop(shop.id, item_id) return "", HTTPStatus.NO_CONTENT @@ -107,7 +107,7 @@ async def api_set_method( ): method = data.method - wordlist = data.wordlist.split("\n") if data.wordlist else None + wordlist = data.wordlist.split("\n") if data.wordlist else [] wordlist = [word.strip() for word in wordlist if word.strip()] shop = await get_or_create_shop_by_wallet(wallet.wallet.id) diff --git a/pyproject.toml b/pyproject.toml index 186e2123a..f1b4e05fa 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -99,7 +99,6 @@ exclude = """(?x)( | ^lnbits/extensions/lndhub. | ^lnbits/extensions/lnurldevice. | ^lnbits/extensions/lnurlp. - | ^lnbits/extensions/offlineshop. | ^lnbits/extensions/satspay. | ^lnbits/extensions/streamalerts. | ^lnbits/extensions/tpos.