lntickets fastAPI refactoring

This commit is contained in:
Tiago vasconcelos
2021-08-22 11:31:04 +01:00
parent 5495dac6d3
commit 7f917b8ad5

View File

@@ -2,6 +2,11 @@ import re
from quart import g, jsonify, request from quart import g, jsonify, request
from http import HTTPStatus from http import HTTPStatus
from fastapi import FastAPI, Query
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from lnbits.core.crud import get_user, get_wallet from lnbits.core.crud import get_user, get_wallet
from lnbits.core.services import create_invoice, check_invoice_status from lnbits.core.services import create_invoice, check_invoice_status
from lnbits.decorators import api_check_wallet_key, api_validate_post_request from lnbits.decorators import api_check_wallet_key, api_validate_post_request
@@ -24,7 +29,7 @@ from .crud import (
# FORMS # FORMS
@lnticket_ext.route("/api/v1/forms", methods=["GET"]) @lnticket_ext.get("/api/v1/forms")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_forms(): async def api_forms():
wallet_ids = [g.wallet.id] wallet_ids = [g.wallet.id]
@@ -33,50 +38,57 @@ async def api_forms():
wallet_ids = (await get_user(g.wallet.user)).wallet_ids wallet_ids = (await get_user(g.wallet.user)).wallet_ids
return ( return (
jsonify([form._asdict() for form in await get_forms(wallet_ids)]), [form._asdict() for form in await get_forms(wallet_ids)],
HTTPStatus.OK, HTTPStatus.OK,
) )
class CreateData(BaseModel):
wallet: str = Query(...)
name: str = Query(...)
webhook: str = Query(None)
description: str = Query(..., min_length=0)
amount: int = Query(..., ge=0)
flatrate: int = Query(...)
@lnticket_ext.route("/api/v1/forms", methods=["POST"]) @lnticket_ext.post("/api/v1/forms")
@lnticket_ext.route("/api/v1/forms/<form_id>", methods=["PUT"]) @lnticket_ext.put("/api/v1/forms/{form_id}")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
@api_validate_post_request( # @api_validate_post_request(
schema={ # schema={
"wallet": {"type": "string", "empty": False, "required": True}, # "wallet": {"type": "string", "empty": False, "required": True},
"name": {"type": "string", "empty": False, "required": True}, # "name": {"type": "string", "empty": False, "required": True},
"webhook": {"type": "string", "required": False}, # "webhook": {"type": "string", "required": False},
"description": {"type": "string", "min": 0, "required": True}, # "description": {"type": "string", "min": 0, "required": True},
"amount": {"type": "integer", "min": 0, "required": True}, # "amount": {"type": "integer", "min": 0, "required": True},
"flatrate": {"type": "integer", "required": True}, # "flatrate": {"type": "integer", "required": True},
} # }
) # )
async def api_form_create(form_id=None): async def api_form_create(data: CreateData, form_id=None):
if form_id: if form_id:
form = await get_form(form_id) form = await get_form(form_id)
if not form: if not form:
return jsonify({"message": "Form does not exist."}), HTTPStatus.NOT_FOUND return {"message": "Form does not exist."}, HTTPStatus.NOT_FOUND
if form.wallet != g.wallet.id: if form.wallet != g.wallet.id:
return jsonify({"message": "Not your form."}), HTTPStatus.FORBIDDEN return jsonify{"message": "Not your form."}, HTTPStatus.FORBIDDEN
form = await update_form(form_id, **g.data) form = await update_form(form_id, **data)
else: else:
form = await create_form(**g.data) form = await create_form(**data)
return jsonify(form._asdict()), HTTPStatus.CREATED return form._asdict(), HTTPStatus.CREATED
@lnticket_ext.route("/api/v1/forms/<form_id>", methods=["DELETE"]) @lnticket_ext.delete("/api/v1/forms/{form_id}")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_form_delete(form_id): async def api_form_delete(form_id):
form = await get_form(form_id) form = await get_form(form_id)
if not form: if not form:
return jsonify({"message": "Form does not exist."}), HTTPStatus.NOT_FOUND return {"message": "Form does not exist."}, HTTPStatus.NOT_FOUND
if form.wallet != g.wallet.id: if form.wallet != g.wallet.id:
return jsonify({"message": "Not your form."}), HTTPStatus.FORBIDDEN return {"message": "Not your form."}, HTTPStatus.FORBIDDEN
await delete_form(form_id) await delete_form(form_id)
@@ -86,37 +98,43 @@ async def api_form_delete(form_id):
#########tickets########## #########tickets##########
@lnticket_ext.route("/api/v1/tickets", methods=["GET"]) @lnticket_ext.get("/api/v1/tickets")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_tickets(): async def api_tickets(all_wallets: bool = Query(None)):
wallet_ids = [g.wallet.id] wallet_ids = [g.wallet.id]
if "all_wallets" in request.args: if all_wallets:
wallet_ids = (await get_user(g.wallet.user)).wallet_ids wallet_ids = (await get_user(g.wallet.user)).wallet_ids
return ( return (
jsonify([form._asdict() for form in await get_tickets(wallet_ids)]), [form._asdict() for form in await get_tickets(wallet_ids)],
HTTPStatus.OK, HTTPStatus.OK,
) )
class CreateTicketData(BaseModel):
form: str = Query(...)
name: str = Query(...)
email: str = Query("")
ltext: str = Query(...)
sats: int = Query(..., ge=0)
@lnticket_ext.route("/api/v1/tickets/<form_id>", methods=["POST"]) @lnticket_ext.post("/api/v1/tickets/{form_id}")
@api_validate_post_request( # @api_validate_post_request(
schema={ # schema={
"form": {"type": "string", "empty": False, "required": True}, # "form": {"type": "string", "empty": False, "required": True},
"name": {"type": "string", "empty": False, "required": True}, # "name": {"type": "string", "empty": False, "required": True},
"email": {"type": "string", "empty": True, "required": True}, # "email": {"type": "string", "empty": True, "required": True},
"ltext": {"type": "string", "empty": False, "required": True}, # "ltext": {"type": "string", "empty": False, "required": True},
"sats": {"type": "integer", "min": 0, "required": True}, # "sats": {"type": "integer", "min": 0, "required": True},
} # }
) # )
async def api_ticket_make_ticket(form_id): async def api_ticket_make_ticket(data: CreateTicketData, form_id):
form = await get_form(form_id) form = await get_form(form_id)
if not form: if not form:
return jsonify({"message": "LNTicket does not exist."}), HTTPStatus.NOT_FOUND return {"message": "LNTicket does not exist."}, HTTPStatus.NOT_FOUND
nwords = len(re.split(r"\s+", g.data["ltext"])) nwords = len(re.split(r"\s+", data["ltext"]))
sats = g.data["sats"] sats = data["sats"]
try: try:
payment_hash, payment_request = await create_invoice( payment_hash, payment_request = await create_invoice(
@@ -126,53 +144,52 @@ async def api_ticket_make_ticket(form_id):
extra={"tag": "lnticket"}, extra={"tag": "lnticket"},
) )
except Exception as e: except Exception as e:
return jsonify({"message": str(e)}), HTTPStatus.INTERNAL_SERVER_ERROR return {"message": str(e)}, HTTPStatus.INTERNAL_SERVER_ERROR
ticket = await create_ticket( ticket = await create_ticket(
payment_hash=payment_hash, wallet=form.wallet, **g.data payment_hash=payment_hash, wallet=form.wallet, **data
) )
if not ticket: if not ticket:
return ( return (
jsonify({"message": "LNTicket could not be fetched."}), {"message": "LNTicket could not be fetched."},
HTTPStatus.NOT_FOUND, HTTPStatus.NOT_FOUND,
) )
return ( return
jsonify({"payment_hash": payment_hash, "payment_request": payment_request}), {"payment_hash": payment_hash, "payment_request": payment_request},
HTTPStatus.OK, HTTPStatus.OK
)
@lnticket_ext.route("/api/v1/tickets/<payment_hash>", methods=["GET"]) @lnticket_ext.get("/api/v1/tickets/{payment_hash}")
async def api_ticket_send_ticket(payment_hash): async def api_ticket_send_ticket(payment_hash):
ticket = await get_ticket(payment_hash) ticket = await get_ticket(payment_hash)
try: try:
status = await check_invoice_status(ticket.wallet, payment_hash) status = await check_invoice_status(ticket.wallet, payment_hash)
is_paid = not status.pending is_paid = not status.pending
except Exception: except Exception:
return jsonify({"paid": False}), HTTPStatus.OK return {"paid": False}, HTTPStatus.OK
if is_paid: if is_paid:
wallet = await get_wallet(ticket.wallet) wallet = await get_wallet(ticket.wallet)
payment = await wallet.get_payment(payment_hash) payment = await wallet.get_payment(payment_hash)
await payment.set_pending(False) await payment.set_pending(False)
ticket = await set_ticket_paid(payment_hash=payment_hash) ticket = await set_ticket_paid(payment_hash=payment_hash)
return jsonify({"paid": True}), HTTPStatus.OK return {"paid": True}, HTTPStatus.OK
return jsonify({"paid": False}), HTTPStatus.OK return {"paid": False}, HTTPStatus.OK
@lnticket_ext.route("/api/v1/tickets/<ticket_id>", methods=["DELETE"]) @lnticket_ext.delete("/api/v1/tickets/{ticket_id}")
@api_check_wallet_key("invoice") @api_check_wallet_key("invoice")
async def api_ticket_delete(ticket_id): async def api_ticket_delete(ticket_id):
ticket = await get_ticket(ticket_id) ticket = await get_ticket(ticket_id)
if not ticket: if not ticket:
return jsonify({"message": "Paywall does not exist."}), HTTPStatus.NOT_FOUND return {"message": "Paywall does not exist."}, HTTPStatus.NOT_FOUND
if ticket.wallet != g.wallet.id: if ticket.wallet != g.wallet.id:
return jsonify({"message": "Not your ticket."}), HTTPStatus.FORBIDDEN return {"message": "Not your ticket."}, HTTPStatus.FORBIDDEN
await delete_ticket(ticket_id) await delete_ticket(ticket_id)