1

I am trying to create an audio server where I can upload various audio files, I have a requirement that I can only create one endpoint for creating, I have come up with this but it does show the request form to input data.

class AudioType(str, Enum):
    Song = "Song"
    Podcast = "Podcast"
    Audiobook = "Audiobook"


@app.post("/{audio_type}", status_code=status.HTTP_200_OK)
def audio(audio_type: AudioType):
    if audio_type == AudioType.Song:
        def create_song(request: schemas.Song, db: Session = Depends(database.get_db)):
            new_song = models.Song(name=request.name, duration=request.duration, uploadTime=request.uploadTime)
            db.add(new_song)
            db.commit()
            db.refresh(new_song)
            return new_song
    elif audio_type == AudioType.Podcast:
        def create_podcast(request: schemas.Podcast, db: Session = Depends(database.get_db)):
            new_podcast = models.Podcast(name=request.name,  duration=request.duration, uploadTime=request.uploadTime,                                         host=request.host)
            db.add(new_podcast)
            db.commit()
            db.refresh(new_podcast)
            return new_podcast
    elif audio_type == AudioType.Audiobook:
        def create_audiobook(request: schemas.Audiobook, db: Session = Depends(database.get_db)):
            new_audiobook = models.Audiobook(titile=request.title, author=request.author, narrator=request.narrator,                                              duration=request.duration, uploadTime=request.uploadTime)
            db.add(new_audiobook)
            db.commit()
            db.refresh(new_audiobook)
            return new_audiobook

1 Answer 1

1

Your method doesn't accept the request object but only the audio_type.
Also from what I understand from your code, you may have multiple request bodies (schemas as you refer to them)

There are 2 options to what you want:

  1. You need to declare your endpoint as follows:

    from typing import Union
    
    @app.post("/{audio_type}", status_code=status.HTTP_200_OK)
    def audio(
        request: Union[schemas.Song, schemas.Podcast, 
        schemas.Audiobook], audio_type: AudioType
    ):
        ... Your method ...
    

    But the auto swagger of fastapi will not provide a schema example and you will have to provide examples manually, (which may or may not be possible, I don't really know and haven't tried it :/)

  2. OR you can have a schema that can accept everything as Optional and the audio_type parameter:

    from typing import Optional
    
    
    class EndpointSchema(BaseModel):
        audio_type: AudioType
        song: Optional[schemas.Song]
        podcast: Optional[schemas.Podcast]
        audiobook: Optional[schemas.Audiobook]
    
    
    @app.post("/audio", status_code=status.HTTP_200_OK)
    def audio(request_body: EndpointSchema):
        if request_body.audio_type == AudioType.Song:
            ... Continue with your request processing ...
    

Finally, very important: You are declaring internal methods (create_song etc.) that you are not calling afterward, so your code will do nothing. You don't need to do that, use the code you want to create a song, podcast, or audiobook directly inside the if, elif ... blocks!

Sign up to request clarification or add additional context in comments.

5 Comments

Thank you for your response, once i have made the request as Union, i want to know how to access them in model.song() ?
@devgru You can access them from the request_body object.
so i tried the union solution, you were correct the swagger UI only shows schema of first parameter, in the second solution it showed all the schemas. is there a way it can show me the schema of only one specified audio type
@devgru I don't know fo sure, but I think that you will have to manually extend the open API for that endpoint: fastapi.tiangolo.com/advanced/extending-openapi
i read this but i don't know where to go from here. can you provide more context ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.