Not 101% sure that this observation is correct, but please review 🙏 .
M2M.authenticate_token() lacks an async version and blocks the event loop when PyJWKClient fetches JWKS keys. The Sessions API correctly handles this with asyncio.to_thread(), but M2M does not.
The docstring for M2M.authenticate_token() states:
"Note: There is no async version of this since we make no network calls."
This blocks the async event loop, causing latency spikes in async applications.
M2M.authenticate_token() # stytch/consumer/api/m2m.py:111
→ jwt_helpers.authenticate_jwt_local() # stytch/shared/jwt_helpers.py:37
→ jwks_client.get_signing_key_from_jwt() # jwt/jwks_client.py:200
→ get_signing_key() # jwt/jwks_client.py:185
→ get_signing_keys() # jwt/jwks_client.py:160
→ get_jwk_set() # jwt/jwks_client.py:136
→ fetch_data() # jwt/jwks_client.py:107-111
→ urllib.request.urlopen() # ❌ BLOCKING
- Stytch version: 15.0.0
- Python version: 3.13
Not 101% sure that this observation is correct, but please review 🙏 .
M2M.authenticate_token() lacks an async version and blocks the event loop when PyJWKClient fetches JWKS keys. The Sessions API correctly handles this with asyncio.to_thread(), but M2M does not.
The docstring for M2M.authenticate_token() states:
"Note: There is no async version of this since we make no network calls."
This blocks the async event loop, causing latency spikes in async applications.
M2M.authenticate_token() # stytch/consumer/api/m2m.py:111
→ jwt_helpers.authenticate_jwt_local() # stytch/shared/jwt_helpers.py:37
→ jwks_client.get_signing_key_from_jwt() # jwt/jwks_client.py:200
→ get_signing_key() # jwt/jwks_client.py:185
→ get_signing_keys() # jwt/jwks_client.py:160
→ get_jwk_set() # jwt/jwks_client.py:136
→ fetch_data() # jwt/jwks_client.py:107-111
→ urllib.request.urlopen() # ❌ BLOCKING