|
|
|
""" |
|
Hugging Face Gradio App for RDF Validation with MCP Server and Anthropic AI |
|
|
|
This app serves both as a web interface and can expose MCP server functionality. |
|
Deploy this on Hugging Face Spaces with your Anthropic API key. |
|
""" |
|
|
|
import gradio as gr |
|
import os |
|
import json |
|
import sys |
|
import asyncio |
|
import logging |
|
import requests |
|
from typing import Any, Dict, List, Optional |
|
import threading |
|
import time |
|
|
|
|
|
print("π§ FORCING ENVIRONMENT VARIABLE OVERRIDES...") |
|
|
|
|
|
problematic_env_vars = [ |
|
'HF_API_URL', |
|
'HF_INFERENCE_URL', |
|
'HF_ENDPOINT_URL', |
|
'HF_MODEL', |
|
'HUGGINGFACE_API_URL', |
|
'HUGGINGFACE_INFERENCE_URL' |
|
] |
|
|
|
for var in problematic_env_vars: |
|
if var in os.environ: |
|
old_value = os.environ[var] |
|
del os.environ[var] |
|
print(f"ποΈ Removed environment variable: {var} = {old_value}") |
|
|
|
print("β
Environment variables cleaned") |
|
|
|
|
|
sys.path.append(os.path.dirname(os.path.abspath(__file__))) |
|
|
|
|
|
try: |
|
from validator import validate_rdf |
|
VALIDATOR_AVAILABLE = True |
|
except ImportError: |
|
VALIDATOR_AVAILABLE = False |
|
print("β οΈ Warning: validator.py not found. Some features may be limited.") |
|
|
|
|
|
try: |
|
from openai import OpenAI |
|
OPENAI_AVAILABLE = True |
|
except ImportError: |
|
OPENAI_AVAILABLE = False |
|
print("π‘ Install 'openai' package for AI-powered corrections: pip install openai") |
|
|
|
try: |
|
import requests |
|
HF_INFERENCE_AVAILABLE = True |
|
except ImportError: |
|
HF_INFERENCE_AVAILABLE = False |
|
print("π‘ Install 'requests' package for AI-powered corrections: pip install requests") |
|
|
|
|
|
logging.basicConfig(level=logging.INFO) |
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
HF_API_KEY = os.getenv('HF_API_KEY', '') |
|
|
|
HF_ENDPOINT_URL = "https://evxgv66ksxjlfrts.us-east-1.aws.endpoints.huggingface.cloud/v1/" |
|
HF_MODEL = "lmstudio-community/Llama-3.3-70B-Instruct-GGUF" |
|
|
|
print(f"π FORCED hardcoded endpoint: {HF_ENDPOINT_URL}") |
|
print(f"π FORCED hardcoded model: {HF_MODEL}") |
|
print(f"π HF_API_KEY configured: {'Yes' if HF_API_KEY else 'No'}") |
|
|
|
|
|
import sys |
|
if 'requests' in sys.modules: |
|
print("π Requests module detected - ensuring no cached env vars") |
|
if 'httpx' in sys.modules: |
|
print("π HTTPX module detected - ensuring no cached env vars") |
|
|
|
|
|
def get_openai_client(): |
|
"""Get configured OpenAI client for HF Inference Endpoint""" |
|
if not HF_API_KEY: |
|
print("β No HF_API_KEY available for OpenAI client") |
|
return None |
|
|
|
print(f"π Creating OpenAI client with:") |
|
print(f" base_url: {HF_ENDPOINT_URL}") |
|
print(f" api_key: {'***' + HF_API_KEY[-4:] if len(HF_API_KEY) > 4 else 'HIDDEN'}") |
|
|
|
return OpenAI( |
|
base_url=HF_ENDPOINT_URL, |
|
api_key=HF_API_KEY, |
|
timeout=120.0 |
|
) |
|
|
|
|
|
SAMPLE_VALID_RDF = '''<?xml version="1.0" encoding="UTF-8"?> |
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
|
xmlns:bf="http://id.loc.gov/ontologies/bibframe/" |
|
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"> |
|
|
|
<bf:Work rdf:about="http://example.org/work/1"> |
|
<rdf:type rdf:resource="http://id.loc.gov/ontologies/bibframe/Text"/> |
|
<bf:title> |
|
<bf:Title> |
|
<bf:mainTitle>Sample Monograph Title</bf:mainTitle> |
|
</bf:Title> |
|
</bf:title> |
|
<bf:creator> |
|
<bf:Agent> |
|
<rdfs:label>Sample Author</rdfs:label> |
|
</bf:Agent> |
|
</bf:creator> |
|
</bf:Work> |
|
|
|
</rdf:RDF>''' |
|
|
|
SAMPLE_INVALID_RDF = '''<?xml version="1.0" encoding="UTF-8"?> |
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> |
|
<!-- Missing namespace declarations --> |
|
<!-- Missing required properties --> |
|
<bf:Work rdf:about="http://example.org/work/1"> |
|
<bf:title>Incomplete Title</bf:title> |
|
<!-- Missing rdf:type --> |
|
<!-- Missing proper title structure --> |
|
</bf:Work> |
|
</rdf:RDF>''' |
|
|
|
|
|
def validate_rdf_tool(rdf_content: str, template: str = "monograph") -> dict: |
|
""" |
|
Validate RDF/XML content against SHACL templates. |
|
|
|
This tool validates RDF/XML data against predefined SHACL shapes to ensure |
|
compliance with metadata standards like BIBFRAME. Returns detailed validation |
|
results with conformance status and specific violation information. |
|
|
|
Args: |
|
rdf_content (str): The RDF/XML content to validate |
|
template (str): Validation template to use ('monograph' or 'custom') |
|
|
|
Returns: |
|
dict: Validation results with conformance status and detailed feedback |
|
""" |
|
if not rdf_content: |
|
return {"error": "No RDF/XML content provided", "conforms": False} |
|
|
|
if not VALIDATOR_AVAILABLE: |
|
return { |
|
"error": "Validator not available - ensure validator.py is present", |
|
"conforms": False |
|
} |
|
|
|
try: |
|
conforms, results_text = validate_rdf(rdf_content.encode('utf-8'), template) |
|
|
|
return { |
|
"conforms": conforms, |
|
"results": results_text, |
|
"template": template, |
|
"status": "β
Valid RDF" if conforms else "β Invalid RDF" |
|
} |
|
|
|
except Exception as e: |
|
logger.error(f"Validation error: {str(e)}") |
|
return { |
|
"error": f"Validation failed: {str(e)}", |
|
"conforms": False |
|
} |
|
|
|
def get_ai_suggestions(validation_results: str, rdf_content: str) -> str: |
|
""" |
|
Generate AI-powered fix suggestions for invalid RDF/XML. |
|
|
|
This tool analyzes validation results and provides actionable suggestions |
|
for fixing RDF/XML validation errors using AI or rule-based analysis. |
|
|
|
Args: |
|
validation_results (str): The validation error messages |
|
rdf_content (str): The original RDF/XML content that failed validation |
|
|
|
Returns: |
|
str: Detailed suggestions for fixing the RDF validation issues |
|
""" |
|
|
|
if not OPENAI_AVAILABLE: |
|
return generate_manual_suggestions(validation_results) |
|
|
|
|
|
current_api_key = os.getenv('HF_API_KEY', '') |
|
if not current_api_key: |
|
return f""" |
|
π **AI suggestions disabled**: Please set your Hugging Face API key as a Secret in your Space settings. |
|
|
|
{generate_manual_suggestions(validation_results)} |
|
""" |
|
|
|
try: |
|
|
|
print("π Attempting to get OpenAI client for suggestions...") |
|
client = get_openai_client() |
|
if not client: |
|
print("β OpenAI client is None for suggestions.") |
|
return f""" |
|
π **AI suggestions disabled**: HF_API_KEY not configured or client creation failed. |
|
|
|
{generate_manual_suggestions(validation_results)} |
|
""" |
|
print(f"β
OpenAI client obtained for suggestions. Client timeout: {client.timeout}") |
|
|
|
prompt = f"""You are an expert in RDF/XML and SHACL validation. Analyze the following validation results and provide clear, actionable suggestions for fixing the RDF issues. |
|
|
|
Validation Results: |
|
{validation_results} |
|
|
|
Original RDF (first 1000 chars): |
|
{rdf_content[:1000]}... |
|
|
|
Please provide: |
|
1. A clear summary of what's wrong |
|
2. Specific step-by-step instructions to fix each issue |
|
3. Example corrections where applicable |
|
4. Best practices to prevent similar issues |
|
|
|
Format your response in a helpful, structured way using markdown.""" |
|
|
|
|
|
print(f"π Making SUGGESTION API call to: {HF_ENDPOINT_URL} with model: {HF_MODEL}") |
|
print(f"π Client base_url: {client.base_url}") |
|
print("β³ Attempting client.chat.completions.create() for suggestions...") |
|
|
|
chat_completion = client.chat.completions.create( |
|
model=HF_MODEL, |
|
messages=[ |
|
{ |
|
"role": "user", |
|
"content": prompt |
|
} |
|
], |
|
max_tokens=1500, |
|
temperature=0.7, |
|
top_p=0.9 |
|
) |
|
|
|
print(f"β
client.chat.completions.create() returned for suggestions. Type: {type(chat_completion)}") |
|
generated_text = chat_completion.choices[0].message.content |
|
print("β
Suggestion API call successful, content extracted.") |
|
return f"π€ **AI-Powered Suggestions:**\n\n{generated_text}" |
|
|
|
except Exception as e: |
|
logger.error(f"OpenAI/HF Inference Endpoint error (suggestions): {str(e)}", exc_info=True) |
|
return f""" |
|
β **AI suggestions error**: {str(e)} |
|
|
|
{generate_manual_suggestions(validation_results)} |
|
""" |
|
|
|
def get_ai_correction(validation_results: str, rdf_content: str) -> str: |
|
""" |
|
Generate AI-powered corrected RDF/XML based on validation errors. |
|
|
|
This tool takes invalid RDF/XML and validation results, then generates |
|
a corrected version that addresses all identified validation issues. |
|
|
|
Args: |
|
validation_results (str): The validation error messages |
|
rdf_content (str): The original invalid RDF/XML content |
|
|
|
Returns: |
|
str: Corrected RDF/XML that should pass validation |
|
""" |
|
|
|
if not OPENAI_AVAILABLE: |
|
return generate_manual_correction_hints(validation_results, rdf_content) |
|
|
|
|
|
current_api_key = os.getenv('HF_API_KEY', '') |
|
if not current_api_key: |
|
return f"""<!-- AI correction disabled: Set HF_API_KEY as a Secret in your Space settings --> |
|
|
|
{generate_manual_correction_hints(validation_results, rdf_content)}""" |
|
|
|
try: |
|
|
|
print("π Attempting to get OpenAI client for correction...") |
|
client = get_openai_client() |
|
if not client: |
|
print("β OpenAI client is None for correction.") |
|
return f"""<!-- AI correction disabled: HF_API_KEY not configured or client creation failed. --> |
|
|
|
{generate_manual_correction_hints(validation_results, rdf_content)}""" |
|
print(f"β
OpenAI client obtained for correction. Client timeout: {client.timeout}") |
|
|
|
prompt = f"""You are an expert in RDF/XML. Fix the following RDF/XML based on the validation errors provided. |
|
|
|
Validation Errors: |
|
{validation_results} |
|
|
|
Original RDF/XML: |
|
{rdf_content} |
|
|
|
Please provide the corrected RDF/XML that addresses all validation issues. |
|
- Return only the corrected XML without additional explanation |
|
- Maintain the original structure as much as possible while fixing errors |
|
- Ensure all namespace declarations are present |
|
- Add any missing required properties |
|
- Fix any syntax or structural issues""" |
|
|
|
|
|
print(f"π Making CORRECTION API call to: {HF_ENDPOINT_URL} with model: {HF_MODEL}") |
|
print(f"π Client base_url: {client.base_url}") |
|
print("β³ Attempting client.chat.completions.create() for correction...") |
|
|
|
chat_completion = client.chat.completions.create( |
|
model=HF_MODEL, |
|
messages=[ |
|
{ |
|
"role": "user", |
|
"content": prompt |
|
} |
|
], |
|
max_tokens=2000, |
|
temperature=0.3, |
|
top_p=0.9 |
|
) |
|
|
|
print(f"β
client.chat.completions.create() returned for correction. Type: {type(chat_completion)}") |
|
corrected_text = chat_completion.choices[0].message.content |
|
print("β
Correction API call successful, content extracted.") |
|
return corrected_text |
|
|
|
except Exception as e: |
|
logger.error(f"OpenAI/HF Inference Endpoint error (correction): {str(e)}", exc_info=True) |
|
return f"""<!-- AI correction error: {str(e)} --> |
|
|
|
{generate_manual_correction_hints(validation_results, rdf_content)}""" |
|
|
|
def generate_manual_suggestions(validation_results: str) -> str: |
|
"""Generate rule-based suggestions when AI is not available""" |
|
suggestions = [] |
|
|
|
if "Constraint Violation" in validation_results: |
|
suggestions.append("β’ Fix SHACL constraint violations by ensuring required properties are present") |
|
|
|
if "Missing property" in validation_results or "missing" in validation_results.lower(): |
|
suggestions.append("β’ Add missing required properties (check template requirements)") |
|
|
|
if "datatype" in validation_results.lower(): |
|
suggestions.append("β’ Correct data type mismatches (ensure proper literal types)") |
|
|
|
if "namespace" in validation_results.lower() or "prefix" in validation_results.lower(): |
|
suggestions.append("β’ Add missing namespace declarations at the top of your RDF") |
|
|
|
if "XML" in validation_results or "syntax" in validation_results.lower(): |
|
suggestions.append("β’ Fix XML syntax errors (check for unclosed tags, invalid characters)") |
|
|
|
if not suggestions: |
|
suggestions.append("β’ Review detailed validation results for specific issues") |
|
suggestions.append("β’ Ensure your RDF follows the selected template requirements") |
|
|
|
suggestions_text = "\n".join(suggestions) |
|
|
|
return f""" |
|
π **Manual Analysis:** |
|
|
|
{suggestions_text} |
|
|
|
π‘ **General Tips:** |
|
β’ Check namespace declarations at the top of your RDF |
|
β’ Ensure all required properties are present |
|
β’ Verify data types match expected formats |
|
β’ Make sure XML structure is well-formed |
|
|
|
π§ **Common Fixes:** |
|
β’ Add missing namespace prefixes |
|
β’ Include required properties like rdf:type |
|
β’ Fix malformed URIs or literals |
|
β’ Ensure proper XML syntax |
|
""" |
|
|
|
def generate_manual_correction_hints(validation_results: str, rdf_content: str) -> str: |
|
"""Generate manual correction hints when AI is not available""" |
|
return f"""<!-- Manual correction hints based on validation results --> |
|
<!-- Set HF_API_KEY as a Secret in your Space settings for AI-powered corrections --> |
|
|
|
{rdf_content} |
|
|
|
<!-- |
|
VALIDATION ISSUES FOUND: |
|
{validation_results[:500]}... |
|
|
|
MANUAL CORRECTION STEPS: |
|
1. Add missing namespace declarations |
|
2. Include required properties (rdf:type, etc.) |
|
3. Fix XML syntax errors |
|
4. Ensure proper URI formats |
|
5. Validate data types |
|
-->""" |
|
|
|
def validate_rdf_interface(rdf_content: str, template: str, use_ai: bool = True): |
|
"""Main validation function for Gradio interface""" |
|
if not rdf_content.strip(): |
|
return "β Error", "No RDF/XML data provided", "", "" |
|
|
|
|
|
result = validate_rdf_tool(rdf_content, template) |
|
|
|
if "error" in result: |
|
return f"β Error: {result['error']}", "", "", "" |
|
|
|
status = result["status"] |
|
results_text = result["results"] |
|
|
|
if result["conforms"]: |
|
suggestions = "β
No issues found! Your RDF/XML is valid according to the selected template." |
|
corrected_rdf = "<!-- Already valid - no corrections needed -->\n" + rdf_content |
|
else: |
|
if use_ai: |
|
suggestions = get_ai_suggestions(results_text, rdf_content) |
|
corrected_rdf = get_ai_correction(results_text, rdf_content) |
|
else: |
|
suggestions = generate_manual_suggestions(results_text) |
|
corrected_rdf = generate_manual_correction_hints(results_text, rdf_content) |
|
|
|
return status, results_text, suggestions, corrected_rdf |
|
|
|
def get_rdf_examples(example_type: str = "valid") -> str: |
|
""" |
|
Retrieve example RDF/XML snippets for testing and learning. |
|
|
|
This tool provides sample RDF/XML content that can be used to test |
|
the validation system or learn proper RDF structure. |
|
|
|
Args: |
|
example_type (str): Type of example ('valid', 'invalid', or 'bibframe') |
|
|
|
Returns: |
|
str: RDF/XML example content |
|
""" |
|
examples = { |
|
"valid": SAMPLE_VALID_RDF, |
|
"invalid": SAMPLE_INVALID_RDF, |
|
"bibframe": '''<?xml version="1.0" encoding="UTF-8"?> |
|
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
|
xmlns:bf="http://id.loc.gov/ontologies/bibframe/" |
|
xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"> |
|
|
|
<bf:Instance rdf:about="http://example.org/instance/1"> |
|
<rdf:type rdf:resource="http://id.loc.gov/ontologies/bibframe/Print"/> |
|
<bf:instanceOf rdf:resource="http://example.org/work/1"/> |
|
<bf:title> |
|
<bf:Title> |
|
<bf:mainTitle>Example Book Title</bf:mainTitle> |
|
</bf:Title> |
|
</bf:title> |
|
<bf:provisionActivity> |
|
<bf:Publication> |
|
<bf:date>2024</bf:date> |
|
<bf:place> |
|
<bf:Place> |
|
<rdfs:label>New York</rdfs:label> |
|
</bf:Place> |
|
</bf:place> |
|
</bf:Publication> |
|
</bf:provisionActivity> |
|
</bf:Instance> |
|
|
|
</rdf:RDF>''' |
|
} |
|
|
|
return examples.get(example_type, examples["valid"]) |
|
|
|
|
|
def create_interface(): |
|
"""Create the main Gradio interface""" |
|
|
|
|
|
current_api_key = os.getenv('HF_API_KEY', '') |
|
api_status = "π AI features enabled" if (OPENAI_AVAILABLE and current_api_key) else "β οΈ AI features disabled (set HF_API_KEY)" |
|
|
|
with gr.Blocks( |
|
title="RDF Validation Server with AI", |
|
theme=gr.themes.Soft(), |
|
css=""" |
|
.status-box { |
|
font-weight: bold; |
|
padding: 10px; |
|
border-radius: 5px; |
|
} |
|
.header-text { |
|
text-align: center; |
|
padding: 20px; |
|
} |
|
""" |
|
) as demo: |
|
|
|
|
|
debug_info = f""" |
|
Debug Info: |
|
- OPENAI_AVAILABLE: {OPENAI_AVAILABLE} |
|
- HF_INFERENCE_AVAILABLE: {HF_INFERENCE_AVAILABLE} |
|
- HF_API_KEY set: {'Yes' if current_api_key else 'No'} |
|
- HF_API_KEY length: {len(current_api_key) if current_api_key else 0} |
|
- HF_ENDPOINT_URL: {HF_ENDPOINT_URL} |
|
- HF_MODEL: {HF_MODEL} |
|
""" |
|
|
|
gr.HTML(f""" |
|
<div class="header-text"> |
|
<h1>π RDF Validation Server with AI</h1> |
|
<p>Validate RDF/XML against SHACL schemas with AI-powered suggestions and corrections</p> |
|
<p><strong>Status:</strong> {api_status}</p> |
|
<details><summary>Debug Info</summary><pre>{debug_info}</pre></details> |
|
</div> |
|
""") |
|
|
|
|
|
with gr.Row(): |
|
with gr.Column(scale=1): |
|
gr.Markdown("### π Input") |
|
|
|
rdf_input = gr.Textbox( |
|
label="RDF/XML Content", |
|
placeholder="Paste your RDF/XML content here...", |
|
lines=15, |
|
show_copy_button=True |
|
) |
|
|
|
with gr.Row(): |
|
template_dropdown = gr.Dropdown( |
|
label="Validation Template", |
|
choices=["monograph", "custom"], |
|
value="monograph", |
|
info="Select the SHACL template to validate against" |
|
) |
|
|
|
use_ai_checkbox = gr.Checkbox( |
|
label="Use AI Features", |
|
value=True, |
|
info="Enable AI-powered suggestions and corrections" |
|
) |
|
|
|
validate_btn = gr.Button("π Validate RDF", variant="primary", size="lg") |
|
|
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown("### π Results") |
|
|
|
status_output = gr.Textbox( |
|
label="Validation Status", |
|
interactive=False, |
|
lines=1, |
|
elem_classes=["status-box"] |
|
) |
|
|
|
results_output = gr.Textbox( |
|
label="Detailed Validation Results", |
|
interactive=False, |
|
lines=8, |
|
show_copy_button=True |
|
) |
|
|
|
suggestions_output = gr.Textbox( |
|
label="π‘ Fix Suggestions", |
|
interactive=False, |
|
lines=8, |
|
show_copy_button=True |
|
) |
|
|
|
|
|
with gr.Row(): |
|
with gr.Column(): |
|
gr.Markdown("### π οΈ AI-Generated Corrections") |
|
|
|
corrected_output = gr.Textbox( |
|
label="Corrected RDF/XML", |
|
interactive=False, |
|
lines=15, |
|
show_copy_button=True, |
|
placeholder="Corrected RDF will appear here after validation..." |
|
) |
|
|
|
|
|
with gr.Row(): |
|
gr.Markdown("### π Examples & Tools") |
|
|
|
with gr.Row(): |
|
example1_btn = gr.Button("β
Valid RDF Example", variant="secondary") |
|
example2_btn = gr.Button("β Invalid RDF Example", variant="secondary") |
|
example3_btn = gr.Button("π BibFrame Example", variant="secondary") |
|
clear_btn = gr.Button("ποΈ Clear All", variant="stop") |
|
|
|
|
|
validate_btn.click( |
|
fn=validate_rdf_interface, |
|
inputs=[rdf_input, template_dropdown, use_ai_checkbox], |
|
outputs=[status_output, results_output, suggestions_output, corrected_output] |
|
) |
|
|
|
|
|
rdf_input.change( |
|
fn=validate_rdf_interface, |
|
inputs=[rdf_input, template_dropdown, use_ai_checkbox], |
|
outputs=[status_output, results_output, suggestions_output, corrected_output] |
|
) |
|
|
|
|
|
example1_btn.click( |
|
lambda: get_rdf_examples("valid"), |
|
outputs=[rdf_input] |
|
) |
|
|
|
example2_btn.click( |
|
lambda: get_rdf_examples("invalid"), |
|
outputs=[rdf_input] |
|
) |
|
|
|
example3_btn.click( |
|
lambda: get_rdf_examples("bibframe"), |
|
outputs=[rdf_input] |
|
) |
|
|
|
clear_btn.click( |
|
lambda: ("", "", "", "", ""), |
|
outputs=[rdf_input, status_output, results_output, suggestions_output, corrected_output] |
|
) |
|
|
|
|
|
gr.Markdown(""" |
|
--- |
|
### π **Deployment Instructions for Hugging Face Spaces:** |
|
|
|
1. **Create a new Space** on [Hugging Face](https://huggingface.co/spaces) |
|
2. **Set up your Hugging Face Inference Endpoint** and get the endpoint URL |
|
3. **Set your tokens** in Space settings (use Secrets for security): |
|
- Go to Settings β Repository secrets |
|
- Add: `HF_API_KEY` = `your_huggingface_api_key_here` |
|
- Endpoint is now hardcoded to your specific Inference Endpoint |
|
4. **Upload these files** to your Space repository |
|
5. **Install requirements**: The Space will auto-install from `requirements.txt` |
|
|
|
### π§ **MCP Server Mode:** |
|
This app functions as both a web interface AND an MCP server for Claude Desktop and other MCP clients. |
|
|
|
**Available MCP Tools (via SSE):** |
|
- `validate_rdf_tool`: Validate RDF/XML against SHACL shapes |
|
- `get_ai_suggestions`: Get AI-powered fix suggestions |
|
- `get_ai_correction`: Generate corrected RDF/XML |
|
- `get_rdf_examples`: Retrieve example RDF snippets |
|
|
|
**MCP Connection:** |
|
1. When deployed on Hugging Face Spaces, the MCP server is available at: |
|
`https://your-space-id.hf.space/gradio_api/mcp/sse` |
|
2. Use this URL in Claude Desktop's MCP configuration |
|
3. The app automatically exposes functions with proper docstrings as MCP tools |
|
|
|
### π‘ **Features:** |
|
- β
Real-time RDF/XML validation against SHACL schemas |
|
- π€ AI-powered error suggestions and corrections (with HF Inference Endpoint) |
|
- π Built-in examples and templates |
|
- π Auto-validation as you type |
|
- π Copy results with one click |
|
|
|
**Note:** AI features require a valid Hugging Face API key (HF_API_KEY) set as a Secret. Manual suggestions are provided as fallback. |
|
""") |
|
|
|
return demo |
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
print("π FINAL CHECK: Verifying problematic environment variables are removed...") |
|
for var in problematic_env_vars: |
|
if var in os.environ: |
|
print(f"β οΈ WARNING: {var} still exists! Value: {os.environ[var]}") |
|
del os.environ[var] |
|
print(f"ποΈ FORCE REMOVED: {var}") |
|
else: |
|
print(f"β
{var} confirmed not in environment") |
|
|
|
demo = create_interface() |
|
|
|
|
|
port = int(os.getenv('PORT', 7860)) |
|
|
|
demo.launch( |
|
server_name="0.0.0.0", |
|
server_port=port, |
|
share=False, |
|
show_error=True, |
|
show_api=True, |
|
allowed_paths=["."] |
|
) |
|
|