Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Raise exception in python-fastApi middleware

I am trying to validate token in fastapi middleware but this seems impossible. As i am thinking middleware needs to make next call although its not required. I am not able to find any good solution to handle token in one go in this python-fastapi backend. Any help is appreciated.

@app.middleware("http")
async def add_middleware_here(request: Request, call_next):
    token = request.headers["Authorization"]
    try:
        verification_of_token = verify_token(token)
        if verification_of_token:
            response = await call_next(request)
            return response
    except InvalidSignatureError as er:
        raise HTTPException(status_code=401)
like image 281
TrickOrTreat Avatar asked Apr 22 '20 06:04

TrickOrTreat


People also ask

How do you raise the HTTP exception in Python?

In the event of a network problem (e.g. DNS failure, refused connection, etc), Requests will raise a ConnectionError exception. In the rare event of an invalid HTTP response, Requests will raise an HTTPError exception. If a request times out, a Timeout exception is raised.

What is a middleware in FastAPI?

A "middleware" is a function that works with every request before it is processed by any specific path operation. And also with every response before returning it. It takes each request that comes to your application. It can then do something to that request or run any needed code.

Is FastAPI asgi?

As FastAPI is based on Starlette and implements the ASGI specification, you can use any ASGI middleware.

What are the exception handlers in fastapi?

These handlers are in charge of returning the default JSON responses when you raise an HTTPException and when the request has invalid data. You can override these exception handlers with your own. When a request contains invalid data, FastAPI internally raises a RequestValidationError.

Can you add middleware to fastapi applications?

You can add middleware to FastAPI applications. A "middleware" is a function that works with every request before it is processed by any specific path operation. And also with every response before returning it. It takes each request that comes to your application. It can then do something to that request or run any needed code.

How to raise exceptions in Python?

Summary: in this tutorial, you’ll learn how to raise exceptions by using the Python raise statement. The ExceptionType () must be subclass of the BaseException class. Typically, it is a subclass of the Exception class. Note that the ExceptionType doesn’t need to be directly inherited from the Exception class.

How do I override a requestvalidationerror in fastapi?

When a request contains invalid data, FastAPI internally raises a RequestValidationError. And it also includes a default exception handler for it. To override it, import the RequestValidationError and use it with @app.exception_handler (RequestValidationError) to decorate the exception handler.


Video Answer


2 Answers

You need to return a response. I'll show you how you can make it work:

from fastapi.responses import JSONResponse

@app.middleware("http")
async def add_middleware_here(request: Request, call_next):
    token = request.headers["Authorization"]
    try:
        verification_of_token = verify_token(token)
        if verification_of_token:
            response = await call_next(request)
            return response
        else:
            return JSONResponse(status_code=403) # or 401
    except InvalidSignatureError as er:
        return JSONResponse(status_code=401)

Be aware that using this middleware implies that you don't have a login route on your API (for token generation).

Besides, you should consider using this dependency instead: https://fastapi.tiangolo.com/tutorial/security/simple-oauth2/

Another thing is that you can use fastapi.status for your status code.

like image 97
Marcelo Trylesinski Avatar answered Oct 20 '22 09:10

Marcelo Trylesinski


See JSONResponse API documentation.

from fastapi.responses import JSONResponse

@app.middleware("http")
async def errors_handling(request: Request, call_next):
    try:
        return await call_next(request)
    except Exception as exc:
        return JSONResponse(status_code=500, content={'reason': str(exc)})
like image 26
Constantin De La Roche Avatar answered Oct 20 '22 08:10

Constantin De La Roche