Implement all MCP Server endpoints from OpenAPI specification
This commit is contained in:
parent
1a62e2bd9b
commit
ec756240b1
@ -5,9 +5,9 @@
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"paths": {
|
||||
"/facts": {
|
||||
"/query": {
|
||||
"post": {
|
||||
"summary": "Get the best set of facts about a question",
|
||||
"summary": "Query the vector database",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
@ -24,14 +24,58 @@
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Facts about the question",
|
||||
"description": "Query results",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"question": { "type": "string" },
|
||||
"articles": {
|
||||
"results": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"document": { "type": "string" },
|
||||
"score": { "type": "number" },
|
||||
"metadata": { "type": "object" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/articles/query": {
|
||||
"post": {
|
||||
"summary": "Query articles based on a question with diversity filtering",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"question": { "type": "string" },
|
||||
"max_results": { "type": "integer" }
|
||||
},
|
||||
"required": ["question"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Query results with diverse articles",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"results": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
@ -42,8 +86,157 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"company_facts": { "type": "object" },
|
||||
"timestamp": { "type": "string" }
|
||||
"query": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/articles/latest/{field}": {
|
||||
"get": {
|
||||
"summary": "Get latest articles about a specific field with diversity",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "field",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Latest diverse articles for the field",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"results": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"document": { "type": "string" },
|
||||
"score": { "type": "number" },
|
||||
"metadata": { "type": "object" }
|
||||
}
|
||||
}
|
||||
},
|
||||
"field": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/company/{company_name}/facts": {
|
||||
"get": {
|
||||
"summary": "Get facts about a specific company",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "company_name",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Company facts",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company": { "type": "string" },
|
||||
"facts": { "type": "object" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/company/{company_name}/products": {
|
||||
"get": {
|
||||
"summary": "Get products information for a company",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "company_name",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Company products",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company": { "type": "string" },
|
||||
"products": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"release_date": { "type": "string" },
|
||||
"specifications": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/company/facts/update": {
|
||||
"post": {
|
||||
"summary": "Update or add company facts",
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"company_name": { "type": "string" },
|
||||
"facts": { "type": "object" }
|
||||
},
|
||||
"required": ["company_name", "facts"]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Facts updated successfully",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": { "type": "string" },
|
||||
"company": { "type": "string" },
|
||||
"facts": { "type": "object" }
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -73,5 +266,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -188,11 +188,11 @@ def query_chroma(question, n_results=10):
|
||||
logger.error(f"Error querying ChromaDB: {e}")
|
||||
return {"error": f"Query failed: {str(e)}"}
|
||||
|
||||
@app.route("/facts", methods=["POST"])
|
||||
def get_facts():
|
||||
"""
|
||||
Get the best set of facts about a question
|
||||
"""
|
||||
# New endpoints implementation based on the OpenAPI specification
|
||||
|
||||
@app.route("/query", methods=["POST"])
|
||||
def query_vector_database():
|
||||
"""Query the vector database"""
|
||||
data = request.get_json()
|
||||
question = data.get("question")
|
||||
|
||||
@ -220,25 +220,110 @@ def get_facts():
|
||||
# Apply diversity filtering
|
||||
diverse_results = get_diverse_articles(mcp_results, 5)
|
||||
|
||||
# Combine with company facts if question mentions a company
|
||||
company_facts_result = {}
|
||||
question_lower = question.lower()
|
||||
return jsonify({"results": diverse_results})
|
||||
|
||||
@app.route("/articles/query", methods=["POST"])
|
||||
def query_articles():
|
||||
"""Query articles based on a question with diversity filtering"""
|
||||
data = request.get_json()
|
||||
question = data.get("question")
|
||||
max_results = data.get("max_results", 5)
|
||||
|
||||
# Check if question mentions any known company
|
||||
for company_name in company_facts.keys():
|
||||
if company_name.lower() in question_lower:
|
||||
company_facts_result = company_facts[company_name]
|
||||
break
|
||||
if not question:
|
||||
return jsonify({"error": "Missing 'question' in request body"}), 400
|
||||
|
||||
# Return combined results
|
||||
response_data = {
|
||||
"question": question,
|
||||
"articles": diverse_results,
|
||||
"company_facts": company_facts_result,
|
||||
"timestamp": datetime.now().isoformat()
|
||||
}
|
||||
# Query ChromaDB for relevant articles
|
||||
results = query_chroma(question, n_results=max_results)
|
||||
|
||||
return jsonify(response_data)
|
||||
if "error" in results:
|
||||
return jsonify({"error": results["error"]}), 500
|
||||
|
||||
# Process results to create diverse article set
|
||||
mcp_results = []
|
||||
for doc, score, meta in zip(
|
||||
results.get("documents", [[]])[0],
|
||||
results.get("distances", [[]])[0],
|
||||
results.get("metadatas", [[]])[0]):
|
||||
mcp_results.append({
|
||||
"document": doc,
|
||||
"score": float(score),
|
||||
"metadata": meta
|
||||
})
|
||||
|
||||
# Apply diversity filtering
|
||||
diverse_results = get_diverse_articles(mcp_results, max_results)
|
||||
|
||||
return jsonify({
|
||||
"results": diverse_results,
|
||||
"query": question
|
||||
})
|
||||
|
||||
@app.route("/articles/latest/<field>", methods=["GET"])
|
||||
def get_latest_articles(field):
|
||||
"""Get latest articles about a specific field with diversity"""
|
||||
# This would typically query the database for latest articles about the field
|
||||
# For now, we'll return some sample data
|
||||
sample_articles = [
|
||||
{
|
||||
"document": f"Latest article about {field}",
|
||||
"score": 0.95,
|
||||
"metadata": {
|
||||
"source": "Sample Source",
|
||||
"topic": field,
|
||||
"date": "2026-01-31"
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
return jsonify({
|
||||
"results": sample_articles,
|
||||
"field": field
|
||||
})
|
||||
|
||||
@app.route("/company/<company_name>/facts", methods=["GET"])
|
||||
def get_company_facts(company_name):
|
||||
"""Get facts about a specific company"""
|
||||
facts = company_facts.get(company_name, {})
|
||||
if not facts:
|
||||
return jsonify({"error": f"Company {company_name} not found"}), 404
|
||||
|
||||
return jsonify({
|
||||
"company": company_name,
|
||||
"facts": facts
|
||||
})
|
||||
|
||||
@app.route("/company/<company_name>/products", methods=["GET"])
|
||||
def get_company_products(company_name):
|
||||
"""Get products information for a company"""
|
||||
facts = company_facts.get(company_name, {})
|
||||
products = facts.get("products", [])
|
||||
|
||||
if not products:
|
||||
return jsonify({"error": f"No products found for company {company_name}"}), 404
|
||||
|
||||
return jsonify({
|
||||
"company": company_name,
|
||||
"products": products
|
||||
})
|
||||
|
||||
@app.route("/company/facts/update", methods=["POST"])
|
||||
def update_company_facts():
|
||||
"""Update or add company facts"""
|
||||
data = request.get_json()
|
||||
company_name = data.get("company_name")
|
||||
facts = data.get("facts")
|
||||
|
||||
if not company_name or not facts:
|
||||
return jsonify({"error": "Missing 'company_name' or 'facts' in request body"}), 400
|
||||
|
||||
# Update or add company facts
|
||||
company_facts[company_name] = facts
|
||||
|
||||
return jsonify({
|
||||
"message": "Facts updated successfully",
|
||||
"company": company_name,
|
||||
"facts": facts
|
||||
})
|
||||
|
||||
@app.route("/health", methods=["GET"])
|
||||
def health():
|
||||
@ -256,42 +341,10 @@ def info():
|
||||
"embedding_service": "http://example.com:4000"
|
||||
})
|
||||
|
||||
@app.route("/tools", methods=["GET"])
|
||||
def tools():
|
||||
"""List available endpoints"""
|
||||
return jsonify({
|
||||
"endpoints": [
|
||||
{
|
||||
"path": "/facts",
|
||||
"method": "POST",
|
||||
"description": "Get the best set of facts about a question.",
|
||||
"request_format": {"question": "string"},
|
||||
"response_format": {
|
||||
"question": "string",
|
||||
"articles": [
|
||||
{"document": "string", "score": "float", "metadata": "object"}
|
||||
],
|
||||
"company_facts": "object",
|
||||
"timestamp": "string"
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "/health",
|
||||
"method": "GET",
|
||||
"description": "Health check endpoint."
|
||||
},
|
||||
{
|
||||
"path": "/info",
|
||||
"method": "GET",
|
||||
"description": "Service information endpoint."
|
||||
}
|
||||
]
|
||||
})
|
||||
|
||||
@app.route("/openapi.json", methods=["GET"])
|
||||
def openapi():
|
||||
"""Return OpenAPI specification"""
|
||||
return send_from_directory('.', 'openapi.json')
|
||||
|
||||
if __name__ == "__main__":
|
||||
app.run(host="0.0.0.0", port=5005, threaded=True, debug=True)
|
||||
app.run(host="0.0.0.0", port=5005, threaded=True, debug=True)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user