youkii-xr commited on
Commit
db4e1b2
·
verified ·
1 Parent(s): d30e626

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -23
app.py CHANGED
@@ -6,42 +6,45 @@ from huggingface_hub import hf_hub_download
6
  import numpy as np
7
 
8
  # --- 1. SETUP & MODEL LOADING ---
9
- # We download the model securely at startup
10
- MODEL_REPO = "youkii-xr/hieroglyphic-detection" # <--- REPLACE THIS
11
  MODEL_FILENAME = "best.pt"
12
 
13
- print(f"Attempting to download {MODEL_FILENAME} from {MODEL_REPO}...")
 
14
 
15
  try:
 
 
 
16
  model_path = hf_hub_download(
17
  repo_id=MODEL_REPO,
18
  filename=MODEL_FILENAME,
19
- token=os.environ.get("HF_TOKEN") # Needs 'HF_TOKEN' secret in Space settings
20
  )
21
- print(f"Model downloaded to: {model_path}")
22
  model = YOLO(model_path)
23
  except Exception as e:
24
- print(f"CRITICAL ERROR loading model: {e}")
25
  model = None
26
 
27
  # --- 2. DETECTION LOGIC ---
28
- # NOTE: Type hints (image: Image.Image) and Docstrings are MANDATORY for MCP
29
  def detect_hieroglyphs(image: Image.Image, conf_threshold: float = 0.25):
30
  """
31
- Detects Egyptian hieroglyph symbols in an image.
32
 
33
  Args:
34
- image: The image to analyze (uploaded file).
35
- conf_threshold: Confidence threshold for detection (default 0.25).
36
 
37
  Returns:
38
- A tuple containing the annotated image with bounding boxes and a JSON summary of findings.
39
  """
40
  if image is None:
41
  return None, {"error": "No image provided"}
42
 
43
  if model is None:
44
- return None, {"error": "Model failed to load on server."}
45
 
46
  try:
47
  # Run Inference
@@ -51,12 +54,11 @@ def detect_hieroglyphs(image: Image.Image, conf_threshold: float = 0.25):
51
  iou=0.45,
52
  imgsz=640,
53
  verbose=False,
54
- device='cpu', # Spaces usually run on CPU unless you pay for GPU
55
  max_det=300
56
  )
57
 
58
- # 1. Generate Visual Output
59
- # plot() returns BGR numpy array, convert to RGB PIL
60
  annotated_array = results[0].plot()
61
  annotated_image = Image.fromarray(annotated_array[..., ::-1])
62
 
@@ -77,13 +79,12 @@ def detect_hieroglyphs(image: Image.Image, conf_threshold: float = 0.25):
77
  detections.append({
78
  "code": code,
79
  "confidence": round(conf, 2),
80
- # Convert bbox to list for JSON serialization
81
  "box": [round(x, 1) for x in box.xyxy[0].cpu().numpy().tolist()]
82
  })
83
 
84
  summary = {
85
  "status": "success",
86
- "total_detected": len(detections),
87
  "unique_symbols": list(gardiner_counts.keys()),
88
  "counts": gardiner_counts
89
  }
@@ -91,24 +92,30 @@ def detect_hieroglyphs(image: Image.Image, conf_threshold: float = 0.25):
91
  return annotated_image, summary
92
 
93
  except Exception as e:
94
- print(f"Error during inference: {e}")
95
  return None, {"error": str(e)}
96
 
97
- # --- 3. INTERFACE & SERVER ---
98
- # mcp_server=True creates the endpoint automatically
99
  demo = gr.Interface(
100
  fn=detect_hieroglyphs,
101
  inputs=[
102
  gr.Image(type="pil", label="Upload Image"),
103
- gr.Number(value=0.25, label="Confidence Threshold")
104
  ],
105
  outputs=[
106
  gr.Image(label="Annotated Result"),
107
  gr.JSON(label="Detection Data")
108
  ],
109
  title="Egyptian Hieroglyph MCP Server",
110
- description="MCP-compatible server for Hieroglyph Detection. Connect this to Claude Desktop."
111
  )
