Colin-b / httpx_auth

Authentication classes to be used with httpx
MIT License
114 stars 26 forks source link

Breaking: Use httpx generator-based auth-flow protocol in place of internal Clients #88

Open rafalkrupinski opened 6 months ago

rafalkrupinski commented 6 months ago

Tried to make a minimal change to get some feedback, so only headers are supported.

The entire stack is changed to generators. requesting and refreshing tokens yield requests, TokenMemoryCache.get_token() passes them through. It's a breaking change for those who use or inherit token cache classes, or inherit from httpx_auth OAuth2 related classes.

MultiAuth has now separate implementations for sync and async.

Most tests changes replace client with headers; token cache test needed to be changed since now get_token is a generator function.

The custom headers parameter is sometimes called headers and other times token_headers. I thought in the API (user-facing) it's sufficient to use shorter name, but internally I wanted to separate headers set to the user request and the ones for OAuth2 requests.

Technically setting meta-auth headers could be delegated to another Auth instance (meta-auth). The previous version of this change implemented this, and it made the code somewhat more complex. I think setting a couple of fields (headers, cookies etc) doesn't require for such complexity. Also I don't expect anyone would need OAuth2 to get an OAuth2 token, which I think wasn't supported by the version with internal Client either.

sonarcloud[bot] commented 6 months ago

Quality Gate Failed Quality Gate failed

Failed conditions
41.9% Duplication on New Code (required ≤ 3%)

See analysis details on SonarCloud

rafalkrupinski commented 6 months ago

Continuing #72

rafalkrupinski commented 6 months ago

I have the following remarks:

1. What would be the benefit of yielding ?

httpx.Auth instances should yield any auth-related requests before finally yielding the actual user-made request with added auth headers. This way, as long as it doesn't use any IO, a single implementation works with both Client and AsyncClient. Otherwise any IO or locking code should be put in Auth.a/sync_flow() functions.

2. Client needs to be supported, it provide much more than headers.

Like I wrote in the description, I tried to make a minimal change just to get a feedback.

What exactly do Auth implementations need client for, other than simply sending token/refresh requests?

Supporting properties of httpx.Request (cookies, query and path parameters and request body) is trivial. Proxy and TLS settings can be handled by client mounts, like we talked before.

Is there a need to handle redirects or auth for auth requests (meta auth)? Cookie state (beyond what's already there)? Am I missing anything?

Also I don't want to break the interface for now if possible.

There's a clear upgrade path - request stuff (headers, etc) goes into Auth instances, connection stuff to the client mounts.

For alternatives, there's #48, or perhaps a function in OAuth2Base could handle auth requests: if client is set, use it for the purpose, otherwise yield. I'd recommend against it, except as a temporary solution.

But what's wrong with breaking the API? I thought httpx-auth was in version 0.x for exactly this reason...

rafalkrupinski commented 5 months ago

@Colin-b any ideas how would you like to move this forward, if at all?

Colin-b commented 5 months ago

@Colin-b any ideas how would you like to move this forward, if at all?

IRL is pretty busy but I will take a look at this next week if everything goes well.