from fastapi import FastAPI, HTTPException, Request, Response #from fastapi import Body, Cookie, File, Form, Header, Path, Query from contextlib import asynccontextmanager from pydantic import BaseModel, ValidationError from typing import Optional import uvicorn import aiomysql import bcrypt #import asyncio # In this FastAPI example, we skip BaseModel verification cause NuxtJS does that for us # In other words, this backend only recieves requests from nuxt js backend # So we can trust it class db: pool = None host = "192.168.1.208" user = "suricata" db_name = "yt2mp3_nuxt" pwd = "19_P@NDCATA" @asynccontextmanager async def lifespan(app: FastAPI): db.pool = await aiomysql.create_pool(host=db.host,user=db.user,password=db.pwd,db=db.db_name, minsize=1, maxsize=10) try: yield finally: db.pool.close() await db.pool.wait_closed() app = FastAPI(lifespan=lifespan) async def fetch_user_info(email: str): async with db.pool.acquire() as conn: async with conn.cursor(aiomysql.DictCursor) as cur: await cur.execute("SELECT * FROM users WHERE email = %s", (email,)) return await cur.fetchone() @app.post("/convert") async def convert_endpoint(): pass class register_model(BaseModel): first_name:str last_name:str email:str password:str @app.post("/register") async def create_user(req: Request): body = await req.json() #body = register_model(**body) # Auto exceptions give more verbose to Nuxt. #try: # body = register_model(**body) #except ValidationError: # raise HTTPException(status_code=400, detail="Missing / invalid arguments") body["password"] = bcrypt.hashpw(body["password"].encode(), bcrypt.gensalt()).decode() async with db.pool.acquire() as conn: async with conn.cursor() as cur: await cur.execute("INSERT INTO users (`first_name`,`last_name`,`email`,`password`) VALUES (%s,%s,%s,%s)", (body.first_name, body.last_name, body.email, body.password)) await conn.commit() class login_data(BaseModel): email: str password: str @app.post("/login") async def login_endpoint(req: Request): body = await req.json() #print(body) try: #login = login_data(**body) # ensure it's only email and password user_data = await fetch_user_info(body["email"]) if (user_data is None): raise HTTPException(status_code=401, detail="User doesn't exist") else: pwd = user_data.get("password") if (bcrypt.checkpw(body["password"].encode(), user_data.get("password").encode())): return user_data else: raise HTTPException(status_code=401) except KeyError: raise HTTPException(status_code=400) #except ValidationError: # raise HTTPException(status_code=400) @app.get("/me") async def me_get_endpoint(req: Request): """ Retrieves user profile data. Trusts Nuxt's backend to allow it or not. """ args = dict(req.query_params) #print(args) try: me = await fetch_user_info(args["email"]) if (me is None): raise HTTPException(404, "User doesn't exist") else: return me except KeyError: raise HTTPException(400, "Please provide email") if __name__ == "__main__": uvicorn.run(app, host="127.0.0.1", port=8003)