Artem
Artem

Reputation: 833

How do I consume query parameters from POST in FastAPI?

I want to write a route in FastAPI to consume a POST request. I have the following URL example:

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

However, I'm only used to consuming the body from request. How do I "fetch" the path parameter data from the above example?

EDIT:

I'm trying to write a service that receives the above URL from an external service. I tried doing the following because I thougth that since it was a POST my route should look like this:

@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

With the following Pydantic model:

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

And CRUD function:

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

SQLAlchemy ORM model for writing the query params to a SQL DB:

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)

But I keep getting a 422 Error.

EDIT 2:

Ended up changing my route to the following:

@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

This is working, but it's somewhat clunky.

Upvotes: 4

Views: 16845

Answers (1)

Allprod
Allprod

Reputation: 443

I am not sure if you want to consume Path parameters (part of the url path, as in google.co/youtube/videos/1) or if you want to consume query parameters (a variable named after the path url, as in google.co?video=1) but either way you just declare the path parameters as parameters of the of the method decoration (@app(params)) and for query parameters you declare them in the method parameters (def get_video(params)). so for the given link, if you want to get the query parameters you would do:

@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)
    

and to get path variables (sticking to the example I gave above) you do this:

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

Whichever on you choose to implement will take the parameter values (by location in the path for path params, or from the query parameter by the same name in the query params) from the request url the client sends and place them into the variable names you declare. then you use them as normal like the example shows.

The docs are very newcomer friendly so for query parameters refer here, and for path parameters refer here.

as a side note, for more pythonic code, I suggest you use snake case to name your variables

Upvotes: 3

Related Questions