112
 
113
  if __name__ == "__main__":
114
- demo.launch(mcp_server=True)
 
 
 
 
 
 
 
 
6
  import numpy as np
7
 
8
  # --- 1. SETUP & MODEL LOADING ---
9
+ # Replace with your actual private repo ID
10
+ MODEL_REPO = "youkii-xr/hieroglyphic-detection"
11
  MODEL_FILENAME = "best.pt"
12
 
13
+ print(f"Server Status: Public MCP Endpoint Active")
14
+ print(f"Security: Model weights are protected (private repo)")
15
 
16
  try:
17
+ # 🔒 SECURE DOWNLOAD:
18
+ # This uses the 'HF_TOKEN' Secret from Space Settings to authenticate.
19
+ # Users of the Space CANNOT see this token or the downloaded file.
20
  model_path = hf_hub_download(
21
  repo_id=MODEL_REPO,
22
  filename=MODEL_FILENAME,
23
+ token=os.environ.get("HF_TOKEN")
24
  )
25
+ print(f"System: Model loaded successfully from private storage.")
26
  model = YOLO(model_path)
27
  except Exception as e:
28
+ print(f"CRITICAL ERROR: Could not load model. Check HF_TOKEN in Settings. {e}")
29
  model = None
30
 
31
  # --- 2. DETECTION LOGIC ---
 
32
  def detect_hieroglyphs(image: Image.Image, conf_threshold: float = 0.25):
33
  """
34
+ Analyzes an image to find Egyptian hieroglyphs.
35
 
36
  Args:
37
+ image: The image to analyze.
38
+ conf_threshold: Confidence level (0.1 to 1.0). Default is 0.25.
39
 
40
  Returns:
41
+ A tuple containing the annotated image and a JSON summary of findings.
42
  """
43
  if image is None:
44
  return None, {"error": "No image provided"}
45
 
46
  if model is None:
47
+ return None, {"error": "Server Error: Model not loaded."}
48
 
49
  try:
50
  # Run Inference
 
54
  iou=0.45,
55
  imgsz=640,
56
  verbose=False,
57
+ device='cpu',
58
  max_det=300
59
  )
60
 
61
+ # 1. Generate Visual Output (RGB Image)
 
62
  annotated_array = results[0].plot()
63
  annotated_image = Image.fromarray(annotated_array[..., ::-1])
64
 
 
79
  detections.append({
80
  "code": code,
81
  "confidence": round(conf, 2),
 
82
  "box": [round(x, 1) for x in box.xyxy[0].cpu().numpy().tolist()]
83
  })
84
 
85
  summary = {
86
  "status": "success",
87
+ "total_found": len(detections),
88
  "unique_symbols": list(gardiner_counts.keys()),
89
  "counts": gardiner_counts
90
  }
 
92
  return annotated_image, summary
93
 
94
  except Exception as e:
95
+ print(f"Inference Error: {e}")
96
  return None, {"error": str(e)}
97
 
98
+ # --- 3. INTERFACE ---
 
99
  demo = gr.Interface(
100
  fn=detect_hieroglyphs,
101
  inputs=[
102
  gr.Image(type="pil", label="Upload Image"),
103
+ gr.Number(value=0.25, label="Confidence")
104
  ],
105
  outputs=[
106
  gr.Image(label="Annotated Result"),
107
  gr.JSON(label="Detection Data")
108
  ],
109
  title="Egyptian Hieroglyph MCP Server",
110
+ description="Public MCP Endpoint for Hieroglyph Detection. (Model Weights are Private)"
111
  )
112
 
113
  if __name__ == "__main__":
114
+ # Settings to ensure Public access works without 403 errors:
115
+ # ssr_mode=False: Disables Server-Side Rendering (helps with API proxies)
116
+ # allowed_paths: Grants permission to read temp files uploaded by MCP
117
+ demo.launch(
118
+ mcp_server=True,
119
+ ssr_mode=False,
120
+ allowed_paths=["/tmp"]
121
+ )