Comments (3)
This is most likely not the best solution, but still I'll leave it here:
# endpoints.py
from apiclient import endpoint
@endpoint(base_url='https://base.com')
class Endpoints:
oauth_token = '/oauth/token'
some1 = 'some1'
some2 = 'some2'
# authentication_methods.py
from .endpoints import Endpoints
class HeaderAuthenticationRetry(HeaderAuthentication):
def __init__(self, token: Optional[str] = None, **kwargs):
super().__init__(token or '', **kwargs)
def perform_initial_auth(self, client: APIClient, force: bool= Fasle):
if force:
self._token = client.get_token()
# or
self._token = client.get(Endpoints.oauth_token)
def get_headers(self) -> Dict[str, str]:
if self._token:
return super().get_headers()
return {}
# retrying.py
from apiclient.retrying import retry_if_api_request_error
from tenacity import RetryCallState, retry, stop_after_attempt, wait_fixed
from .authentication_methods import HeaderAuthenticationRetry
class retry_auth(retry_if_api_request_error): # noqa: N801
def __call__(self, retry_state: RetryCallState) -> bool:
ret = super().__call__(retry_state=retry_state)
if ret:
client, *_ = retry_state.args
auth = client.get_authentication_method()
if isinstance(auth, HeaderAuthenticationRetry):
auth._token = None
auth.perform_initial_auth(client, force=True)
return ret
use_token = retry(retry=retry_auth(status_codes=[401]), wait=wait_fixed(1), stop=stop_after_attempt(2), reraise=True)
# client.py
from .retrying import use_token
from .endpoints import Endpoints
class MyAPIClient(APIClient):
def __init__(
self,
authentication_method: Optional[BaseAuthenticationMethod] = None,
**kwargs,
):
super().__init__(
authentication_method=authentication_method or HeaderAuthenticationRetry(),
**kwargs,
)
# Not auth
def get_some1(self):
return self.get(Endpoints.some1)
# Auth
@use_token
def get_some2(self):
return self.get(Endpoints.some2)
# Use
client = MyAPIClient()
client.get_some1() # 1 request without token
client.get_some2() # 3 requests 1 - without token (401), 1 - get token, 1 - with token in header
client.get_some1() # 1 request with token. Because it was saved in the previous request.
from api-client.
Maybe Retrying help you.
from api-client.
I don't think the client is yet capable of doing this. But not a bad idea for a new version. But in the meantime, I'd recommend maybe looking into retrying, but I'm not sure if that will have enough knowledge of the client implementation itself. Potentially you could extend the HeaderAuthentication so that it works out if the token is invalid or has expired and requests a new one? If you couple that with retrying on 401s, you might have a working solution.
from api-client.
Related Issues (20)
- Extended Example's import models lost HOT 2
- api-client (1.2.0) LOST module [dataclasses] Not backward compatible HOT 1
- Could add the debug option when request the API url
- Need MORE Content-type class IN request_formatter.py HOT 2
- request_strategy parameter for APIClient constructor HOT 12
- Tenacity 7.0 breaks test suite HOT 2
- `tox` command not running unittests HOT 3
- Async support HOT 3
- Extend APIClient with Additional Constructor Attributes HOT 2
- Consider adding py.typed?
- OAuth handler HOT 1
- Don't swallow errors
- Testing response with unittest mock
- Allow defining a client-level base URL that is prepended to endpoint URLs in requests HOT 2
- Async Client
- paginator has no access to the original response when using JsonResponseHandler
- Handling files HOT 1
- Package name is conflicting with google_api_python_client
- post() does not support arrays
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from api-client.