Describe the bug
I cannot find a way to add Starlette's HTTPEndpoint onto app.router.
To Reproduce
Steps to reproduce the behavior:
Create app: app = fastapi.FastAPI()
Create an endpoint:
class HealthHandler(starlette.endpoints.HTTPEndpoint):
async def get(self, request):
return starlette.responses.JSONResponse({'status': 'OK'})
app.router.Expected behavior
Able to add HTTPEndpoint class.
Environment:
OS: macOS
FastAPI Version: fastapi==0.29.1
Python version: 3.7.3
That's not really how FastAPI's meant to look like.
However, if you wanted to define an endpoint that way, remember you are in a Starlette environment:
FastAPIis actually a sub-class ofStarlette.
Therefore, what you could do is:
# main.py
from fastapi import FastAPI
from starlette.endpoints import HTTPEndpoint
from starlette.responses import JSONResponse
app = FastAPI()
@app.route("/")
class HealthHandler(HTTPEndpoint):
async def get(self, request):
return JSONResponse({'status': 'OK'})
uvicorn main:app
# INFO: Started server process [19630]
# INFO: Waiting for application startup.
# INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
# INFO: ('127.0.0.1', 50608) - "GET / HTTP/1.1" 200 ==> {"status":"OK"}
Follow up question if you don't mind,
what if the Endpoint class is defined in a different module, how can I add it without using the decorator syntax?
One solution could be this:
#health_handler.py
from main import app
from starlette.endpoints import HTTPEndpoint
from starlette.responses import JSONResponse
@app.route("/")
class HealthHandler(HTTPEndpoint):
async def get(self, request):
return JSONResponse({'status': 'OK'})
# main.py
from fastapi import FastAPI
app = FastAPI()
import health_handler
@stefanondisponibile @didip Starlette (and FastAPI as subclass) has add_route method so there is no need to create cyclical dependencies:
#health_handler.py
from starlette.endpoints import HTTPEndpoint
from starlette.responses import JSONResponse
class HealthHandler(HTTPEndpoint):
async def get(self, request):
return JSONResponse({'status': 'OK'})
# main.py
from fastapi import FastAPI
from health_handler import HealthHandler
app = FastAPI()
app.add_route(path="/", route=HealthHandler)
@HarrySky follow up question, if I do app.add_route, I don't get the auto generated Swagger, yes?
Is there a app.add_api_route that also generate Swagger?
Yep. @stefanondisponibile is correct. And then @HarrySky's insight is correct too :smile:
Thanks for the help @stefanondisponibile and @HarrySky !
@didip The Swagger autogeneration depends on OpenAPI.
OpenAPI depends on being able to know the parameters of your request. And that currently depends on using the normal decorator style, not the HTTPEndpoint style.
Gotcha, thank you for all the explanations, guys!
Thanks for reporting back and closing the issue.
Most helpful comment
That's not really how FastAPI's meant to look like.
However, if you wanted to define an endpoint that way, remember you are in a Starlette environment:
Therefore, what you could do is: