File size: 4,404 Bytes
676c241 31b076e 676c241 a1f7a6b 676c241 a1f7a6b 676c241 |
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 147 |
# app.py
import os
import math
import requests
from flask import Flask, request, jsonify
from flask_cors import CORS
from langdetect import detect
# -----------------------------------------------------------------------------
# Configuration
# -----------------------------------------------------------------------------
HF_API_URL = "https://api-inference.huggingface.co/models/YOUR_USERNAME/YOUR_MODEL"
HF_TOKEN = os.getenv("HF_TOKEN")
HEADERS = {
"Authorization": f"Bearer {HF_TOKEN}",
"Content-Type": "application/json"
}
app = Flask(__name__)
CORS(app)
# -----------------------------------------------------------------------------
# Utility Functions
# -----------------------------------------------------------------------------
def entropy(probs):
"""Shannon entropy as epistemic uncertainty indicator."""
return -sum(p * math.log2(p) for p in probs if p > 0)
def normalize_labels(hf_output):
"""
Normalize Hugging Face output into a stable schema.
Expected HF format:
[
{"label": "HUMAN", "score": 0.73},
{"label": "AI", "score": 0.27}
]
"""
result = {item["label"].lower(): float(item["score"]) for item in hf_output}
human_p = result.get("human", 0.0)
ai_p = result.get("ai", 0.0)
return human_p, ai_p
def hf_inference(text):
payload = {"inputs": text}
r = requests.post(HF_API_URL, headers=HEADERS, json=payload, timeout=30)
r.raise_for_status()
return r.json()
# -----------------------------------------------------------------------------
# Core Endpoint
# -----------------------------------------------------------------------------
@app.route("/analyze", methods=["POST"])
def analyze():
data = request.get_json()
text = data.get("text", "").strip()
if not text:
return jsonify({"error": "Empty input"}), 400
# 1. Language detection (supports linguistic auditing)
try:
language = detect(text)
except Exception:
language = "unknown"
# 2. Hugging Face inference
hf_raw = hf_inference(text)
if not isinstance(hf_raw, list):
return jsonify({"error": "Unexpected model response", "raw": hf_raw}), 500
human_p, ai_p = normalize_labels(hf_raw)
# 3. Decision
label = "Human" if human_p >= ai_p else "Machine"
confidence = max(human_p, ai_p)
# 4. Epistemic uncertainty
H = entropy([human_p, ai_p])
# 5. Explainability placeholder (XAI-ready schema)
explainability_stub = {
"method": "pending",
"note": (
"This model endpoint does not natively expose SHAP/LIME. "
"Post-hoc explainability must be computed locally using a "
"replicated model or proxy explainer."
),
"token_attributions": []
}
# 6. Fairness metadata (for downstream auditing)
fairness_context = {
"language": language,
"human_probability": human_p,
"ai_probability": ai_p,
"entropy": H
}
response = {
"prediction": {
"label": label,
"confidence": round(confidence, 4)
},
"probabilities": {
"human": round(human_p, 4),
"machine": round(ai_p, 4)
},
"uncertainty": {
"entropy": round(H, 4),
"interpretation": (
"High entropy indicates epistemic ambiguity; "
"classification should be treated cautiously."
)
},
"linguistic_context": {
"detected_language": language
},
"explainability": explainability_stub,
"fairness_audit_fields": fairness_context
}
return jsonify(response)
# -----------------------------------------------------------------------------
# Health Check
# -----------------------------------------------------------------------------
@app.route("/", methods=["GET"])
def index():
return jsonify({
"system": "HATA API",
"capabilities": [
"Human vs AI classification",
"Probability calibration",
"Uncertainty estimation",
"Language-aware auditing",
"Explainability-ready schema",
"Fairness instrumentation"
]
})
# -----------------------------------------------------------------------------
if __name__ == "__main__":
app.run(host="0.0.0.0", port=5000, debug=True)
|