I am using a callable object to wrap an endpoint function for a custom APIRoute.
The callable object calls the endpoint function with the __call__ method.
The is_coroutine check fails to determine the __call__ method is a coroutine since it's checking the instance of the object.
This change will allow for the use of decorators on endpoints to feed information to the APIRoute
class EndpointWrapper(Callable[..., Any]):
def __init__(self, endpoint: Callable[..., Any]):
self.endpoint = endpoint
self.protected = False
update_wrapper(self, endpoint)
async def __call__(self, *args, **kwargs):
return await self.endpoint(*args, **kwargs)
def dummy_secruity_check(token: HTTPAuthorizationCredentials = Depends(HTTPBearer())):
if token.credentials != "fake-token":
raise HTTPException(status_code=401, detail="Unauthorized")
def protect(endpoint: Callable[..., Any]):
if not isinstance(endpoint, EndpointWrapper):
endpoint = EndpointWrapper(endpoint)
endpoint.protected = True
return endpoint
class CustomAPIRoute(APIRoute):
def __init__(self, path: str, endpoint: Callable[..., Any], dependencies=None, **kwargs) -> None:
if dependencies is None:
dependencies = []
if (
isinstance(endpoint, EndpointWrapper)
and endpoint.protected
):
dependencies.append(Depends(dummy_secruity_check))
super().__init__(path, endpoint, dependencies=dependencies, **kwargs)
app = FastAPI()
app.router.route_class = CustomAPIRoute
@app.get("/protected")
@protect
async def protected_route():
return {"message": "This is a protected route"}
I am using a callable object to wrap an endpoint function for a custom APIRoute. The callable object calls the endpoint function with the
__call__
method. Theis_coroutine
check fails to determine the__call__
method is a coroutine since it's checking the instance of the object.This change will allow for the use of decorators on endpoints to feed information to the APIRoute