# --- PYTHON 3.13 COMPATIBILITY MONKEY-PATCH --- import sys import types if 'audioop' not in sys.modules: mock_audioop = types.ModuleType('audioop') mock_audioop.error = Exception mock_audioop.getsample = lambda data, width, index: 0 sys.modules['audioop'] = mock_audioop # ---------------------------------------------- import os import sqlite3 import json import requests import pandas as pd from datetime import datetime from flask import Flask, request, jsonify, render_template_string, redirect, session, url_for from groq import Groq app = Flask(__name__) app.secret_key = "strides_pharma_domain_secret_encryption_key_2026" app.config.update( SESSION_COOKIE_SECURE=True, SESSION_COOKIE_SAMESITE='None', ) DATA_DIR = "/data" if os.path.exists("/data") else "." DB_NAME = os.path.join(DATA_DIR, "strides_architecture.db") def init_db(): conn = sqlite3.connect(DB_NAME) cursor = conn.cursor() cursor.execute(''' CREATE TABLE IF NOT EXISTS project_tasks ( id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP, phase TEXT, task_name TEXT, owner TEXT, timeline TEXT, priority TEXT ) ''') cursor.execute(''' CREATE TABLE IF NOT EXISTS chat_sessions ( session_id TEXT PRIMARY KEY, user_owner TEXT, title TEXT, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ) ''') cursor.execute(''' CREATE TABLE IF NOT EXISTS chat_history ( id INTEGER PRIMARY KEY AUTOINCREMENT, session_id TEXT, role TEXT, content TEXT, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP ) ''') cursor.execute("SELECT COUNT(*) FROM project_tasks") if cursor.fetchone()[0] == 0: cursor.executemany('INSERT INTO project_tasks (phase, task_name, owner, timeline, priority) VALUES (?,?,?,?,?)', [ ('BRD-Scope', 'Automated Audit Trail Log Consolidation', 'A. Sharma', 'Q3-2026', 'Critical'), ('GxP-Compliance', '21 CFR Part 11 Electronic Signature Verification', 'R. Verma', 'Q3-2026', 'Critical') ]) conn.commit() conn.close() init_db() USER_CREDENTIALS = {"admin": "strides", "compliance_tester": "AuditPass123"} GROQ_MODELS = ["llama-3.1-8b-instant", "llama-3.1-70b-versatile"] OPENROUTER_MODELS = ["nvidia/nemotron-3-ultra-550b-a55b:free"] def get_current_user(): return session.get("username") @app.route("/login", methods=["POST"]) def login(): username = request.form.get("username") password = request.form.get("password") if USER_CREDENTIALS.get(username) == password: session["username"] = username return redirect(url_for("index")) return render_template_string(HTML_TEMPLATE, error="Invalid credentials profile verification fail.", show_login=True) @app.route("/logout") def logout(): session.clear() return redirect(url_for("index")) @app.route("/api/sessions", methods=["GET"]) def api_get_sessions(): user = get_current_user() if not user: return jsonify({"error": "Unauthorized"}), 401 conn = sqlite3.connect(DB_NAME) cursor = conn.cursor() cursor.execute("SELECT session_id, title FROM chat_sessions WHERE user_owner = ? ORDER BY updated_at DESC", (user,)) rows = cursor.fetchall() conn.close() if not rows: sid = f"session_{user}_initial" conn = sqlite3.connect(DB_NAME) c = conn.cursor() c.execute("INSERT OR IGNORE INTO chat_sessions (session_id, user_owner, title) VALUES (?,?,?)", (sid, user, "Initial Session Thread")) conn.commit() conn.close() rows = [(sid, "Initial Session Thread")] return jsonify([{"id": r[0], "title": r[1]} for r in rows]) @app.route("/api/sessions/new", methods=["POST"]) def api_new_session(): user = get_current_user() if not user: return jsonify({"error": "Unauthorized"}), 401 new_id = f"session_{user}_{int(datetime.now().timestamp())}" conn = sqlite3.connect(DB_NAME) cursor = conn.cursor() cursor.execute("INSERT INTO chat_sessions (session_id, user_owner, title) VALUES (?, ?, ?)", (new_id, user, "New Chat Session")) conn.commit() conn.close() return jsonify({"status": "success", "id": new_id}) @app.route("/api/history/", methods=["GET"]) def api_get_history(session_id): if not get_current_user(): return jsonify({"error": "Unauthorized"}), 401 conn = sqlite3.connect(DB_NAME) cursor = conn.cursor() cursor.execute("SELECT role, content FROM chat_history WHERE session_id = ? ORDER BY timestamp ASC", (session_id,)) rows = cursor.fetchall() conn.close() return jsonify([{"role": r[0], "content": r[1]} for r in rows]) @app.route("/api/chat", methods=["POST"]) def api_chat(): user = get_current_user() if not user: return jsonify({"error": "Unauthorized"}), 401 data = request.json or {} sid = data.get("session_id") msg = data.get("message", "").strip() provider = data.get("provider") api_key = data.get("api_key") model = data.get("model") if not msg or not api_key: return jsonify({"error": "Missing message or API key"}), 400 conn = sqlite3.connect(DB_NAME) cursor = conn.cursor() cursor.execute("INSERT INTO chat_history (session_id, role, content) VALUES (?, 'user', ?)", (sid, msg)) cursor.execute("SELECT COUNT(*) FROM chat_history WHERE session_id = ?", (sid,)) if cursor.fetchone()[0] <= 2: cursor.execute("UPDATE chat_sessions SET title = ? WHERE session_id = ?", (msg[:25] + "...", sid)) conn.commit() cursor.execute("SELECT role, content FROM chat_history WHERE session_id = ? ORDER BY timestamp ASC", (sid,)) history = [{"role": r[0], "content": r[1]} for r in cursor.fetchall()] conn.close() sys_prompt = "You are a Pharma Business Analyst for Strides. Output specifications and save entries if data schema formats matches." messages = [{"role": "system", "content": sys_prompt}] + history try: if provider == "Groq": client = Groq(api_key=api_key) resp = client.chat.completions.create(model=model, messages=messages, temperature=0.0) ai_out = resp.choices[0].message.content.strip() else: headers = {"Authorization": f"Bearer {api_key}", "Content-Type": "application/json"} payload = {"model": model, "messages": messages, "temperature": 0.0} r = requests.post("https://openrouter.ai/api/v1/chat/completions", headers=headers, json=payload) ai_out = r.json()['choices'][0]['message']['content'].strip() if "||JSON_DATA:" in ai_out: try: payload_str = ai_out.split("||JSON_DATA:")[1].split("||")[0].strip() p = json.loads(payload_str) conn = sqlite3.connect(DB_NAME) conn.cursor().execute("INSERT INTO project_tasks (phase, task_name, owner, timeline, priority) VALUES (?,?,?,?,?)", (p.get('phase'), p.get('task_name'), p.get('owner'), p.get('timeline'), p.get('priority'))) conn.commit() conn.close() ai_out += "\n\nāš™ļø [SYSTEM LOGGED SUCCESS]" except: pass conn = sqlite3.connect(DB_NAME) conn.cursor().execute("INSERT INTO chat_history (session_id, role, content) VALUES (?, 'assistant', ?)", (sid, ai_out)) conn.commit() conn.close() return jsonify({"reply": ai_out}) except Exception as e: return jsonify({"reply": f"āŒ Gateway Execution Error: {str(e)}"}) @app.route("/api/query", methods=["POST"]) def api_query(): if not get_current_user(): return jsonify({"error": "Unauthorized"}), 401 data = request.json or {} q = data.get("query", "") api_key = data.get("api_key") provider = data.get("provider") model = data.get("model") sys_prompt = "You are a SQLite assistant. Return ONLY a valid executable raw SQLite query targeting table 'project_tasks'." try: if provider == "Groq": client = Groq(api_key=api_key) resp = client.chat.completions.create(model=model, messages=[{"role":"system","content":sys_prompt},{"role":"user","content":q}], temperature=0.0) sql = resp.choices[0].message.content.strip() else: r = requests.post("https://openrouter.ai/api/v1/chat/completions", headers={"Authorization": f"Bearer {api_key}"}, json={"model": model, "messages": [{"role":"system","content":sys_prompt},{"role":"user","content":q}]}) sql = r.json()['choices'][0]['message']['content'].strip() sql = sql.replace("```sql", "").replace("```", "").replace("`", "").strip() conn = sqlite3.connect(DB_NAME) box_df = pd.read_sql_query(sql, conn) conn.close() return jsonify({"sql": sql, "data": box_df.to_dict(orient="records")}) except Exception as e: return jsonify({"error": str(e)}) HTML_TEMPLATE = """ Strides Pharma AI {% if show_login %}

šŸ’Š Strides Security Gate

{% if error %}
{{ error }}
{% endif %}
{% else %}
šŸ•’ Session Explorer

šŸ”‘ Gateway Options
Logged in as: {{ username }} Log Out
  • šŸ¤– Requirement Chat Workspace
  • šŸ”Ž Inventory SQL Explorer
{% endif %} """ @app.route("/") def index(): user = get_current_user() if not user: return render_template_string(HTML_TEMPLATE, show_login=True) return render_template_string(HTML_TEMPLATE, show_login=False, username=user) # Ensure the bottom of app.py looks exactly like this: if __name__ == "__main__": app.run(host="0.0.0.0", port=7860)