Răsfoiți Sursa

TG-31: Implement /api/food/search fast fuzzy matching route

FerRo988 1 lună în urmă
părinte
comite
4b07ad42e7
2 a modificat fișierele cu 29 adăugiri și 1 ștergeri
  1. 18 0
      database.py
  2. 11 1
      main.py

+ 18 - 0
database.py

@@ -157,3 +157,21 @@ def delete_session(token: str):
         conn.close()
     except Exception as e:
         logger.error(f"Error deleting session: {e}")
+
+def search_foods_by_name(query: str, limit: int = 15) -> list[Dict[str, Any]]:
+    """Securely search for foods matching a string query using fuzzy matching"""
+    try:
+        conn = get_db_connection()
+        cursor = conn.cursor()
+        
+        # SQL Injection safe query utilizing LIKE parameterization
+        # COLLATE NOCASE search inherently supported by index on table creation
+        q = f"%{query}%"
+        cursor.execute("SELECT * FROM foods WHERE name LIKE ? LIMIT ?", (q, limit))
+        
+        rows = cursor.fetchall()
+        conn.close()
+        return [dict(row) for row in rows]
+    except Exception as e:
+        logger.error(f"Error searching foods: {e}")
+        return []

+ 11 - 1
main.py

@@ -4,7 +4,7 @@ import httpx
 import bcrypt
 from contextlib import asynccontextmanager
 from fastapi import FastAPI, HTTPException, Depends, Header
-from database import create_tables, create_user, get_user_by_username, create_session, get_user_from_token, delete_session
+from database import create_tables, create_user, get_user_by_username, create_session, get_user_from_token, delete_session, search_foods_by_name
 from fastapi.responses import HTMLResponse, StreamingResponse
 from fastapi.staticfiles import StaticFiles
 from pydantic import BaseModel
@@ -140,6 +140,16 @@ async def chat_endpoint(request: ChatRequest, current_user: dict = Depends(get_c
 
     return StreamingResponse(generate_response(), media_type="text/event-stream")
 
+@app.get("/api/food/search")
+async def search_food(q: str, current_user: dict = Depends(get_current_user)):
+    """API endpoint to search for food items securely using token authentication"""
+    if not q or len(q.strip()) < 1:
+        return {"results": []}
+    
+    logger.info(f"User {current_user['username']} searched for [{q}]")
+    results = search_foods_by_name(q.strip(), limit=15)
+    return {"results": results}
+
 if __name__ == "__main__":
     import uvicorn
     uvicorn.run("main:app", host="127.0.0.1", port=8000, reload=True)