我正在使用FastAPI开发一个简单的API。
我有一个端点,我正在测试它,不管它应该返回什么,我总是得到一个包含一个空列表的200段代码。如果我试图通过打印、返回404或其他方式来调试它,它将继续返回相同的响应。这不是第一次使用FastAPI。
其他端点正常工作。
我正在使用电机连接到MongoDB,如果这可能会造成任何问题。
有问题的端点是name_list
路由器文件:
import editdistance
from datetime import datetime
from motor import motor_asyncio
from fastapi import APIRouter, HTTPException, Body, status
from fastapi.encoders import jsonable_encoder
from fastapi.responses import JSONResponse
from app.config import MONGO_URL, DATABASE_NAME
from app.tools import all_to_lower
from app.models.department import Department
from app.logger import logger as log
router = APIRouter()
client = motor_asyncio.AsyncIOMotorClient(MONGO_URL)
db = client[DATABASE_NAME]
@router.post("/insert", response_description="Insert a new department", response_model=Department)
async def insert_department(department: Department = Body(...)):
'''
Inserts or updates a department
'''
department = jsonable_encoder(department)
department = all_to_lower(department)
department['created_at'] = datetime.now()
if department["parent_department"] != "root" and not db.departments.find_one({"name": department["parent_department"]}):
raise HTTPException(status_code=404, detail="Parent department not found")
if not department["owners"]:
raise HTTPException(status_code=400, detail="Owners can't be empty")
for owner in department["owners"]:
if not owner.endswith("@crealsa.es"):
raise HTTPException(status_code=400, detail="Owners must be a valid email ending with @crealsa.es")
parent_exists = await db.departments.find_one({"name": department["parent_department"]})
if department["parent_department"] != "root" and not parent_exists:
raise HTTPException(status_code=404, detail="Parent department not found")
new_department = await db.departments.find_one_and_update(
{"name": department["name"]},
{"$setOnInsert": department},
upsert=True,
return_document=True,
)
created_department = await db.departments.find_one({"_id": new_department["_id"]})
created_department["created_at"] = created_department["created_at"].strftime("%Y-%m-%dT%H:%M:%S")
return JSONResponse(status_code=status.HTTP_201_CREATED, content=created_department)
@router.get("/all", response_description="Get all departments", response_model=list[Department])
async def get_all_departments():
departments = []
async for department in db.departments.find():
departments.append(department)
return departments
@router.get("/{name}", response_description="Get a single department by its name", response_model=list[Department])
async def get_department(name: str):
'''
Get a single department by its name
'''
name = name.lower()
department = await db.departments.find_one({"name": name})
if department:
department["created_at"] = department["created_at"].strftime("%Y-%m-%dT%H:%M:%S")
return [department]
departments = []
async for department in db.departments.find():
departments.append(department)
substr = [dept for dept in departments if name[1:-1] in dept["name"]]
closest = []
for dept in departments:
if editdistance.eval(name, dept["name"]) < 5:
closest.append(dept)
closest = sorted(closest, key=lambda dept: editdistance.eval(name, dept["name"]))
closest = [dept for i, dept in enumerate(closest) if i == 0 or dept["_id"] != closest[i-1]["_id"]]
closest = closest[:10]
result = substr + closest
return [dept for i, dept in enumerate(result) if i == 0 or dept["_id"] != result[i-1]["_id"]]
@router.get("/id/{id}", response_description="Get a single department by its id", response_model=Department)
async def get_department_by_id(id: str):
'''
Get a single department by its id
'''
if (department := await db.departments.find_one({"_id": id})) is not None:
return department
raise HTTPException(status_code=404, detail=f"Department {id} not found")
@router.get("/name_list", response_description="Get all departments names", response_model=str)
async def get_all_departments_names():
'''
Returns a list with all departments names
'''
log.info("Getting all departments names")
return HTTPException(status_code=404, detail="No departments found")
发布于 2022-10-03 11:30:23
在方法的最后一行中使用return
,name_list
认为要很好地执行该函数,并返回200个代码。若要引发错误,请使用raise
关键字而不是return
。希望你会发现它有用。
发布于 2022-10-03 11:54:52
您已经定义了一个路由,该路由在该路由之前捕获针对/
的所有请求,因此您没有执行您认为正在执行的端点。
@router.get("/{name}", ...)
async def get_department(name: str):
...
这是被调用的端点--使用name_list
作为name
。
相反,在定义name_list
之前先定义/{name}
--或者更好的是,如果您还没有将其发布给任何第三方--使用前缀(例如/departments/{name}
)重新定位/{name}
。通常,资源类型限定符应该出现在任何REST URL的开头。
https://stackoverflow.com/questions/73934691
复制相似问题