Merge pull request #316 from arcbtc/FastAPI

Front page loading!
This commit is contained in:
Arc 2021-08-23 18:23:58 +01:00 committed by GitHub
commit 89ffc621c4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 88 additions and 84 deletions

View File

@ -38,6 +38,7 @@ async def create_app(config_object="lnbits.settings") -> FastAPI:
"""
app = FastAPI()
app.mount("/static", StaticFiles(directory="lnbits/static"), name="static")
app.mount("/core/static", StaticFiles(directory="lnbits/core/static"), name="core_static")
origins = [
"http://localhost",

View File

@ -53,16 +53,16 @@ class CreateData(BaseModel):
price_per_ticket: int = Query(..., ge=0)
@events_ext.post("/api/v1/events")
@events_ext.put("/api/v1/events/<event_id>")
@events_ext.put("/api/v1/events/{event_id}")
@api_check_wallet_key("invoice")
async def api_event_create(data: CreateData, event_id=None):
if event_id:
event = await get_event(event_id)
if not event:
return jsonable_encoder({"message": "Form does not exist."}), HTTPStatus.NOT_FOUND
return {"message": "Form does not exist."}, HTTPStatus.NOT_FOUND
if event.wallet != g.wallet.id:
return jsonable_encoder({"message": "Not your event."}), HTTPStatus.FORBIDDEN
return {"message": "Not your event."}, HTTPStatus.FORBIDDEN
event = await update_event(event_id, **data)
else:
@ -71,15 +71,15 @@ async def api_event_create(data: CreateData, event_id=None):
return event._asdict(), HTTPStatus.CREATED
@events_ext.delete("/api/v1/events/<event_id>")
@events_ext.delete("/api/v1/events/{event_id}")
@api_check_wallet_key("invoice")
async def api_form_delete(event_id):
event = await get_event(event_id)
if not event:
return jsonable_encoder({"message": "Event does not exist."}), HTTPStatus.NOT_FOUND
return {"message": "Event does not exist."}, HTTPStatus.NOT_FOUND
if event.wallet != g.wallet.id:
return jsonable_encoder({"message": "Not your event."}), HTTPStatus.FORBIDDEN
return {"message": "Not your event."}, HTTPStatus.FORBIDDEN
await delete_event(event_id)
return "", HTTPStatus.NO_CONTENT
@ -105,11 +105,11 @@ class CreateTicketData(BaseModel):
name: str = Query(...)
email: str
@events_ext.post("/api/v1/tickets/<event_id>/<sats>")
@events_ext.post("/api/v1/tickets/{event_id}/{sats}")
async def api_ticket_make_ticket(data: CreateTicketData, event_id, sats):
event = await get_event(event_id)
if not event:
return jsonable_encoder({"message": "Event does not exist."}), HTTPStatus.NOT_FOUND
return {"message": "Event does not exist."}, HTTPStatus.NOT_FOUND
try:
payment_hash, payment_request = await create_invoice(
wallet_id=event.wallet,
@ -118,22 +118,19 @@ async def api_ticket_make_ticket(data: CreateTicketData, event_id, sats):
extra={"tag": "events"},
)
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(
payment_hash=payment_hash, wallet=event.wallet, event=event_id, **data
)
if not ticket:
return jsonable_encoder({"message": "Event could not be fetched."}), HTTPStatus.NOT_FOUND
return {"message": "Event could not be fetched."}, HTTPStatus.NOT_FOUND
return (
jsonable_encoder({"payment_hash": payment_hash, "payment_request": payment_request}),
HTTPStatus.OK,
)
return {"payment_hash": payment_hash, "payment_request": payment_request}, HTTPStatus.OK
@events_ext.get("/api/v1/tickets/<payment_hash>")
@events_ext.get("/api/v1/tickets/{payment_hash}")
async def api_ticket_send_ticket(payment_hash):
ticket = await get_ticket(payment_hash)
@ -141,7 +138,7 @@ async def api_ticket_send_ticket(payment_hash):
status = await check_invoice_status(ticket.wallet, payment_hash)
is_paid = not status.pending
except Exception:
return jsonable_encoder({"message": "Not paid."}), HTTPStatus.NOT_FOUND
return {"message": "Not paid."}, HTTPStatus.NOT_FOUND
if is_paid:
wallet = await get_wallet(ticket.wallet)
@ -149,21 +146,21 @@ async def api_ticket_send_ticket(payment_hash):
await payment.set_pending(False)
ticket = await set_ticket_paid(payment_hash=payment_hash)
return jsonable_encoder({"paid": True, "ticket_id": ticket.id}), HTTPStatus.OK
return {"paid": True, "ticket_id": ticket.id}, HTTPStatus.OK
return jsonable_encoder({"paid": False}), HTTPStatus.OK
return {"paid": False}, HTTPStatus.OK
@events_ext.delete("/api/v1/tickets/<ticket_id>")
@events_ext.delete("/api/v1/tickets/{ticket_id}")
@api_check_wallet_key("invoice")
async def api_ticket_delete(ticket_id):
ticket = await get_ticket(ticket_id)
if not ticket:
return jsonable_encoder({"message": "Ticket does not exist."}), HTTPStatus.NOT_FOUND
return {"message": "Ticket does not exist."}, HTTPStatus.NOT_FOUND
if ticket.wallet != g.wallet.id:
return jsonable_encoder({"message": "Not your ticket."}), HTTPStatus.FORBIDDEN
return {"message": "Not your ticket."}, HTTPStatus.FORBIDDEN
await delete_ticket(ticket_id)
return "", HTTPStatus.NO_CONTENT
@ -172,26 +169,23 @@ async def api_ticket_delete(ticket_id):
# Event Tickets
@events_ext.get("/api/v1/eventtickets/<wallet_id>/<event_id>")
@events_ext.get("/api/v1/eventtickets/{wallet_id}/{event_id]")
async def api_event_tickets(wallet_id, event_id):
return ([ticket._asdict() for ticket in await get_event_tickets(wallet_id=wallet_id, event_id=event_id)],
HTTPStatus.OK,
)
@events_ext.get("/api/v1/register/ticket/<ticket_id>")
@events_ext.get("/api/v1/register/ticket/{ticket_id}")
async def api_event_register_ticket(ticket_id):
ticket = await get_ticket(ticket_id)
if not ticket:
return jsonable_encoder({"message": "Ticket does not exist."}), HTTPStatus.FORBIDDEN
return {"message": "Ticket does not exist."}, HTTPStatus.FORBIDDEN
if not ticket.paid:
return jsonable_encoder({"message": "Ticket not paid for."}), HTTPStatus.FORBIDDEN
return {"message": "Ticket not paid for."}, HTTPStatus.FORBIDDEN
if ticket.registered == True:
return jsonable_encoder({"message": "Ticket already registered"}), HTTPStatus.FORBIDDEN
return {"message": "Ticket already registered"}, HTTPStatus.FORBIDDEN
return (
[ticket._asdict() for ticket in await reg_ticket(ticket_id)],
HTTPStatus.OK,
)
return [ticket._asdict() for ticket in await reg_ticket(ticket_id)], HTTPStatus.OK

View File

@ -40,7 +40,7 @@ async def api_get_jukeboxs():
##################SPOTIFY AUTH#####################
@jukebox_ext.get("/api/v1/jukebox/spotify/cb/<juke_id>")
@jukebox_ext.get("/api/v1/jukebox/spotify/cb/{juke_id}")
async def api_check_credentials_callbac(juke_id):
sp_code = ""
sp_access_token = ""
@ -69,7 +69,7 @@ async def api_check_credentials_callbac(juke_id):
return "<h1>Success!</h1><h2>You can close this window</h2>"
@jukebox_ext.get("/api/v1/jukebox/<juke_id>")
@jukebox_ext.get("/api/v1/jukebox/{juke_id}")
@api_check_wallet_key("admin")
async def api_check_credentials_check(juke_id):
jukebox = await get_jukebox(juke_id)
@ -89,7 +89,7 @@ class CreateData(BaseModel):
price: Optional[str] = None
@jukebox_ext.post("/api/v1/jukebox/")
@jukebox_ext.put("/api/v1/jukebox/<juke_id>")
@jukebox_ext.put("/api/v1/jukebox/{juke_id}")
@api_check_wallet_key("admin")
async def api_create_update_jukebox(data: CreateData, juke_id=None):
if juke_id:
@ -100,7 +100,7 @@ async def api_create_update_jukebox(data: CreateData, juke_id=None):
return jukebox._asdict(), HTTPStatus.CREATED
@jukebox_ext.delete("/api/v1/jukebox/<juke_id>")
@jukebox_ext.delete("/api/v1/jukebox/{juke_id}")
@api_check_wallet_key("admin")
async def api_delete_item(juke_id):
await delete_jukebox(juke_id)
@ -120,7 +120,7 @@ async def api_delete_item(juke_id):
@jukebox_ext.get(
"/api/v1/jukebox/jb/playlist/<juke_id>/<sp_playlist>"
"/api/v1/jukebox/jb/playlist/{juke_id}/{sp_playlist}"
)
async def api_get_jukebox_song(juke_id, sp_playlist, retry=False):
try:
@ -210,7 +210,7 @@ async def api_get_token(juke_id):
######CHECK DEVICE
@jukebox_ext.get("/api/v1/jukebox/jb/<juke_id>")
@jukebox_ext.get("/api/v1/jukebox/jb/{juke_id}")
async def api_get_jukebox_device_check(juke_id, retry=False):
try:
jukebox = await get_jukebox(juke_id)
@ -255,7 +255,7 @@ async def api_get_jukebox_device_check(juke_id, retry=False):
######GET INVOICE STUFF
@jukebox_ext.get("/api/v1/jukebox/jb/invoice/<juke_id>/<song_id>")
@jukebox_ext.get("/api/v1/jukebox/jb/invoice/{juke_id}/{song_id}")
async def api_get_jukebox_invoice(juke_id, song_id):
try:
jukebox = await get_jukebox(juke_id)
@ -295,7 +295,7 @@ async def api_get_jukebox_invoice(juke_id, song_id):
@jukebox_ext.get(
"/api/v1/jukebox/jb/checkinvoice/<pay_hash>/<juke_id>"
"/api/v1/jukebox/jb/checkinvoice/{pay_hash}/{juke_id}"
)
async def api_get_jukebox_invoice_check(pay_hash, juke_id):
try:
@ -320,7 +320,7 @@ async def api_get_jukebox_invoice_check(pay_hash, juke_id):
@jukebox_ext.get(
"/api/v1/jukebox/jb/invoicep/<song_id>/<juke_id>/<pay_hash>"
"/api/v1/jukebox/jb/invoicep/{song_id}/{juke_id}/{pay_hash}"
)
async def api_get_jukebox_invoice_paid(song_id, juke_id, pay_hash, retry=False):
try:
@ -437,7 +437,7 @@ async def api_get_jukebox_invoice_paid(song_id, juke_id, pay_hash, retry=False):
############################GET TRACKS
@jukebox_ext.get("/api/v1/jukebox/jb/currently/<juke_id>")
@jukebox_ext.get("/api/v1/jukebox/jb/currently/{juke_id}")
async def api_get_jukebox_currently(juke_id, retry=False):
try:
jukebox = await get_jukebox(juke_id)

View File

@ -4,6 +4,11 @@ from lnurl.exceptions import InvalidUrl as LnurlInvalidUrl # type: ignore
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
from fastapi import FastAPI, Query
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from pydantic import BaseModel
from . import livestream_ext
from .crud import (
get_or_create_livestream_by_wallet,
@ -18,7 +23,7 @@ from .crud import (
)
@livestream_ext.route("/api/v1/livestream", methods=["GET"])
@livestream_ext.get("/api/v1/livestream")
@api_check_wallet_key("invoice")
async def api_livestream_from_wallet():
ls = await get_or_create_livestream_by_wallet(g.wallet.id)
@ -26,8 +31,7 @@ async def api_livestream_from_wallet():
producers = await get_producers(ls.id)
try:
return (
jsonify(
return
{
**ls._asdict(),
**{
@ -39,21 +43,19 @@ async def api_livestream_from_wallet():
"producers": [producer._asdict() for producer in producers],
},
}
),
HTTPStatus.OK,
)
,
HTTPStatus.OK
except LnurlInvalidUrl:
return (
jsonify(
return
{
"message": "LNURLs need to be delivered over a publically accessible `https` domain or Tor."
}
),
HTTPStatus.UPGRADE_REQUIRED,
)
,
HTTPStatus.UPGRADE_REQUIRED
@livestream_ext.route("/api/v1/livestream/track/<track_id>", methods=["PUT"])
@livestream_ext.put("/api/v1/livestream/track/{track_id}")
@api_check_wallet_key("invoice")
async def api_update_track(track_id):
try:
@ -68,7 +70,7 @@ async def api_update_track(track_id):
return "", HTTPStatus.NO_CONTENT
@livestream_ext.route("/api/v1/livestream/fee/<fee_pct>", methods=["PUT"])
@livestream_ext.put("/api/v1/livestream/fee/{fee_pct}")
@api_check_wallet_key("invoice")
async def api_update_fee(fee_pct):
ls = await get_or_create_livestream_by_wallet(g.wallet.id)
@ -76,33 +78,40 @@ async def api_update_fee(fee_pct):
return "", HTTPStatus.NO_CONTENT
@livestream_ext.route("/api/v1/livestream/tracks", methods=["POST"])
@livestream_ext.route("/api/v1/livestream/tracks/<id>", methods=["PUT"])
class CreateData(BaseModel):
name: str
download_url: str = Query(None)
price_msat: int = Query(None, ge=0)
producer_id: int #missing the exclude thing
producer_name: str #missing the exclude thing
@livestream_ext.post("/api/v1/livestream/tracks")
@livestream_ext.put("/api/v1/livestream/tracks/{id}")
@api_check_wallet_key("invoice")
@api_validate_post_request(
schema={
"name": {"type": "string", "empty": False, "required": True},
"download_url": {"type": "string", "empty": False, "required": False},
"price_msat": {"type": "number", "min": 0, "required": False},
"producer_id": {
"type": "number",
"required": True,
"excludes": "producer_name",
},
"producer_name": {
"type": "string",
"required": True,
"excludes": "producer_id",
},
}
)
async def api_add_track(id=None):
# @api_validate_post_request(
# schema={
# "name": {"type": "string", "empty": False, "required": True},
# "download_url": {"type": "string", "empty": False, "required": False},
# "price_msat": {"type": "number", "min": 0, "required": False},
# "producer_id": {
# "type": "number",
# "required": True,
# "excludes": "producer_name",
# },
# "producer_name": {
# "type": "string",
# "required": True,
# "excludes": "producer_id",
# },
# }
# )
async def api_add_track(data: CreateData, id=None):
ls = await get_or_create_livestream_by_wallet(g.wallet.id)
if "producer_id" in g.data:
p_id = g.data["producer_id"]
elif "producer_name" in g.data:
p_id = await add_producer(ls.id, g.data["producer_name"])
if "producer_id" in data:
p_id = data["producer_id"]
elif "producer_name" in data:
p_id = await add_producer(ls.id, data["producer_name"])
else:
raise TypeError("need either producer_id or producer_name arguments")
@ -110,24 +119,24 @@ async def api_add_track(id=None):
await update_track(
ls.id,
id,
g.data["name"],
g.data.get("download_url"),
g.data.get("price_msat", 0),
data["name"],
data.get("download_url"),
data.get("price_msat", 0),
p_id,
)
return "", HTTPStatus.OK
else:
await add_track(
ls.id,
g.data["name"],
g.data.get("download_url"),
g.data.get("price_msat", 0),
data["name"],
data.get("download_url"),
data.get("price_msat", 0),
p_id,
)
return "", HTTPStatus.CREATED
@livestream_ext.route("/api/v1/livestream/tracks/<track_id>", methods=["DELETE"])
@livestream_ext.delete("/api/v1/livestream/tracks/{track_id}")
@api_check_wallet_key("invoice")
async def api_delete_track(track_id):
ls = await get_or_create_livestream_by_wallet(g.wallet.id)