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

Replace BasicAuth instance check with Protocol check #4690

Open
stj opened this issue Apr 13, 2020 · 1 comment
Open

Replace BasicAuth instance check with Protocol check #4690

stj opened this issue Apr 13, 2020 · 1 comment

Comments

@stj
Copy link
Contributor

stj commented Apr 13, 2020

🐣 Is your feature request related to a problem? Please describe.

The server I am authenticating against uses bearer token for the authentication header. For that I like to use a custom auth class and use it with a dedicated ClientSession as the auth parameter.
Regarding ClientSession this is only a type hint issue but down in ClientRequest.update_auth the instance check for BasicAuth brakes my approach.

💡 Describe the solution you'd like

It feels that the auth instance only needs to have an encode method to work. Because of that I'd propose defining a protocol for auth and do an instance check on that.

from typing import Protocol, runtime_checkable

@runtime_checkable
class AuthProtocol(Protocol):
    def encode(self) -> str:
        ...

class ClientRequest:
    ...
    def update_auth(self):
        ...
        if not isinstance(auth, Protocol):
            ...

    def update_proxy(self):
        ...
        if proxy_auth and not isinstance(proxy_auth, Protocol):
            ...

Describe alternatives you've considered

The proposed solution only works with >= Python 3.8. Other alternatives that come to mind are:

  • Define an ABC.
  • Replacing the instance check with an attribute check.
  • Just remove the instance check.
@carloshorn
Copy link

Hi,
Any news on this issue?

My current solution is using a subclass:

class BearerAuth(aiohttp.BasicAuth):
    def __init__(self, token: str) -> None:
        self.token = token
        
    def encode(self) -> str:
        return f"Bearer {self.token}"

However, it does not lead to a satisfactory solution, because aiohttp.BasicAuth inherits from a namedtuple and calls the __new__ method which will build the named tuple with login=token, password='', encoding='latin1'. Afterwards the __init__ method will set the token attribute.
I would prefer an ABC for deriving user specific authentications, because encode is a very common class method name, e.g. str. The ABC would prevent any misuse.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants