From ac9ad979b17c0fd80a71021d5b3e72cba101892d Mon Sep 17 00:00:00 2001 From: Lordwill Date: Thu, 30 Apr 2026 08:28:12 +0200 Subject: [PATCH] Add API validation and consistent JSON errors Made-by: LordKay-sudo --- main.py | 55 ++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/main.py b/main.py index 06268e4..dbdefa0 100644 --- a/main.py +++ b/main.py @@ -3,7 +3,7 @@ import sys import signal from datetime import datetime, timezone -from flask import Flask, request, render_template, abort +from flask import Flask, request, render_template, abort, jsonify from markupsafe import Markup import mistune import uuid @@ -88,6 +88,31 @@ def get_chat_history(user_id): return db.list_by_user(user_id, 10) +def api_error(message, status_code=400): + """return a consistent API error payload""" + logging.error(message) + return jsonify({"error": {"message": message}}), status_code + + +def parse_api_question(): + """validate and normalize question from API JSON payload""" + body = request.get_json(silent=True) + log.debug(body) + if not isinstance(body, dict): + return None, api_error( + "invalid request body: expected JSON object", 400) + + question = body.get("question") + if not isinstance(question, str): + return None, api_error("missing field: question", 400) + + question = question.strip() + if question == "": + return None, api_error("field 'question' cannot be empty", 400) + + return question, None + + @app.route("/") def index(): """home page""" @@ -189,7 +214,6 @@ def ask_internal(conversation, question): # fetch latest conversation conversation = db.get(conversation_id, user_id) - sources = [] return answer, conversation, sources @@ -213,14 +237,10 @@ def get_conversation(id): def ask_api_new(): """returns an answer to a question in a new conversation""" - # get request json from body - body = request.get_json() - log.debug(body) - if "question" not in body: - m = "missing field: question" - logging.error(m) - abort(400, m) - question = body["question"] + question, error = parse_api_question() + if error is not None: + return error + user_id = get_current_user_id() conversation = { "conversationId": str(uuid.uuid4()), @@ -241,21 +261,14 @@ def ask_api_new(): def ask_api(id): """returns an answer to a question in a conversation""" - # get request json from body - body = request.get_json() - log.debug(body) - if "question" not in body: - m = "missing field: question" - logging.error(m) - abort(400, m) - question = body["question"] + question, error = parse_api_question() + if error is not None: + return error user_id = get_current_user_id() if id == "": - m = "conversation id is required" - logging.error(m) - abort(400, m) + return api_error("conversation id is required", 400) else: conversation = db.get(id, user_id) logging.info("fetched conversation")