Closed summersz closed 3 years ago
@summersz Could you please, provide more details, maybe share some code or post some instructions what and when it happens, etc.?
Upd: asyncio.run() - introduced in Python3.7, you can use it. But if someone need to make it working with Python3.6+, then should use given approach
Thanks @serhiibuniak-okta. I have the below module to create a decorator that is called on protected routes. The error is thrown when a request is made to a protected route. I am using Python 3.7 so will proceed with using asyncio.run().
import asyncio
from flask import current_app, request
from okta_jwt_verifier import JWTVerifier
from functools import wraps
class JWTBaseException(Exception):
pass
class NoAuthorizationError(JWTBaseException):
pass
loop = asyncio.get_event_loop()
def token_required(f):
@wraps(f)
def wrapper(*args, **kwargs):
try:
verify_token()
except:
return "Unauthorized", 401
return f(*args, **kwargs)
return wrapper
def verify_token():
if request.method == 'OPTIONS':
return
try:
token = request.headers.get("Authorization").split("Bearer ")[1]
except:
raise NoAuthorizationError
try:
is_access_token_valid(token)
except NoAuthorizationError:
raise
def is_access_token_valid(token):
jwt_verifier = JWTVerifier(current_app.config['OKTA_ISSUER'],current_app.config['OKTA_CLIENT_ID'], current_app.config['OKTA_AUDIENCE'])
try:
loop.run_until_complete(jwt_verifier.verify_access_token(token))
# asyncio.run(jwt_verifier.verify_access_token(token))
return
except Exception:
raise NoAuthorizationError
Traceback (most recent call last):
File "C:\Users\summersra\Python\AutopilotAPI\AutopilotAPI\__init__.py", line 4, in <module>
from AutopilotAPI.routes import initialize_routes
File "C:\Users\summersra\Python\AutopilotAPI\AutopilotAPI\routes.py", line 3, in <module>
from .Resources.CHK.BFM import *
File "C:\Users\summersra\Python\AutopilotAPI\AutopilotAPI\Resources\CHK\BFM.py", line 1, in <module>
from AutopilotAPI.okta_auth import token_required
File "C:\Users\summersra\Python\AutopilotAPI\AutopilotAPI\okta_auth.py", line 12, in <module>
loop = asyncio.get_event_loop()
File "C:\Python38\Lib\asyncio\events.py", line 639, in get_event_loop
raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-3'.
@summersz , usually, this kind of error happens, when no event loop is started. It would be good to see full code, but looks like the problem is in "token_required" function, from this doc https://flask.palletsprojects.com/en/2.0.x/async-await/ it should be like the following:
def extension(func):
@wraps(func)
def wrapper(*args, **kwargs):
... # Extension logic
return current_app.ensure_sync(func)(*args, **kwargs)
return wrapper
A bit another approach how to handle async code, you can find within these samples https://github.com/okta/samples-python-flask
Let me know if anything helps. Otherwise, it would be good to see the whole code (without any sensitive info, of course) and I'll be able to help more.
@summersz I'm closing this issue as stalled. Feel free to reopen this issue or create a new one if your problem exists still.
I have implemented the examples into a Flask api but receive the following error:
RuntimeError: There is no current event loop in thread 'Thread-3'
It seems that
get_event_loop()
will only create a new event loop if it is running on the main thread. Is there a reason that the event loop is created like this rather than using asyncio.run()?Alternatively, can the event loop be created using the following:
I am unfamiliar with asyncio and am not sure what the ramifications are of using either option.