raghav
Fix: Use handle_file() for proper gradio_client file upload
732911b
Raw History Blame Contribute Delete
5.69 kB
"""
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(
"""
<div id="header">
<h1>πŸ—οΈ Netra AI - Construction Material Classifier</h1>
<p>AI-powered material identification for construction sites</p>
</div>
""",
elem_id="header"
)
with gr.Row():
with gr.Column(scale=1):
gr.Markdown("### πŸ“Έ Upload Material Image")
image_input = gr.Image(
type="pil",
label="Construction Material Photo",
height=400
)
classify_btn = gr.Button("πŸš€ Classify Material", variant="primary", size="lg")
gr.Markdown(
"""
**Supported Materials:**
- πŸ–οΈ Reet (Sand)
- πŸ”· 12mm VSI (Uniform Aggregate)
- πŸͺ¨ Stone (Large Boulders)
- πŸ—οΈ GSB (Mixed Graded Base)
"""
)
gr.Markdown("### πŸ“· Try Sample Images")
gr.Examples(
examples=[
["sanity_test_dataset/12mm_VSI_01.jpeg"],
["sanity_test_dataset/Reet_01_fine.jpeg"],
["sanity_test_dataset/Stone_01.jpeg"],
["sanity_test_dataset/GSB_01.jpeg"],
],
inputs=image_input,
label=""
)
with gr.Column(scale=1):
result_output = gr.Markdown("", elem_id="result")
confidence_output = gr.Markdown("", elem_id="confidence")
reasoning_output = gr.Markdown("", elem_id="reasoning")
gr.Markdown(
"""
<div id="about">
### πŸ“Š About This Demo
This is a proof-of-concept for **Netra AI's** automated material classification system.
**Technology:**
- Vision AI for real-time material identification
- Prevents grade fraud at construction sites
- Automates dispatch logging
**Use Cases:**
- Gate monitoring at crusher plants
- Dispatch verification
- Quality control
---
**Netra AI** - *Making every tonne count.*
For commercial inquiries: [Contact Us](mailto:guptaraghu321@gmail.com)
</div>
"""
)
# Connect button
classify_btn.click(
fn=classify_material,
inputs=[image_input],
outputs=[result_output, confidence_output, reasoning_output]
)
# Launch
if __name__ == "__main__":
demo.launch(show_error=True)