postgresql 如何从FastAPI中的依赖函数返回多个数据/对象?

stszievb  于 5个月前  发布在  PostgreSQL
关注(0)|答案(2)|浏览(69)

我正在使用FastAPI框架并将一些数据写入PostgreSQL数据库。我遇到的问题是,我有一个函数get_current_user()可以返回用户凭据(包括电子邮件),但我不知道如何从另一个函数s3_create_upload_files()访问这些数据。
原因我想这样做是因为我想写的电子邮件地址和文件名,我要上传到同一行的数据库后,文件成功上传。

get_current_user()

async def get_current_user(
    request: Request,
    db: Session = Depends(get_db),
):
    token = request.cookies.get("Authorization")

    if token is None:
        raise HTTPException(status_code=302, headers={"Location": '/auth/login'})

    token = token.split("Bearer ")[-1]

    try:
        payload = jwt.decode(token, os.getenv('SECRET_KEY'), algorithms=["HS256"])
        email: str = payload.get("sub")
        if email is None:
            raise HTTPException(status_code=302, headers={"Location": '/auth/login'})
    except jwt.exceptions.ExpiredSignatureError:
        raise HTTPException(status_code=302, headers={"Location": '/auth/login'})

    user = db.query(User).filter(User.email == email).first()
    if user is None:
        raise HTTPException(status_code=302, headers={"Location": '/auth/login'})
    
    print(f'Email is {user.email}')

    return user  # Ensure 'user' is a User object

字符串

s3_upload_files()

async def s3_create_upload_files(
    file: UploadFile = File(...),
    current_user: User = Depends(get_current_user), 
    db: Session = Depends(get_db)
):
....CODE HERE,,,,

        # Insert data into the database after successful upload
    try:
        db = SessionLocal()
        file_data = User(filename=sanitized_filename, email=current_user.email)
        db.add(file_data)
        db.commit()
    except Exception as e:
        db.rollback()
        raise HTTPException(status_code=500, detail=str(e))
    finally:
        db.close()


我尝试了几种不同的方法来接收s3_create_upload_files()中的数据,但所有这些方法都导致HTML端出现错误。Same error has come about again "{"detail":"'Depends' object has no attribute 'email'"}"
后端的错误是INFO: 192.168.65.1:62133 - "POST /dashboard HTTP/1.1" 500 Internal Server Error

s6fujrry

s6fujrry1#

您可以使用下面描述的方法之一来实现这一点。

选项1 -返回listdict数据

从依赖函数返回list的数据,并在端点中定义一个适当的参数,以期望这些数据以适当的形式出现。

from fastapi import FastAPI, Depends
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    name: str
    age: int
    
    
async def get_user_data():
    user = User(name='john', age=33)
    email = '[email protected]'
    return [user, email]

@app.post('/upload')
async def upload(data: list = Depends(get_user_data)):
    return {'user': data[0], 'email': data[1]}

字符串
若要改为使用dict,请对上面的示例应用以下更改:

# ...

async def get_user_data():
    user = User(name='john', age=33)
    email = '[email protected]'
    return {'user': user, 'email': email}

@app.post('/upload')
async def upload(data: dict = Depends(get_user_data)):
    return {'user': data['user'], 'email': data['email']}

选项1 -返回自定义Python类的对象

解决这个问题的另一种方法是使用相关数据创建一个自定义Python类,在依赖函数中示例化该类以创建一个对象,最后将对象返回到端点。为了简单起见,可以使用Python的dataclass-如this answer所示-其中可以自动添加特殊方法,例如__init__()__repr__()

from fastapi import FastAPI, Depends
from pydantic import BaseModel
from dataclasses import dataclass

app = FastAPI()

class User(BaseModel):
    name: str
    age: int
    

@dataclass
class UserData:
    user: User
    email: str

    
async def get_user_data():
    user = User(name='john', age=33)
    email = '[email protected]'
    return UserData(user, email)

@app.post('/upload')
async def upload(data: UserData = Depends(get_user_data)):
    return {'user': data.user, 'email': data.email}

选项3 -使用request.state存储任意数据

存储此类任意数据的另一种可能更简单的方法是使用request.state,这将允许您稍后在端点中使用Request对象检索这些数据。(以及FastAPI中的全局dependenciesrequest.state),我强烈建议看看this answerthis answer以及thisthis

from fastapi import FastAPI, Depends, Request
from pydantic import BaseModel

app = FastAPI()

class User(BaseModel):
    name: str
    age: int
    
    
async def get_current_user(request: Request):
    user = User(name='john', age=33)
    request.state.email = '[email protected]'
    return user

@app.post('/upload')
async def upload(request: Request, user: User = Depends(get_current_user)):
    return {'user': user, 'email': request.state.email}

zqry0prt

zqry0prt2#

DependsAnnotated参数仅通过FastAPI注入路由。
如果你的s3_create_upload_files()函数是从你的route函数调用的,你应该声明所有的依赖作为你的route参数,并在你调用s3_create_upload_file()的时候传递它们。下面是一个例子:

@app.post("/uploadfile/")
async def create_upload_file(
    file: UploadFile,
    current_user: User = Depends(get_current_user), 
    db: Session = Depends(get_db)
):
    do_whatever()
    s3_create_upload_files(file, current_user, db)
    return {"filename": file.filename}

字符串

相关问题