Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ Allow callabe in dependant for get_request_handler #11508

Open
wants to merge 9 commits into
base: master
Choose a base branch
from

Conversation

Reton2
Copy link

@Reton2 Reton2 commented May 1, 2024

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"}

@Reton2
Copy link
Author

Reton2 commented May 1, 2024

mypy doesn't seem to be happy with callable either.

@alejsdev alejsdev changed the title fix: allow callabe in dependant for get_request_handler ♻️ Allow callabe in dependant for get_request_handler May 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants