首页 > 解决方案 > 如何在 FastAPI 中使用来自 POST 的查询参数?

问题描述

我想在 FastAPI 中编写一个路由来使用 POST 请求。我有以下 URL 示例:

https://URL.com/api/FlexfoneCall/outgoing?AccountId=1234&TimeStamp=2021-05-20+08%3a30%3a56&UniqueCallId=SIP%2f%2b4512345678-0000e4a81463430317&EmployeeLocalNumber=200&ANumber=12345678&BNumber=87654321&PhoneLocalNumber=123456

但是,我只习惯于从请求中消耗身体。如何从上面的示例中“获取”路径参数数据?

编辑:

我正在尝试编写一个从外部服务接收上述 URL 的服务。我尝试执行以下操作,因为我认为由于它是 POST 我的路线应该如下所示:

@app.post('/callout', response_model=CallIn)
async def create_call_out(callout: CallOut, db: Session = Depends(get_db)):
    db_write_call_out = write_call_out(db, callout)

    return db_write_call_out

使用以下 Pydantic 模型:

class CallOut(BaseModel):
    accountid: str = None
    timestamp: str = None
    uniquecallid: str = None
    employeelocalnumber: str = None
    anumber: str = None
    bnumber: str = None
    phonelocalnumber: str = None

    class Config:
        orm_mode = True

和 CRUD 功能:

def write_call_out(db: Session, callout: CallOut):
    db_write_call_out = DBCallOut(**callout.dict())
    db.add(db_write_call_out)
    db.commit()
    db.refresh(db_write_call_out)

    return db_write_call_out

用于将查询参数写入 SQL DB 的 SQLAlchemy ORM 模型:

class DBCallOut(Base):
    __tablename__ = "call_out"

    accountid = Column('AccountId', String(250))
    uniquecallid = Column('UniqueCallId', String(250))
    employeelocalnumber = Column('EmployeeLocalNumber', String(250))
    anumber = Column('ANumber', String(250))
    timestamp = Column('TimeStamp', String(250))
    phonelocalnumber = Column('PhoneLocalNumber', String(250))
    bnumber = Column('BNumber', String(250))
    ID = Column(Integer,  primary_key=True,  index=True, autoincrement=True)

但我不断收到 422 错误。

编辑2:

最终将我的路线更改为以下内容:

@app.get('/call')
async def outgoing(AccountId: str,
                   TimeStamp: str,
                   UniqueCallId: str,
                   EmployeeLocalNumber: str,
                   ANumber: str,
                   BNumber: str,
                   PhoneLocalNumber: str, db: Session = Depends(get_db)):
    callout = {"AccountId": AccountId,
                "TimeStamp": TimeStamp,
                "UniqueCallId": UniqueCallId,
                "EmployeeLocalNumber": EmployeeLocalNumber,
                "ANumber": ANumber,
                "BNumber": BNumber,
                "PhoneLocalNumber": PhoneLocalNumber}
    db_write_call_out = write_call_out(db, callout)

    return db_write_call_out

这是有效的,但它有点笨拙。

标签: pythonfastapi

解决方案


我不确定您是要使用 Path 参数(url 路径的一部分,如 中)还是google.co/youtube/videos/1要使用查询参数(以路径 url 命名的变量,如google.co?video=1作为方法装饰 ( @app(params)) 的参数,对于查询参数,您在方法参数 ( def get_video(params)) 中声明它们。所以对于给定的链接,如果你想获取查询参数,你会这样做:

@app.post("outgoing/")
async def do_something(
      AccountId: int, 
      TimeStamp: str, 
      UniqueCallId: str, 
      EmployeeLocalNumber: str,
      ANumber: int,
      BNumber: int,
      PhoneLocalNumber: int
    ):
    # do some stuff
    save_to_db(owner=AccountId,time=TimeStamp,contact=PhoneLocalNumber)
    

并获得路径变量(坚持我上面给出的例子)你这样做:

@app.post("video/{video_id}")
async def do_something():
    # do something
    save_to_db(video_id)
    

无论您选择实现哪个,都将从客户端发送的请求 url 中获取参数值(通过路径参数的路径中的位置,或查询参数中同名的查询参数),并将它们放入您的变量名中宣布。然后像示例所示的那样正常使用它们。

文档对新手非常友好,因此查询参数请参见此处,路径参数请参见此处

作为旁注,对于更多pythonic代码,我建议您使用蛇形案例来命名您的变量


推荐阅读