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 riscrittura 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. Se l'utente fornisce una query SPARQL con una richiesta di spiegazione o correzione, riscrivila per renderla più efficiente o corretta. Regole: - Non generare nulla al di fuori di una query SPARQL, a meno che non sia esplicitamente richiesto. - 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 def generate_response(message, max_tokens, temperature): system_message = create_system_message(rdf_context) full_prompt = f"{system_message}\nUtente: {message}\nAssistente:" try: # Usa il metodo corretto per invocare il modello Hugging Face response = client.post( model="Qwen/Qwen2.5-72B-Instruct", inputs=full_prompt, parameters={ "max_new_tokens": max_tokens, "temperature": temperature } ) return response.get("generated_text", "").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 = 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.") return {"query": response} # Endpoint per verificare se il server è attivo @app.get("/") async def root(): return {"message": "Il server è attivo e pronto a generare query SPARQL!"}