OzoneAsai commited on
Commit
4ce4f5d
1 Parent(s): 1f3e5b4

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +166 -0
app.py ADDED
@@ -0,0 +1,166 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ from flask import Flask, request, jsonify, render_template_string
3
+ from llama_cpp import Llama
4
+ from pydantic import BaseModel, ValidationError
5
+ from typing import List
6
+ import logging
7
+
8
+ app = Flask(__name__)
9
+
10
+ # Configure logging
11
+ logging.basicConfig(level=logging.INFO)
12
+ logger = logging.getLogger(__name__)
13
+
14
+ # Initialize the Llama model
15
+ llm = Llama.from_pretrained(
16
+ repo_id="bartowski/Marco-o1-GGUF",
17
+ filename="Marco-o1-Q3_K_M.gguf",
18
+ )
19
+
20
+ # Pydantic Models
21
+ class Message(BaseModel):
22
+ role: str
23
+ content: str
24
+
25
+ class ChatRequest(BaseModel):
26
+ messages: List[Message]
27
+
28
+ class ChatResponse(BaseModel):
29
+ response: str
30
+
31
+ # Route to serve the chat interface
32
+ @app.route('/')
33
+ def index():
34
+ html_content = """
35
+ <!DOCTYPE html>
36
+ <html>
37
+ <head>
38
+ <meta charset="UTF-8">
39
+ <title>Llama Chat Interface</title>
40
+ <style>
41
+ body { font-family: Arial, sans-serif; background-color: #f4f4f4; padding: 20px; }
42
+ #chat-container { max-width: 600px; margin: auto; background: #fff; padding: 20px; border-radius: 5px; }
43
+ #messages { border: 1px solid #ccc; padding: 10px; height: 300px; overflow-y: scroll; }
44
+ .message { margin-bottom: 15px; }
45
+ .user { color: blue; }
46
+ .assistant { color: green; }
47
+ #input-form { display: flex; margin-top: 10px; }
48
+ #input-form input { flex: 1; padding: 10px; border: 1px solid #ccc; border-radius: 3px; }
49
+ #input-form button { padding: 10px; border: none; background: #28a745; color: #fff; cursor: pointer; border-radius: 3px; margin-left: 5px; }
50
+ #input-form button:hover { background: #218838; }
51
+ </style>
52
+ </head>
53
+ <body>
54
+ <div id="chat-container">
55
+ <h2>Llama Chatbot</h2>
56
+ <div id="messages"></div>
57
+ <form id="input-form">
58
+ <input type="text" id="user-input" placeholder="Type your message here..." required />
59
+ <button type="submit">Send</button>
60
+ </form>
61
+ </div>
62
+
63
+ <!-- Babel CDN -->
64
+ <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
65
+
66
+ <!-- Your JavaScript Code -->
67
+ <script type="text/babel">
68
+ const chatContainer = document.getElementById('messages');
69
+ const inputForm = document.getElementById('input-form');
70
+ const userInput = document.getElementById('user-input');
71
+
72
+ // Function to append messages to the chat container
73
+ function appendMessage(role, content) {
74
+ const messageDiv = document.createElement('div');
75
+ messageDiv.classList.add('message');
76
+ if (role === 'user') {
77
+ messageDiv.classList.add('user');
78
+ messageDiv.innerHTML = '<strong>You:</strong> ' + content;
79
+ } else if (role === 'assistant') {
80
+ messageDiv.classList.add('assistant');
81
+ messageDiv.innerHTML = '<strong>Assistant:</strong> ' + content;
82
+ }
83
+ chatContainer.appendChild(messageDiv);
84
+ chatContainer.scrollTop = chatContainer.scrollHeight;
85
+ }
86
+
87
+ // Handle form submission
88
+ inputForm.addEventListener('submit', async (e) => {
89
+ e.preventDefault();
90
+ const message = userInput.value.trim();
91
+ if (message === '') return;
92
+
93
+ appendMessage('user', message);
94
+ userInput.value = '';
95
+
96
+ try {
97
+ const response = await fetch('/chat', {
98
+ method: 'POST',
99
+ headers: {
100
+ 'Content-Type': 'application/json'
101
+ },
102
+ body: JSON.stringify({
103
+ messages: [
104
+ {
105
+ role: 'user',
106
+ content: message
107
+ }
108
+ ]
109
+ })
110
+ });
111
+
112
+ if (!response.ok) {
113
+ const errorData = await response.json();
114
+ appendMessage('assistant', 'Error: ' + (errorData.error || 'Unknown error'));
115
+ return;
116
+ }
117
+
118
+ const data = await response.json();
119
+ appendMessage('assistant', data.response);
120
+ } catch (error) {
121
+ appendMessage('assistant', 'Error: ' + error.message);
122
+ }
123
+ });
124
+ </script>
125
+ </body>
126
+ </html>
127
+ """
128
+ return render_template_string(html_content)
129
+
130
+ # Chat API Endpoint
131
+ @app.route('/chat', methods=['POST'])
132
+ def chat():
133
+ try:
134
+ # Parse and validate the JSON request using Pydantic
135
+ json_data = request.get_json()
136
+ if not json_data:
137
+ logger.warning("Invalid JSON payload received.")
138
+ return jsonify({'error': 'Invalid JSON payload'}), 400
139
+
140
+ chat_request = ChatRequest(**json_data)
141
+ logger.info(f"Received messages: {chat_request.messages}")
142
+
143
+ # Convert Pydantic models to the format expected by Llama
144
+ messages = [message.dict() for message in chat_request.messages]
145
+
146
+ # Generate the chat completion
147
+ completion = llm.create_chat_completion(messages=messages)
148
+ logger.info(f"Generated completion: {completion}")
149
+
150
+ # Create the response using Pydantic
151
+ chat_response = ChatResponse(response=completion)
152
+
153
+ return jsonify(chat_response.dict())
154
+
155
+ except ValidationError as ve:
156
+ # Handle validation errors from Pydantic
157
+ logger.error(f"Pydantic validation error: {ve.errors()}")
158
+ errors = [{"field": error['loc'][0], "message": error['msg']} for error in ve.errors()]
159
+ return jsonify({'error': errors}), 422
160
+ except Exception as e:
161
+ # Handle unexpected errors
162
+ logger.error(f"Unexpected error: {str(e)}")
163
+ return jsonify({'error': str(e)}), 500
164
+
165
+ if __name__ == '__main__':
166
+ app.run(host='0.0.0.0', port=7860, debug=True)