0

I have this FastAPI application

import uvicorn
from fastapi import FastAPI
from starlette.responses import FileResponse

app = FastAPI()


@app.get("/a")
async def read_index():
    return FileResponse('static/index.html')


@app.get("/a/b")
def download():
    return "get"


@app.post("/a/b")
def ab():
    return "post"


def main():
    uvicorn.run("run:app", host="0.0.0.0", reload=True, port=8001)


if __name__ == "__main__":
    main()

and in static/index.html I have:

<!DOCTYPE html>
<html lang="en">
  <head>
  </head>
  <body>
    <section>
      <form method="post" action="/a/b" enctype="multipart/form-data">
        <div>
          <p>Download:</p>
        </div>
        <div>
          <input type="submit" value="Download"/>
        </div>
      </form>
    </section>
  </body>
</html>

I send a get request to http://127.0.0.1:8001/a and click on the download button it loads, it returns "get"

However, I change the application to

import uvicorn
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles

app = FastAPI()

app.mount("/a", StaticFiles(directory="static", html=True))



@app.get("/a/b")
def download():
    return "get"


@app.post("/a/b")
def ab():
    return "post"


def main():
    uvicorn.run("run:app", host="0.0.0.0", reload=True, port=8001)


if __name__ == "__main__":
    main()

with the same HTML file, I click on the download button, and I get detail: "Method Not Allowed" because it is doing INFO: 127.0.0.1:58109 - "POST /b HTTP/1.1" 405 Method Not Allowed

I want to use mount becuase I want to put js and css files there as well, to be used by the index.html file. how should I do this?

Chris
  • 18,724
  • 6
  • 46
  • 80
Amin Ba
  • 1,603
  • 1
  • 13
  • 38
  • Please have a look at related answers [here](https://stackoverflow.com/a/74498663/17865804), as well as [here](https://stackoverflow.com/a/75715292/17865804) and [here](https://stackoverflow.com/a/71741617/17865804) – Chris May 16 '23 at 04:49

1 Answers1

0

The easiest way to solve the problem is to register all a/blahblah routes first and a then. Just change order:

@app.get("/a/b")
def ...

@app.post("/a/b")
def ...

app.mount("/a", StaticFiles(directory="static", html=True))

However, in this case file with name b uploaded to static folder will be inaccessible. Becasue @app.get("/a/b") will be called first. I recommend to redesign routes structure if you want to avoid this behavior.

Here is a full detailed answer

rzlvmp
  • 7,512
  • 5
  • 16
  • 45
  • 1
    Thanks, I had read that post but could not figure out what to do. this answer helped me solve my problem – Amin Ba May 16 '23 at 08:58