File size: 4,004 Bytes
459e957
d983211
459e957
 
 
 
 
 
 
 
 
 
 
 
 
 
d983211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459e957
d983211
459e957
 
d983211
 
459e957
d983211
459e957
d983211
 
459e957
d983211
459e957
 
 
 
 
 
 
d983211
459e957
 
 
 
d983211
459e957
 
 
d983211
 
 
459e957
d983211
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459e957
 
 
 
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
import gradio as gr
import sqlite3
import secrets
import string
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer

# --- CONFIGURATION DU MODÈLE ---
MODEL_ID = "Finisha-F-scratch/Charlotte-amity"
tokenizer = AutoTokenizer.from_pretrained(MODEL_ID)
model = AutoModelForCausalLM.from_pretrained(
    MODEL_ID, 
    torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32,
    device_map="auto"
)

# --- GESTION DE LA BASE DE DONNÉES (SQLITE) ---
DB_NAME = "charlotte_api.db"

def init_db():
    conn = sqlite3.connect(DB_NAME)
    c = conn.cursor()
    # Table pour stocker les clés et le nombre de requêtes
    c.execute('''CREATE TABLE IF NOT EXISTS api_keys 
                 (key TEXT PRIMARY KEY, requests_count INTEGER)''')
    conn.commit()
    conn.close()

init_db()

def create_key():
    """Génère une clé tn-xxxx0000 et l'enregistre"""
    letters = ''.join(secrets.choice(string.ascii_lowercase) for _ in range(4))
    digits = ''.join(secrets.choice(string.digits) for _ in range(4))
    new_key = f"tn-{letters}{digits}"
    
    conn = sqlite3.connect(DB_NAME)
    c = conn.cursor()
    try:
        c.execute("INSERT INTO api_keys (key, requests_count) VALUES (?, ?)", (new_key, 0))
        conn.commit()
        return new_key
    except:
        return "Erreur lors de la génération. Réessayez."
    finally:
        conn.close()

def validate_and_log(key):
    """Vérifie la clé et incrémente le compteur"""
    conn = sqlite3.connect(DB_NAME)
    c = conn.cursor()
    c.execute("SELECT requests_count FROM api_keys WHERE key=?", (key,))
    result = c.fetchone()
    if result is not None:
        c.execute("UPDATE api_keys SET requests_count = requests_count + 1 WHERE key=?", (key,))
        conn.commit()
        conn.close()
        return True
    conn.close()
    return False

# --- FONCTION D'INFÉRENCE (L'API) ---
def charlotte_api(api_key, message):
    """
    Point d'entrée principal pour les appels externes.
    """
    if not validate_and_log(api_key):
        return "❌ Erreur : Clé API 'tn-' invalide ou non trouvée."

    # Limitation stricte au contexte de 128 tokens
    inputs = tokenizer(message, return_tensors="pt", truncation=True, max_length=128).to(model.device)
    
    with torch.no_grad():
        outputs = model.generate(
            **inputs,
            max_new_tokens=100,
            do_sample=True,
            temperature=0.8,
            pad_token_id=tokenizer.eos_token_id
        )
    
    full_text = tokenizer.decode(outputs[0], skip_special_tokens=True)
    # On renvoie uniquement la réponse générée
    response = full_text[len(message):].strip()
    return response

# --- INTERFACE GRADIO ---
with gr.Blocks(theme=gr.themes.Monochrome()) as demo:
    gr.Markdown("# 🌸 Charlotte-Amity : Système API Personnel")
    
    with gr.Tab("🔑 Gérer mes clés"):
        gr.Markdown("Cliquez ci-dessous pour générer une clé d'accès unique.")
        key_output = gr.Textbox(label="Votre nouvelle clé API", interactive=False)
        generate_btn = gr.Button("Générer ma clé tn-")
        generate_btn.click(create_key, outputs=key_output)
        gr.Info("Note: Gardez précieusement votre clé pour vos appels externes.")

    with gr.Tab("💬 Test Rapide"):
        api_input = gr.Textbox(label="Clé API (tn-...)")
        msg_input = gr.Textbox(label="Votre message")
        text_output = gr.Textbox(label="Réponse de Charlotte")
        run_btn = gr.Button("Envoyer")
        run_btn.click(charlotte_api, inputs=[api_input, msg_input], outputs=text_output)

    # L'EXPOSITION DE L'API POUR L'EXTÉRIEUR
    # Cette ligne permet d'appeler la fonction via l'URL du Space
    api_interface = gr.Interface(
        fn=charlotte_api,
        inputs=[gr.Textbox(label="api_key"), gr.Textbox(label="message")],
        outputs="text",
        api_name="chat" # C'est le nom à utiliser dans le client Python
    )

if __name__ == "__main__":
    demo.launch()