File size: 3,898 Bytes
034a1e6
aa07e9d
034a1e6
 
 
1575481
034a1e6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
aa07e9d
034a1e6
 
 
1575481
 
034a1e6
 
 
 
 
 
 
 
 
8e527d0
034a1e6
 
 
 
 
8e527d0
034a1e6
8e527d0
034a1e6
 
 
 
3b0ec68
034a1e6
3b0ec68
 
 
 
034a1e6
 
3b0ec68
 
034a1e6
3b0ec68
 
 
 
 
034a1e6
3b0ec68
 
 
 
 
 
59a476c
034a1e6
 
aa07e9d
034a1e6
 
 
 
3b0ec68
034a1e6
 
 
 
 
 
 
34e60a5
 
 
8e527d0
34e60a5
034a1e6
 
1575481
034a1e6
aa07e9d
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
import os
from fastapi import FastAPI, HTTPException
from huggingface_hub import InferenceClient
from rdflib import Graph
from pydantic import BaseModel

# Configurazione API Hugging Face
API_KEY = os.getenv("HF_API_KEY")
client = InferenceClient(api_key=API_KEY)

# File RDF
RDF_FILE = "Progetto.rdf"

# Carica il file RDF
def load_rdf():
    if os.path.exists(RDF_FILE):
        with open(RDF_FILE, "r") as f:
            return f.read()
    return ""

rdf_context = load_rdf()

# Valida le query SPARQL
def validate_sparql_query(query, rdf_data):
    try:
        g = Graph()
        g.parse(data=rdf_data, format="xml")
        g.query(query)
        return True
    except Exception:
        return False

# FastAPI app
app = FastAPI()

# Modello di input per richieste POST
class QueryRequest(BaseModel):
    message: str
    max_tokens: int = 512
    temperature: float = 0.7

# Messaggio di sistema con RDF incluso
def create_system_message(rdf_context):
    return f"""
Sei un assistente specializzato nella generazione e spiegazione di query SPARQL basate su dati RDF.
La base di conoscenza RDF è la seguente:
{rdf_context}
Il tuo compito principale è:
1. Analizzare lo schema RDF o i dati RDF forniti e la domanda in linguaggio naturale posta dall'utente.
2. Generare una query SPARQL valida che recuperi le informazioni richieste dai dati RDF.
3. Spiegare in modo prolisso e naturale il significato dei risultati, come farebbe una guida in un museo.
Regole:
- Genera solo query SPARQL in una singola riga, senza formattazioni aggiuntive.
- Se la domanda non può essere soddisfatta con una query SPARQL, rispondi con: \"Non posso generare una query per questa domanda.\"
"""

# Funzione per inviare la richiesta al modello Hugging Face
async def generate_response(message, max_tokens, temperature):
    system_message = create_system_message(rdf_context)
    messages = [
        {"role": "system", "content": system_message},
        {"role": "user", "content": message}
    ]

    try:
        # Usa il metodo chat.completions.create per lo streaming dei risultati
        stream = client.chat.completions.create(
            model="Qwen/Qwen2.5-72B-Instruct",
            messages=messages,
            temperature=temperature,
            max_tokens=max_tokens,
            top_p=0.7,
            stream=True
        )

        response = ""
        for chunk in stream:
            if "choices" in chunk and len(chunk["choices"]) > 0:
                response += chunk["choices"][0]["delta"]["content"]

        return response.strip()
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"Errore nell'elaborazione: {str(e)}")

# Endpoint per generare query SPARQL
@app.post("/generate-query/")
async def generate_query(request: QueryRequest):
    # Genera risposta
    response = await generate_response(request.message, request.max_tokens, request.temperature)

    # Valida la query se possibile
    if response.startswith("SELECT") or response.startswith("ASK"):
        is_valid = validate_sparql_query(response, rdf_context)
        if not is_valid:
            raise HTTPException(status_code=400, detail="La query generata non è valida rispetto al file RDF fornito.")

    # Correzione f-string: usiamo `.replace()` in modo sicuro
    explanation = f"La query generata è: {response.replace('\\n', ' ').strip()}. "
    explanation += "Questa query è stata progettata per estrarre informazioni specifiche dai dati RDF, consentendo di rispondere alla tua domanda. Risultati ottenuti da questa query possono includere dettagli come entità, relazioni o attributi collegati al contesto fornito."

    return {"query": response.replace("\\n", " ").strip(), "explanation": explanation}

# Endpoint per verificare se il server è attivo
@app.get("/")
async def root():
    return {"message": "Il server è attivo e pronto a generare query SPARQL!"}