mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-01-30 15:16:45 +08:00
Fix : Web API tests by normalizing errors, validation, and uploads (#12620)
### What problem does this PR solve? Fixes web API behavior mismatches that caused test failures by normalizing error responses, tightening validations, correcting error messages, and closing upload file handles. ### Type of change - [x] Bug Fix (non-breaking change which fixes an issue)
This commit is contained in:
@ -16,21 +16,23 @@
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
from importlib.util import module_from_spec, spec_from_file_location
|
||||
from pathlib import Path
|
||||
from quart import Blueprint, Quart, request, g, current_app, session
|
||||
from quart import Blueprint, Quart, request, g, current_app, session, jsonify
|
||||
from itsdangerous.url_safe import URLSafeTimedSerializer as Serializer
|
||||
from quart_cors import cors
|
||||
from common.constants import StatusEnum
|
||||
from common.constants import StatusEnum, RetCode
|
||||
from api.db.db_models import close_connection, APIToken
|
||||
from api.db.services import UserService
|
||||
from api.utils.json_encode import CustomJSONEncoder
|
||||
from api.utils import commands
|
||||
|
||||
from quart_auth import Unauthorized
|
||||
from quart_auth import Unauthorized as QuartAuthUnauthorized
|
||||
from werkzeug.exceptions import Unauthorized as WerkzeugUnauthorized
|
||||
from quart_schema import QuartSchema
|
||||
from common import settings
|
||||
from api.utils.api_utils import server_error_response
|
||||
from api.utils.api_utils import server_error_response, get_json_result
|
||||
from api.constants import API_VERSION
|
||||
from common.misc_utils import get_uuid
|
||||
|
||||
@ -38,6 +40,22 @@ settings.init_settings()
|
||||
|
||||
__all__ = ["app"]
|
||||
|
||||
UNAUTHORIZED_MESSAGE = "<Unauthorized '401: Unauthorized'>"
|
||||
|
||||
|
||||
def _unauthorized_message(error):
|
||||
if error is None:
|
||||
return UNAUTHORIZED_MESSAGE
|
||||
try:
|
||||
msg = repr(error)
|
||||
except Exception:
|
||||
return UNAUTHORIZED_MESSAGE
|
||||
if msg == UNAUTHORIZED_MESSAGE:
|
||||
return msg
|
||||
if "Unauthorized" in msg and "401" in msg:
|
||||
return msg
|
||||
return UNAUTHORIZED_MESSAGE
|
||||
|
||||
app = Quart(__name__)
|
||||
app = cors(app, allow_origin="*")
|
||||
|
||||
@ -145,10 +163,18 @@ def login_required(func: Callable[P, Awaitable[T]]) -> Callable[P, Awaitable[T]]
|
||||
|
||||
@wraps(func)
|
||||
async def wrapper(*args: P.args, **kwargs: P.kwargs) -> T:
|
||||
if not current_user: # or not session.get("_user_id"):
|
||||
raise Unauthorized()
|
||||
else:
|
||||
return await current_app.ensure_async(func)(*args, **kwargs)
|
||||
timing_enabled = os.getenv("RAGFLOW_API_TIMING")
|
||||
t_start = time.perf_counter() if timing_enabled else None
|
||||
user = current_user
|
||||
if timing_enabled:
|
||||
logging.info(
|
||||
"api_timing login_required auth_ms=%.2f path=%s",
|
||||
(time.perf_counter() - t_start) * 1000,
|
||||
request.path,
|
||||
)
|
||||
if not user: # or not session.get("_user_id"):
|
||||
raise QuartAuthUnauthorized()
|
||||
return await current_app.ensure_async(func)(*args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
@ -258,12 +284,33 @@ client_urls_prefix = [
|
||||
|
||||
@app.errorhandler(404)
|
||||
async def not_found(error):
|
||||
error_msg: str = f"The requested URL {request.path} was not found"
|
||||
logging.error(error_msg)
|
||||
return {
|
||||
logging.error(f"The requested URL {request.path} was not found")
|
||||
message = f"Not Found: {request.path}"
|
||||
response = {
|
||||
"code": RetCode.NOT_FOUND,
|
||||
"message": message,
|
||||
"data": None,
|
||||
"error": "Not Found",
|
||||
"message": error_msg,
|
||||
}, 404
|
||||
}
|
||||
return jsonify(response), RetCode.NOT_FOUND
|
||||
|
||||
|
||||
@app.errorhandler(401)
|
||||
async def unauthorized(error):
|
||||
logging.warning("Unauthorized request")
|
||||
return get_json_result(code=RetCode.UNAUTHORIZED, message=_unauthorized_message(error)), RetCode.UNAUTHORIZED
|
||||
|
||||
|
||||
@app.errorhandler(QuartAuthUnauthorized)
|
||||
async def unauthorized_quart_auth(error):
|
||||
logging.warning("Unauthorized request (quart_auth)")
|
||||
return get_json_result(code=RetCode.UNAUTHORIZED, message=repr(error)), RetCode.UNAUTHORIZED
|
||||
|
||||
|
||||
@app.errorhandler(WerkzeugUnauthorized)
|
||||
async def unauthorized_werkzeug(error):
|
||||
logging.warning("Unauthorized request (werkzeug)")
|
||||
return get_json_result(code=RetCode.UNAUTHORIZED, message=_unauthorized_message(error)), RetCode.UNAUTHORIZED
|
||||
|
||||
@app.teardown_request
|
||||
def _db_close(exception):
|
||||
|
||||
Reference in New Issue
Block a user