azure-activedirectory-library-for-python
azure-activedirectory-library-for-python copied to clipboard
async support
Hey good work but would be even better with async support instead of blocking calls (I'm not talking about starting another thread / process but genuine async IO support), is there any plan in that regard (using grequests instead of requests for example)?
We don't currently have a plan for that. We can log this as a feature request for future consideration.
Right now, your options can be trying to wrap the ADAL functions inside gevent or eventlet or whatever async library you choose. Typically they will provide some monkey patch mechanism to turn any non-async code into async code. For example, the grequests itself is a thin wrapper onto top of requests.
I am using ADAL as part of Celery tasks inheriting from a base class that maintains single requests session. The Celery worker is executed with gevent pool option and the app is monkey-patched. While my logs show single shared base object for all tasks and single Session(), each of the greenlets gets its own ADAL token. How could I ensure that each greenlet uses the same token from the shared AuthenticationContext?
@OK-UNDP Your question is more about "how to reuse/share token", less about "async support". Nonetheless, there are several possible solutions.
-
You could obtain an access token once and somehow share it among those workers. This way all workers reuse the same token, until it expires after typically one hour. If your tasks last shorter than one hour, this might be an easy fix.
-
ADAL's
AuthenticationContextcan also be a long-live global instance, somehow shared by each of the worker. That way each worker can call the sameAuthenticationContextto acquire a token, and then theAuthenticationContext's built-in in-memory cache would kick in, so you actually still reuse the same token. (You might still end up acquiring some 2~3 tokens, if there happen to be several workers launch the initial requests at the same time. But that's not a big deal.) -
If you have to initialize an
AuthenticationContextwithin each worker, you can probably still implement your own thin persistence layer on top of ADAL Python's TokenCache. That way, all those differentAuthenticationContextwould still share the same cache.
Lastly, there is ADAL Python's successor, MSAL Python, which also comes with its own samples, a cleaner API design and implementation, even with a recipe of how to persist your token cache. All the suggestions above are also applicable to MSAL Python. If you are building your cool new project, you better start with MSAL Python. If you need to migrate your existing ADAL-based projects to MSAL Python, you may find this migration guide helpful.
@rayluo I use the second approach in my distributed MS Graph API exporter project (check out MsGraphExporter repo I've just published). Celery worker maintains longlived AuthenticationContext instance to be re-used by the tasks.
I did tests with the deployment limited to a single worker and thus, one AuthenticationContext shared by all task within the worker. What I see is that acquire_token_with_client_credentials() returns one token for the first call and then a different token for the rest of the calls.
So, the tasks do reuse single token within the worker, but not from the first time, for some reason. I initially assumed it was somehow related to Gevent and asked here.
Anyway, thanks for pointing me to the MSAL. I'll definitely refactor to migrate from ADAL.
Closing this issue, as ADAL Python reaches end-of-life. We will no longer add new feature or change into ADAL Python.
You may subscribe the same async topic in MSAL Python, although we are currently working on other higher priority features.