Skip to content

Commit 0430cef

Browse files
3
1 parent 83408f3 commit 0430cef

File tree

10 files changed

+367
-266
lines changed

10 files changed

+367
-266
lines changed

app.py

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,7 @@
1-
from flask import Flask, send_from_directory, request, jsonify
1+
from flask import Flask, render_template, jsonify, request
22
import requests
3-
from werkzeug.exceptions import NotFound
43
from ollamaClient import OllamaClient
54

6-
# Constants
7-
TEMPLATE_FOLDER = "./templates"
8-
95
# Initialize Flask app and Ollama client
106
app = Flask(__name__)
117
ai = OllamaClient()
@@ -14,36 +10,30 @@
1410
# Route to serve the main index page
1511
@app.route("/")
1612
def index():
17-
return send_from_directory(directory=TEMPLATE_FOLDER, path="index.html")
18-
13+
return render_template("index.html"),200
1914

20-
# Route to handle other static pages
21-
@app.route("/<path:name>")
22-
def page_handler(name):
23-
try:
24-
return send_from_directory(directory=TEMPLATE_FOLDER, path=name)
25-
except NotFound:
26-
return send_from_directory(directory=TEMPLATE_FOLDER, path="404.html"), 404
2715

16+
@app.errorhandler(Exception)
17+
def error_page(error):
18+
if hasattr(error, "code") and error.code == 404:
19+
return render_template("404.html"), 404
2820

29-
# Custom 404 error handler
30-
@app.errorhandler(404)
31-
def page_not_found(error):
32-
return send_from_directory(directory=TEMPLATE_FOLDER, path="404.html"), 404
21+
return (
22+
render_template("error.html", error=str(error)),
23+
500,
24+
) # Return 500 for general errors
3325

3426

3527
# API endpoint to check connection to the Ollama server
3628
@app.route("/api/connection")
3729
def api_connection():
3830
try:
39-
# Attempt to connect to the Ollama server
4031
res = requests.get("http://localhost:11434", timeout=5)
4132
status_code = res.status_code
4233
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
4334
print("[LOG] ERROR: UNABLE TO CONNECT TO SERVER")
4435
status_code = 404
4536

46-
# Return appropriate response based on connection status
4737
if status_code == 200:
4838
return jsonify({"host": "localhost", "port": 11434, "status": "OK"}), 200
4939
else:
@@ -53,14 +43,12 @@ def api_connection():
5343
# API endpoint to get connection stats (available and active models)
5444
@app.route("/api/connection/stats")
5545
def api_connection_stats():
56-
list_of_models = ai.listModels()
57-
list_of_active_models = ai.listActiveModels()
46+
list_of_models = ai.list_models()
47+
list_of_active_models = ai.list_active_models()
5848

59-
# Handle cases where no models are available or active
6049
if not list_of_models and not list_of_active_models:
6150
return jsonify({"error": "No models found"}), 404
6251

