Open Parthib opened 5 months ago
+1 on this
Tried removing our rate limiting logic, and it looks to me that there is a bigger issue here:
Connexion's security handlers are now performed by middleware that exist outside of the Flask application, so it is not possible to access the Flask request context in the security handlers. Unfortunately for us, we have a dependency on Flask SQLAlchemy for our security handling that relies on access to the flask request context:
@decorators.setup_security_sentry_scope
def basic_auth(email: str, password: str, request):
try:
user: models.User = models.User.query.filter_by(email=email).one_or_none()
...
Stacktrace:
File "/backend/lib/python3.9/site-packages/connexion/security.py", line 569, in verify_fn
token_info = await token_info
File "/backend/lib/python3.9/site-packages/connexion/security.py", line 116, in wrapper
token_info = func(*args, **kwargs)
File "/backend/app/api/decorators.py", line 59, in wrapper
result = security_function(*args, **kwargs)
File "/backend/app/api/connexion_auth.py", line 24, in basic_auth
user: models.User = models.User.query.filter_by(email=email).one_or_none()
File "/backend/lib/python3.9/site-packages/flask_sqlalchemy/model.py", line 23, in __get__
cls, session=cls.__fsa__.session() # type: ignore[arg-type]
File "/backend/lib/python3.9/site-packages/sqlalchemy/orm/scoping.py", line 220, in __call__
sess = self.registry()
File "/backend/lib/python3.9/site-packages/sqlalchemy/util/_collections.py", line 632, in __call__
key = self.scopefunc()
File "/backend/lib/python3.9/site-packages/flask_sqlalchemy/session.py", line 111, in _app_ctx_id
return id(app_ctx._get_current_object()) # type: ignore[attr-defined]
File "/backend/lib/python3.9/site-packages/werkzeug/local.py", line 508, in _get_current_object
raise RuntimeError(unbound_message) from None
There was a recent change to allow the security handling logic access to the ConnexionRequest request object, but that doesn't help us here because our dependency needs access to the flask application context.
@RobbeSneyders since you recently worked on passing the ConnexionRequest to the security handler - do you have any recommendations for our use case? Essentially we have dependencies in our security handling path that requires access to the flask application context, and this does not seem possible in Connexion 3.0
Being able to access the flask application context, and, in particular, the FlaskSQLAlchemy at the Security Middleware is utterly important to my case as well, and I'm having a really really hard time from moving of Connexion2 to Connexion3.
Background
Flask-Limiter is a popular tool used to rate-limit endpoints of Flask applications.
We currently use it on our Flask server using connexion 2.14.2. However, due to the ASGI nature of Connexion 3.0, we are facing issues with the extension.
A basic use case of Flask-Limiter would be:
Internally, Flask-Limiter uses
flask.request.endpoint
to retrieve the key it should use to rate-limit for, but I don't thinkflask.request
is really accessible in connexion 3.0. Whenever I attempt to, I get an exception statingAttempted Solution
As I understand from reading the migration docs, connexion requests are now Starlette requests that can be retrieved via
from connexion import request
, so I attempted to take advantage of this. Flask-Limiter allows you define a callable in the Flask configRATELIMIT_REQUEST_IDENTIFIER
that replaces the use of flask.Request.endpoint, so I tried the following:class BaseConfig: """Configures common variables and other settings for the backend.""" def get_endpoint(): return request.scope["endpoint"]
RuntimeError: Working outside of application context.