1
from starlette.middleware import Middleware
from starlette.middleware.base import BaseHTTPMiddleware
from starlette.routing import Mount
from fastapi import FastAPI, HTTPException

class CustomHeaderMiddleware(BaseHTTPMiddleware):

    async def dispatch(self, request: Request, call_next):
         customer =stripe.Customer.retrieve(request.session.get("user"))
         r= stripe.Subscription.list(customer=customer.id,limit=3)
         if r.data[0].status =="incomplete":
            raise HTTPException(401)
        #  response= RedirectResponse(url='/gradio')
         
         response = await call_next(request)
        
         return response  
 
io = gr.Interface(lambda x: "Hello, " + x + "!", "textbox", "textbox")

middleware = [
    Middleware(CustomHeaderMiddleware)
]

routes = [
    Mount('/gradio', app=io, middleware=middleware),
]
app = FastAPI(routes=routes)

File "C:\Users\Shivam 112\AppData\Roaming\Python\Python310\site-packages\starlette\middleware\base.py", line 69, in coro await self.app(scope, receive_or_disconnect, send_no_error)

TypeError: object str can't be used in 'await' expression

Chris
  • 18,724
  • 6
  • 46
  • 80
shivam jha
  • 11
  • 4
  • Are you using [gradio](https://gradio.app/quickstart/)? – Paweł Rubin Jan 04 '23 at 08:28
  • 1
    The traceback is incomplete and your question exhibits no debugging effort. Please review the [help] and in particular [How to ask](/help/how-to-ask) as well as the guidance for providing a [mre]. – tripleee Jan 04 '23 at 10:14

1 Answers1

0

The issue here is that the routes argument in the FastAPI constructor does not accept plain Starlette routes. There is probably a way to work around that, but there is an even easier solution. Looking into gradio a bit, it turns out that their web app is a FastAPI application, meaning we can add the middleware in the normal way, and then mount the gradio app as a sub application:

import gradio
import gradio.routes
import stripe
from fastapi import FastAPI, Request, Response, status
from starlette.middleware.base import BaseHTTPMiddleware


class CustomHeaderMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request: Request, call_next):
        customer = stripe.Customer.retrieve(request.session.get("user"))
        r= stripe.Subscription.list(customer=customer.id,limit=3)
        if r.data[0].status =="incomplete":
            return Response(status_code=status.HTTP_401_UNAUTHORIZED)

        response = await call_next(request)
        return response

io = gradio.Interface(lambda x: "Hello, " + x + "!", "textbox", "textbox")

# Create gradio FastAPI application
gradio_app = gradio.routes.App.create_app(io)
gradio_app.add_middleware(CustomHeaderMiddleware)

app = FastAPI()

app.mount("/gradio", gradio_app)

Also, raising an HTTPException only works in a FastAPI route, not in a middleware, which is why I'm returning a plain response instead.

M.O.
  • 1,712
  • 1
  • 6
  • 18