63-
# Prepare response data
6452
data = {
6553
"available": list_of_models,
6654
"active": list_of_active_models,
@@ -69,22 +57,24 @@ def api_connection_stats():
6957
return jsonify(data), 200
7058

7159

72-
# API endpoint to handle chat requests
7360
@app.route("/api/chat", methods=["POST"])
7461
def api_chat():
75-
data = request.get_json()
62+
# Get JSON data from the request
63+
data = request.json
64+
prompt = data.get("prompt")
65+
model = data.get("model")
7666

77-
# Validate required fields in the request
78-
if not data or "prompt" not in data or "model" not in data:
79-
return jsonify({"error": "Missing 'prompt' or 'model' in request"}), 400
67+
if not prompt:
68+
return jsonify({"error": "Missing 'prompt' in request"}), 400
69+
if not model:
70+
return jsonify({"error": "Missing 'model' in request"}), 400
71+
72+
# Assuming ai.chat is a function that takes prompt and model as arguments
73+
res = ai.chat(prompt=prompt, model=model)
74+
75+
# Return the response as JSON
76+
return jsonify({"response": res}), 200
8077

81-
try:
82-
# Send the chat request to the Ollama client
83-
res = ai.chat(prompt=data.get("prompt"), model=data.get("model"))
84-
return jsonify(res), 200
85-
except Exception as e:
86-
print(f"[LOG] ERROR: {e}")
87-
return jsonify({"error": "Failed to process chat request"}), 500
8878

8979
if __name__ == "__main__":
90-
app.run()
80+
app.run(debug=True) # Set debug=True for development

ollamaClient.py

Lines changed: 79 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,82 +1,105 @@
11
import requests
22
import json
33

4-
ollama_serve = "http://localhost:11434"
5-
collection_of_apis = {
4+
# Constants
5+
OLLAMA_SERVER = "http://localhost:11434"
6+
API_ENDPOINTS = {
67
"list-models": "/api/tags",
78
"list-active-models": "/api/ps",
89
"chat": "/api/chat",
910
}
1011

11-
def get_data(url):
12-
try:
13-
res = requests.get(url, timeout=5)
14-
data = res.json()
15-
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
16-
print("[LOG] ERROR : UNABLE TO CONNECT TO SERVER")
17-
data = {}
18-
19-
return data
2012

21-
def post_data(url, data):
22-
headers = {'Content-Type': 'application/json'}
13+
# Helper functions
14+
def fetch_data(url):
15+
"""Fetch data from a given URL using a GET request."""
2316
try:
24-
res = requests.post(url, json=data, headers=headers,stream=True)
25-
content = res.text # parse response as JSON
26-
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
27-
print("[LOG] ERROR : UNABLE TO CONNECT TO SERVER")
28-
content = {}
29-
30-
return content
31-
17+
response = requests.get(url, timeout=5)
18+
response.raise_for_status() # Raise an exception for HTTP errors
19+
return response.json()
20+
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
21+
print(f"[LOG] ERROR: Unable to connect to server - {e}")
22+
return {}
23+
except requests.exceptions.RequestException as e:
24+
print(f"[LOG] ERROR: Request failed - {e}")
25+
return {}
26+
27+
28+
def send_data(url, data):
29+
"""Send data to a given URL using a POST request."""
30+
headers = {"Content-Type": "application/json"}
31+
try:
32+
response = requests.post(url, json=data, headers=headers, stream=True)
33+
response.raise_for_status() # Raise an exception for HTTP errors
34+
return response.text # Return text instead of raw content
35+
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout) as e:
36+
print(f"[LOG] ERROR: Unable to connect to server - {e}")
37+
return ""
38+
except requests.exceptions.RequestException as e:
39+
print(f"[LOG] ERROR: Request failed - {e}")
40+
return ""
41+
42+
43+
# Ollama Client Class
3244
class OllamaClient:
33-
3445
@staticmethod
35-
def listModels():
36-
data = get_data(ollama_serve + collection_of_apis.get("list-models"))
37-
38-
if data == {}:
46+
def list_models():
47+
"""Fetch and return a list of available models."""
48+
data = fetch_data(OLLAMA_SERVER + API_ENDPOINTS["list-models"])
49+
if not data:
3950
return []
4051

41-
filter_data = data.get('models') # should be 'models' not 'model'
42-
43-
results = []
44-
for item in filter_data:
45-
results.append({"name": item.get("name"), "model": item.get("model")})
46-
47-
return results
52+
models = data.get("models", [])
53+
return [
54+
{"name": item.get("name", ""), "model": item.get("model", "")}
55+
for item in models
56+
]
4857

4958
@staticmethod
50-
def listActiveModels():
51-
data = get_data(ollama_serve + collection_of_apis.get("list-active-models"))
52-
53-
if data=={}:
59+
def list_active_models():
60+
"""Fetch and return a list of active models."""
61+
data = fetch_data(OLLAMA_SERVER + API_ENDPOINTS["list-active-models"])
62+
if not data:
5463
return []
5564

56-
filter_data = data.get("models") # should be 'models' not 'model'
57-
58-
results = []
59-
for item in filter_data:
60-
results.append({"name": item.get("name"), "model": item.get("model")})
61-
62-
return results
65+
models = data.get("models", [])
66+
return [
67+
{"name": item.get("name", ""), "model": item.get("model", "")}
68+
for item in models
69+
]
6370

6471
@staticmethod
6572
def chat(model, prompt):
73+
"""Send a chat prompt to a specified model and return the response."""
6674
data = {
6775
"model": model,
6876
"messages": [{"role": "user", "content": prompt}],
6977
}
7078

71-
res = post_data(ollama_serve + collection_of_apis.get("chat"), data)
72-
# return res
73-
lines = res.split('\n')[:-1]
74-
parsed_json = []
75-
for line in lines:
76-
parsed_json.append(json.loads(line))
77-
78-
results=[]
79-
for item in parsed_json:
80-
results.append(item["message"]["content"])
81-
82-
return "".join(results)
79+
response_text = send_data(OLLAMA_SERVER + API_ENDPOINTS["chat"], data)
80+
if not response_text:
81+
return ""
82+
83+
# Parse the response (assuming it's a stream of JSON objects)
84+
parsed_lines = []
85+
for line in response_text.split("\n"):
86+
if line.strip():
87+
try:
88+
parsed_lines.append(json.loads(line))
89+
except json.JSONDecodeError as e:
90+
print(f"[LOG] ERROR: Failed to parse JSON - {e}")
91+
92+
# Extract the message contents
93+
response_messages = [
94+
item.get("message", {}).get("content", "")
95+
for item in parsed_lines
96+
if "message" in item
97+
]
98+
99+
response_str = "".join(response_messages)
100+
101+
print(
102+
f"[LOG] INCOMING DATA:\nmodel: {model}\nprompt: {prompt}\nOUTGOING:\nResponse: {response_str}"
103+
)
104+
105+
return response_str

0 commit comments

Comments
 (0)