Reputation: 833
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
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