Python框架之FastAPI

原起:

最近项目中现存的是使用的python的异步方式进行开发, 但是只是存在脚本部分, 并没有提供对外的Web服务,正好趁机将Fastapi嵌入其中使用.

 

官方文档: https://fastapi.tiangolo.com/zh/tutorial/first-steps/

 

[安装]

pip install "fastapi[all]"

 

[使用]

基本:

# pip install fastapi pycryptodome
import json
import base64
import string
import random
import uvicorn
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from fastapi import FastAPI
from pydantic import BaseModel
from fastapi.responses import HTMLResponse, JSONResponse

app = FastAPI()

users_db = {
    "testuser": {
        "username": "testuser",
        "password": "testpassword",
        "email": "testuser@example.com",
        "fullName": "Test User",
    }
}


class LoginRequest(BaseModel):
    data: str


def encrypt(data: dict, key: bytes, iv: bytes) -> str:
    cipher = AES.new(key, AES.MODE_CBC, iv)
    padded_data = pad(json.dumps(data).encode("utf-8"), AES.block_size)
    encrypted = cipher.encrypt(padded_data)
    return base64.b64encode(encrypted).decode("utf-8")


def decrypt(data: str, key: bytes, iv: bytes) -> dict:
    encrypted_data = base64.b64decode(data)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decrypted_data = unpad(cipher.decrypt(encrypted_data), AES.block_size)
    return json.loads(decrypted_data.decode("utf-8"))


def generate_string(length: int) -> str:
    return "".join(
        random.choice(string.digits + string.ascii_letters) for _ in range(length)
    )


@app.get("/api/getSecret")
async def get_secret():
    key = generate_string(32)
    iv = generate_string(16)
    app.state.secret_key = key
    app.state.secret_iv = iv
    return {"key": app.state.secret_key, "iv": app.state.secret_iv}


@app.post("/api/login")
async def login(request: LoginRequest):
    key = app.state.secret_key.encode()
    iv = app.state.secret_iv.encode()

    login_data = decrypt(request.data, key, iv)

    username = login_data.get("username")
    password = login_data.get("password")

    if username in users_db and users_db[username]["password"] == password:  # type: ignore
        user_info = users_db[username]  # type: ignore
        encrypted_response = encrypt({"success": True, "user": user_info}, key, iv)
        return JSONResponse(content={"data": encrypted_response})
    else:
        encrypted_response = encrypt(
            {"success": False, "message": "Invalid username or password"}, key, iv
        )
        return JSONResponse(content={"data": encrypted_response})


@app.get("/", response_class=HTMLResponse)
async def index():
    with open("index.html", "r", encoding="utf-8") as file:
        html_content = file.read()
    return HTMLResponse(content=html_content)


if __name__ == "__main__":
    uvicorn.run(app, host="0.0.0.0", port=8000)

部分说明:

  • app.state: state是实例的一个属性, 可以为该实例定义一下全局属性

 

posted @ 2023-12-15 08:31  X-Wolf  阅读(72)  评论(0)    收藏  举报