-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.py
More file actions
147 lines (110 loc) · 3.93 KB
/
Copy pathapp.py
File metadata and controls
147 lines (110 loc) · 3.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
from flask import Flask
from flask import render_template, request, jsonify
from datetime import datetime
import re
import flask_sqlalchemy
# persistence with SQLite via SQLAlchemy
from flask_sqlalchemy import SQLAlchemy
# local Ollama client wrapper
from chat import ollama_client
app = Flask(__name__)
# configure database (SQLite file in project root)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///chat_history.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# make sure the instance path exists (SQLite file will live here)
import os
# ensure instance directory exists (Flask uses this for SQLite file)
os.makedirs(app.instance_path, exist_ok=True)
# initialize ORM
db = SQLAlchemy(app)
# simple model for storing chat messages
class ChatEntry(db.Model):
id = db.Column(db.Integer, primary_key=True)
role = db.Column(db.String(10), nullable=False)
content = db.Column(db.Text, nullable=False)
timestamp = db.Column(db.DateTime, default=datetime.utcnow, nullable=False)
def to_dict(self):
return {
'id': self.id,
'role': self.role,
'content': self.content,
'timestamp': self.timestamp.isoformat(),
}
# create database tables now that models are defined
with app.app_context():
db.create_all()
# Home page
@app.route("/")
def home():
return render_template("home.html")
# About page
@app.route("/about/")
def about():
return render_template("about.html")
# Contact page
@app.route("/contact/")
def contact():
return render_template("contact.html")
@app.route("/hello")
@app.route("/hello/<name>")
def hello_there(name = None):
return render_template(
"hello_there.html",
name = name,
date = datetime.now()
)
@app.route("/api/data")
def get_data():
return app.send_static_file("data.json")
@app.route('/chat', methods=['GET'])
def chat_health():
"""Health-check for the Ollama server.
Returns 200 when available, 503 when not.
"""
ok = ollama_client.is_server_available()
status = {"ollama_available": ok}
return jsonify(status), (200 if ok else 503)
@app.route('/chat', methods=['POST'])
def chat_route():
"""Simple JSON POST endpoint that proxies messages to Ollama.
Expected JSON body: {"messages": [{"role":"user","content":"..."}, ...], "model": "llama3"}
"""
data = request.get_json(force=True, silent=True)
if not data:
return jsonify({"error": "invalid or missing JSON body"}), 400
messages = data.get('messages')
model = data.get('model', 'llama3')
if not isinstance(messages, list):
return jsonify({"error": "'messages' must be a list"}), 400
try:
# persist incoming messages
for msg in messages:
entry = ChatEntry(role=msg.get('role', ''), content=msg.get('content', ''))
db.session.add(entry)
result = ollama_client.chat(messages=messages, model=model)
# if response contains a reply, store it as well
reply_text = None
if isinstance(result, dict):
reply_text = result.get('reply') or result.get('result')
if reply_text:
db.session.add(ChatEntry(role='assistant', content=reply_text))
db.session.commit()
return jsonify(result)
except RuntimeError as e:
db.session.rollback()
return jsonify({"error": str(e)}), 503
except Exception as e:
db.session.rollback()
return jsonify({"error": "internal error", "detail": str(e)}), 500
@app.route('/chat_history')
def chat_history():
"""Return stored chat conversation as JSON list."""
entries = ChatEntry.query.order_by(ChatEntry.timestamp).all()
return jsonify([e.to_dict() for e in entries])
@app.route('/chat_ui')
def chat_ui():
"""Render the simple browser-based chat UI."""
return render_template('chat.html')
if __name__ == '__main__':
# run via `python app.py` for convenience during development
app.run(debug=True)