""" Netra AI - Public Interface Calls protected backend space for classification """ import gradio as gr from gradio_client import Client from huggingface_hub import login import os # Global backend client backend = None def get_backend(): """Lazy initialization of backend client""" global backend if backend is None: HF_TOKEN = os.getenv("HF_TOKEN") if HF_TOKEN: login(token=HF_TOKEN) backend = Client("rg321/Construction_Material_Classification") return backend def classify_material(image): """Proxy function that calls protected backend""" if image is None: return "Please upload an image", "", "" try: import tempfile from PIL import Image as PILImage from gradio_client import handle_file print(f"📤 Calling backend API with image type: {type(image)}") # Convert PIL Image to temp file for gradio_client if isinstance(image, PILImage.Image): with tempfile.NamedTemporaryFile(delete=False, suffix='.jpg', mode='wb') as tmp: image.save(tmp, 'JPEG') image_path = tmp.name else: image_path = image print(f"📤 Sending file: {image_path}") # Call protected space API with properly formatted file client = get_backend() result = client.predict( image=handle_file(image_path), api_name="/classify_material" ) print(f"📥 Backend response: {result}") # result is tuple: (classification, confidence, reasoning) return result[0], result[1], result[2] except Exception as e: import traceback error_msg = str(e) full_error = traceback.format_exc() print(f"❌ Error: {full_error}") return f"❌ Classification Error", "", f"Error: {error_msg}" # Custom CSS (same as original) custom_css = """ #header { text-align: center; background: linear-gradient(90deg, #667eea 0%, #764ba2 100%); padding: 20px; border-radius: 10px; color: white; } #result { font-size: 72px; font-weight: 900; text-align: center; padding: 50px 30px; border-radius: 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; margin-bottom: 25px; box-shadow: 0 8px 16px rgba(0,0,0,0.2); text-transform: uppercase; letter-spacing: 2px; line-height: 1.2; } #confidence { font-size: 24px; font-weight: 600; text-align: center; padding: 15px; background: #f0f9ff; border-radius: 10px; margin-bottom: 20px; } #reasoning { font-size: 14px; text-align: left; padding: 15px; background: #f9fafb; border-radius: 8px; margin-bottom: 20px; color: #4b5563; } #about { font-size: 13px; color: #6b7280; padding-top: 20px; border-top: 1px solid #e5e7eb; } """ # Build Gradio interface with gr.Blocks(css=custom_css, title="Netra AI - Material Classifier") as demo: gr.Markdown( """
AI-powered material identification for construction sites