|
from flask import Flask, request, jsonify, render_template_string |
|
from detoxify import Detoxify |
|
import os |
|
import torch |
|
from transformers import AutoModelForSequenceClassification, AutoTokenizer |
|
|
|
app = Flask(__name__) |
|
|
|
|
|
detoxify_model = Detoxify('multilingual') |
|
koala_model = AutoModelForSequenceClassification.from_pretrained("KoalaAI/Text-Moderation") |
|
koala_tokenizer = AutoTokenizer.from_pretrained("KoalaAI/Text-Moderation") |
|
|
|
|
|
API_KEY = os.getenv('API_KEY') |
|
|
|
|
|
HTML_TEMPLATE = ''' |
|
<!DOCTYPE html> |
|
<html lang="en"> |
|
<head> |
|
<meta charset="UTF-8"> |
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"> |
|
<title>Modern Detoxify & Moderation API Test</title> |
|
<script src="https://cdn.tailwindcss.com"></script> |
|
</head> |
|
<body class="bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100"> |
|
<div class="container mx-auto px-4 py-8"> |
|
<h1 class="text-4xl font-bold mb-6 text-center">Modern Detoxify & Moderation API Test</h1> |
|
<form id="testForm" class="bg-white dark:bg-gray-800 shadow-md rounded px-8 pt-6 pb-8 mb-4"> |
|
<div class="mb-4"> |
|
<label class="block text-gray-700 dark:text-gray-300 text-sm font-bold mb-2" for="api_key">API Key:</label> |
|
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 dark:text-gray-900 leading-tight focus:outline-none focus:shadow-outline" type="text" id="api_key" name="api_key" required> |
|
</div> |
|
<div class="mb-4"> |
|
<label class="block text-gray-700 dark:text-gray-300 text-sm font-bold mb-2" for="model">Select Model:</label> |
|
<select class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 dark:text-gray-900 leading-tight focus:outline-none focus:shadow-outline" id="model" name="model"> |
|
<option value="unitaryai/detoxify-multilingual" selected>unitaryai/detoxify-multilingual</option> |
|
<option value="koalaai/text-moderation">koalaai/text-moderation</option> |
|
</select> |
|
</div> |
|
<div class="mb-4"> |
|
<label class="block text-gray-700 dark:text-gray-300 text-sm font-bold mb-2" for="text">Text to Analyze:</label> |
|
<input class="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 dark:text-gray-900 leading-tight focus:outline-none focus:shadow-outline" type="text" id="text" name="text" required> |
|
</div> |
|
<div class="flex items-center justify-between"> |
|
<button class="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline" type="submit">Analyze</button> |
|
</div> |
|
</form> |
|
<div id="results" class="mt-6"></div> |
|
</div> |
|
<script> |
|
document.getElementById('testForm').addEventListener('submit', async function(event) { |
|
event.preventDefault(); |
|
const apiKey = document.getElementById('api_key').value; |
|
const model = document.getElementById('model').value; |
|
const text = document.getElementById('text').value; |
|
try { |
|
const response = await fetch('/v1/moderations', { |
|
method: 'POST', |
|
headers: { 'Content-Type': 'application/json' }, |
|
body: JSON.stringify({ api_key: apiKey, model: model, texts: [text] }) |
|
}); |
|
const data = await response.json(); |
|
const resultsDiv = document.getElementById('results'); |
|
if (data.error) { |
|
resultsDiv.innerHTML = `<p class="text-red-500 font-bold">Error: ${data.error}</p>`; |
|
} else { |
|
let html = '<h2 class="text-2xl font-bold mb-4">Results:</h2>'; |
|
data.results.forEach(item => { |
|
html += `<div class="mb-4 p-4 bg-gray-200 dark:bg-gray-700 rounded"> |
|
<p class="font-semibold">Input: ${item.input}</p> |
|
<ul>`; |
|
for (const [key, value] of Object.entries(item.predictions)) { |
|
html += `<li>${key}: ${value.toFixed(5)}</li>`; |
|
} |
|
html += ` </ul> |
|
</div>`; |
|
}); |
|
resultsDiv.innerHTML = html; |
|
} |
|
} catch (error) { |
|
console.error('Error:', error); |
|
} |
|
}); |
|
</script> |
|
</body> |
|
</html> |
|
''' |
|
|
|
|
|
@app.route('/v1/moderations', methods=['POST']) |
|
def moderations(): |
|
data = request.get_json() |
|
api_key = data.get('api_key') |
|
texts = data.get('texts') |
|
model_choice = data.get('model', 'unitaryai/detoxify-multilingual') |
|
|
|
if api_key != API_KEY: |
|
return jsonify({"error": "Geçersiz API anahtarı"}), 401 |
|
|
|
if not texts or not isinstance(texts, list): |
|
return jsonify({"error": "Geçersiz giriş, metin listesi bekleniyor"}), 400 |
|
|
|
results = [] |
|
if model_choice == "koalaai/text-moderation": |
|
for text in texts: |
|
inputs = koala_tokenizer(text, return_tensors="pt") |
|
outputs = koala_model(**inputs) |
|
logits = outputs.logits |
|
probabilities = torch.softmax(logits, dim=-1).squeeze().tolist() |
|
|
|
if isinstance(probabilities, float): |
|
probabilities = [probabilities] |
|
labels = [koala_model.config.id2label[idx] for idx in range(len(probabilities))] |
|
prediction = {label: prob for label, prob in zip(labels, probabilities)} |
|
results.append({"input": text, "predictions": prediction}) |
|
response_model = "koalaai/text-moderation" |
|
else: |
|
for text in texts: |
|
pred = detoxify_model.predict([text]) |
|
|
|
prediction = {k: v[0] for k, v in pred.items()} |
|
results.append({"input": text, "predictions": prediction}) |
|
response_model = "unitaryai/detoxify-multilingual" |
|
|
|
response_data = { |
|
"object": "moderation", |
|
"model": response_model, |
|
"results": results |
|
} |
|
return jsonify(response_data) |
|
|
|
@app.route('/') |
|
def home(): |
|
return render_template_string(HTML_TEMPLATE) |
|
|
|
if __name__ == '__main__': |
|
port = int(os.getenv('PORT', 7860)) |
|
app.run(host='0.0.0.0', port=port, debug=True) |
|
|