128 lines
5.1 KiB
Python
128 lines
5.1 KiB
Python
|
|
"""V2 API routes - Enhanced implementation with structured results."""
|
||
|
|
from __future__ import annotations
|
||
|
|
|
||
|
|
import time
|
||
|
|
from flask import Blueprint, jsonify, request
|
||
|
|
from concurrent.futures import ThreadPoolExecutor
|
||
|
|
|
||
|
|
from lawrisk.services.lawrisk_v2_service import search_v2, list_regions
|
||
|
|
from lawrisk.services.licensing_repo import list_permits_for_region
|
||
|
|
from lawrisk.services.lawrisk_service import suggest_questions_embed
|
||
|
|
|
||
|
|
v2_bp = Blueprint('lawrisk_v2', __name__, url_prefix='/fs-ai-asistant/api/workflow/lawrisk')
|
||
|
|
|
||
|
|
|
||
|
|
@v2_bp.route('/v2', methods=['POST', 'GET'])
|
||
|
|
def lawrisk_search_v2():
|
||
|
|
"""V2 search endpoint with structured results."""
|
||
|
|
query, debug_flag, top_k_int, _mode, region_filter = _extract_params()
|
||
|
|
|
||
|
|
if not query or not isinstance(query, str):
|
||
|
|
return jsonify({"error": "query is required"}), 400
|
||
|
|
|
||
|
|
try:
|
||
|
|
t0 = time.time()
|
||
|
|
with ThreadPoolExecutor(max_workers=2) as ex:
|
||
|
|
fut_subject = ex.submit(search_v2, query, debug_flag, region_filter)
|
||
|
|
fut_questions = ex.submit(suggest_questions_embed, query, max(1, top_k_int))
|
||
|
|
|
||
|
|
result_v2 = fut_subject.result()
|
||
|
|
rec_questions = fut_questions.result() or []
|
||
|
|
|
||
|
|
risk_subject = result_v2.get("risk_subject", []) if isinstance(result_v2, dict) else []
|
||
|
|
found = bool(risk_subject)
|
||
|
|
exec_time = int((time.time() - t0) * 1000)
|
||
|
|
|
||
|
|
data = {
|
||
|
|
"llmRespond": "" if found else "抱歉,无法检索到相关答案",
|
||
|
|
"lawRisk": "",
|
||
|
|
"questionExtend": rec_questions,
|
||
|
|
"conversationId": "",
|
||
|
|
"messageId": "",
|
||
|
|
"roundNumber": 0,
|
||
|
|
"conversationInfo": {},
|
||
|
|
"knowledgeSources": [],
|
||
|
|
"totalKnowledgeSources": 0,
|
||
|
|
"executionTime": exec_time,
|
||
|
|
"workflowStatus": "ok" if found else "no_match",
|
||
|
|
"executionSteps": [],
|
||
|
|
"costStatistics": {},
|
||
|
|
"workflowTrackingId": "",
|
||
|
|
"risk_subject": risk_subject,
|
||
|
|
"debug": result_v2.get("debug", {}) if (debug_flag and isinstance(result_v2, dict)) else {},
|
||
|
|
}
|
||
|
|
resp = {"success": True, "message": "OK", "data": data}
|
||
|
|
return jsonify(resp)
|
||
|
|
except Exception as e:
|
||
|
|
print(f"lawrisk_search_v2 error: {e}")
|
||
|
|
return jsonify({"success": False, "message": str(e), "data": {}}), 500
|
||
|
|
|
||
|
|
|
||
|
|
@v2_bp.get('/v2/regions')
|
||
|
|
def lawrisk_regions():
|
||
|
|
"""Get list of available regions."""
|
||
|
|
try:
|
||
|
|
regions = list_regions()
|
||
|
|
return jsonify({"success": True, "data": {"regions": regions}})
|
||
|
|
except Exception as exc:
|
||
|
|
print(f"lawrisk_regions error: {exc}")
|
||
|
|
return jsonify({"success": False, "message": str(exc)}), 500
|
||
|
|
|
||
|
|
|
||
|
|
@v2_bp.route('/getPermits', methods=['GET', 'POST'])
|
||
|
|
def lawrisk_get_permits():
|
||
|
|
"""Get permits for a specific region."""
|
||
|
|
if request.method == "GET":
|
||
|
|
region_value = request.args.get("region") or request.args.get("region_id")
|
||
|
|
else:
|
||
|
|
if request.is_json:
|
||
|
|
payload = request.get_json(silent=True) or {}
|
||
|
|
else:
|
||
|
|
payload = request.form.to_dict(flat=True) if request.form else {}
|
||
|
|
region_value = payload.get("region") or payload.get("region_id")
|
||
|
|
|
||
|
|
if not region_value or (isinstance(region_value, str) and not region_value.strip()):
|
||
|
|
return jsonify({"success": False, "message": "region is required", "data": {}}), 400
|
||
|
|
|
||
|
|
region_token = region_value.strip() if isinstance(region_value, str) else str(region_value)
|
||
|
|
|
||
|
|
try:
|
||
|
|
permits = list_permits_for_region(region_token)
|
||
|
|
return jsonify({"success": True, "data": {"region": region_token, "permits": permits}})
|
||
|
|
except Exception as exc:
|
||
|
|
print(f"lawrisk_get_permits error: {exc}")
|
||
|
|
return jsonify({"success": False, "message": str(exc)}), 500
|
||
|
|
|
||
|
|
|
||
|
|
def _extract_params():
|
||
|
|
"""Extract parameters from request."""
|
||
|
|
if request.method == "GET":
|
||
|
|
query = request.args.get("query") or request.args.get("q") or request.args.get("text")
|
||
|
|
debug_flag = request.args.get("debug") in {"1", "true", "yes", "on"}
|
||
|
|
top_k = request.args.get("top")
|
||
|
|
try:
|
||
|
|
top_k_int = int(top_k) if top_k else 5
|
||
|
|
except Exception:
|
||
|
|
top_k_int = 5
|
||
|
|
mode_value = (request.args.get("mode") or "llm").lower()
|
||
|
|
region_value = request.args.get("region") or request.args.get("region_id")
|
||
|
|
region_list = request.args.getlist("region")
|
||
|
|
if region_list and (not region_value or len(region_list) > 1):
|
||
|
|
region_value = region_list
|
||
|
|
else:
|
||
|
|
if request.is_json:
|
||
|
|
payload = request.get_json(silent=True) or {}
|
||
|
|
else:
|
||
|
|
payload = request.form.to_dict(flat=True) if request.form else {}
|
||
|
|
|
||
|
|
query = payload.get("query") or payload.get("q") or payload.get("text")
|
||
|
|
debug_flag = str(payload.get("debug", "")).strip().lower() in {"1", "true", "yes", "on"}
|
||
|
|
try:
|
||
|
|
top_k_int = int(payload.get("top", 5))
|
||
|
|
except Exception:
|
||
|
|
top_k_int = 5
|
||
|
|
mode_value = str(payload.get("mode", "llm")).lower()
|
||
|
|
region_value = payload.get("region") or payload.get("region_id")
|
||
|
|
|
||
|
|
return query, debug_flag, top_k_int, mode_value, region_value
|