2025 / api.py
muhammadshaheryar's picture
Update api.py
19924d7 verified
from flask import Flask, request, jsonify
from flask_cors import CORS
import sys
import os
import logging
# Add project root to PYTHONPATH
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(BASE_DIR)
# ✅ Correct imports based on your structure
from .python.vector_store import VectorStore
from .embedder_wrapper import SyncEmbedder
from .python.config import (
OPENAI_API_KEY,
QDRANT_URL,
QDRANT_API_KEY,
COLLECTION_NAME
)
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
app = Flask(__name__)
CORS(
app,
origins=[
"http://localhost:3000",
"http://localhost:5000",
"http://127.0.0.1:3000",
"http://127.0.0.1:5000"
],
supports_credentials=True,
allow_headers=["Content-Type", "Authorization"]
)
# Initialize services
try:
vector_store = VectorStore(
url=QDRANT_URL,
api_key=QDRANT_API_KEY,
collection_name=COLLECTION_NAME
)
embedder = SyncEmbedder(api_key=OPENAI_API_KEY)
logger.info("✅ Services initialized successfully")
except Exception as e:
logger.error(f"❌ Failed to initialize services: {e}")
raise
@app.route('/chat', methods=['POST'])
def chat():
try:
data = request.get_json()
if not data or 'message' not in data:
return jsonify({'error': 'Message field is required'}), 400
user_message = data['message']
# Create embedding
query_embedding = embedder.embed_text(user_message)
# Vector search
similar_docs = vector_store.search_similar(query_embedding, top_k=5)
context = "\n".join(doc.get("content", "") for doc in similar_docs)
# Prompt
if context.strip():
prompt = f"""
Answer the question using the context below.
If the answer is not in the context, say you don't know.
Context:
{context}
Question:
{user_message}
Answer:
"""
else:
prompt = f"""
Answer the following question.
If you don't know, say you don't know.
Question:
{user_message}
Answer:
"""
# OpenAI call
from openai import OpenAI
client = OpenAI(api_key=OPENAI_API_KEY)
response = client.chat.completions.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}],
temperature=0.3,
max_tokens=500
)
bot_response = response.choices[0].message.content.strip()
return jsonify({
"response": bot_response,
"sources": [doc.get("source", "") for doc in similar_docs],
"scores": [doc.get("score", 0.0) for doc in similar_docs]
})
except Exception as e:
logger.error(f"Chat error: {e}")
return jsonify({"error": str(e)}), 500
@app.route('/health', methods=['GET'])
def health():
return jsonify({"status": "healthy"})
@app.route('/documents/count', methods=['GET'])
def document_count():
try:
count = vector_store.get_all_documents_count()
return jsonify({"count": count})
except Exception as e:
logger.error(f"Count error: {e}")
return jsonify({"error": str(e)}), 500
if __name__ == "__main__":
app.run(host="0.0.0.0", port=7860, debug=False)