OppaAI commited on
Commit
9f6e9fd
·
verified ·
1 Parent(s): 6bcc2b6

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +22 -23
app.py CHANGED
@@ -8,28 +8,31 @@ from typing import Dict, Any
8
  import gradio as gr
9
  from huggingface_hub import HfApi, InferenceClient
10
  from fastmcp import FastMCP
11
- from pydantic import BaseModel, Field # Import Pydantic BaseModel and Field
12
 
13
  HF_DATASET_REPO = os.environ.get("HF_DATASET_REPO", "OppaAI/Robot_MCP")
14
  HF_VLM_MODEL = os.environ.get("HF_VLM_MODEL", "Qwen/Qwen2.5-VL-7B-Instruct")
15
 
16
- mcp = FastMCP("Robot_MCP_Server") # <-- Important
 
17
 
18
  # ---------------------------------------------------
19
- # Define Pydantic Schema for the input payload
20
  # ---------------------------------------------------
21
- # This defines the expected structure and automatically generates the valid JSON schema
22
  class RobotWatchPayload(BaseModel):
23
  hf_token: str = Field(description="Your Hugging Face API token.")
24
- robot_id: str = Field(description="The unique identifier for the robot.", default="unknown")
25
  image_b64: str = Field(description="Base64 encoded image data.")
26
 
27
 
 
 
 
28
  def upload_image(image_b64: str, hf_token: str):
29
  try:
30
  image_bytes = base64.b64decode(image_b64)
31
-
32
  os.makedirs("/tmp", exist_ok=True)
 
33
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
34
  local_path = f"/tmp/robot_img_{timestamp}.jpg"
35
 
@@ -38,6 +41,7 @@ def upload_image(image_b64: str, hf_token: str):
38
 
39
  filename = f"robot_{timestamp}.jpg"
40
  api = HfApi()
 
41
  api.upload_file(
42
  path_or_fileobj=local_path,
43
  path_in_repo=f"tmp/{filename}",
@@ -46,14 +50,17 @@ def upload_image(image_b64: str, hf_token: str):
46
  token=hf_token
47
  )
48
 
49
- url = f"https://huggingface.co/datasets/{HF_DATASET_REPO}/resolve/main/tmp/{filename}"
50
- return local_path, url, filename, len(image_bytes)
51
 
52
  except Exception:
53
  traceback.print_exc()
54
  return None, None, None, 0
55
 
56
 
 
 
 
57
  def safe_parse_json_from_text(text: str):
58
  if not text:
59
  return None
@@ -75,20 +82,14 @@ def safe_parse_json_from_text(text: str):
75
 
76
 
77
  # ---------------------------------------------------
78
- # TRUE MCP TOOL — THIS must be exposed to MCP client
79
  # ---------------------------------------------------
80
  @mcp.tool("robot_watch", description="Analyze a base64 image using Qwen VLM and return structured JSON.")
81
- def robot_watch(payload: RobotWatchPayload): # <-- Type hint with Pydantic model
82
- # The payload is already validated and typed correctly by fastmcp/pydantic
83
  hf_token = payload.hf_token
84
  image_b64 = payload.image_b64
85
  robot_id = payload.robot_id
86
 
87
- if not hf_token:
88
- # This check is technically redundant if the schema demands it, but safe.
89
- return {"error": "Missing hf_token"}
90
- # image_b64 existence is also guaranteed by the schema
91
-
92
  _, hf_url, _, size_bytes = upload_image(image_b64, hf_token)
93
  if not hf_url:
94
  return {"error": "Image upload failed"}
@@ -136,21 +137,19 @@ Respond in STRICT JSON ONLY:
136
 
137
 
138
  # ---------------------------------------------------
139
- # Gradio UI — Use a simple placeholder function for the UI
140
  # ---------------------------------------------------
141
- def robot_watch(payload):
142
- # This is just for the interactive UI, the real API call goes to /robot_watch endpoint
143
- return {"message": "Use the MCP Client to call the robot_watch tool."}
144
 
145
 
146
  app = gr.Interface(
147
- fn=robot_watch,
148
  inputs=gr.JSON(),
149
  outputs=gr.JSON(),
150
  title="Robot MCP Server",
151
- description="A MCP Server to describe image obtained from the CV of a Robot/Webcam"
152
  )
153
 
154
  if __name__ == "__main__":
155
- # Launch Gradio, which automatically hooks up the 'mcp' instance's APIs
156
  app.launch(mcp_server=True)
 
8
  import gradio as gr
9
  from huggingface_hub import HfApi, InferenceClient
10
  from fastmcp import FastMCP
11
+ from pydantic import BaseModel, Field
12
 
13
  HF_DATASET_REPO = os.environ.get("HF_DATASET_REPO", "OppaAI/Robot_MCP")
14
  HF_VLM_MODEL = os.environ.get("HF_VLM_MODEL", "Qwen/Qwen2.5-VL-7B-Instruct")
15
 
16
+ mcp = FastMCP("Robot_MCP_Server")
17
+
18
 
19
  # ---------------------------------------------------
20
+ # Payload Schema
21
  # ---------------------------------------------------
 
22
  class RobotWatchPayload(BaseModel):
23
  hf_token: str = Field(description="Your Hugging Face API token.")
24
+ robot_id: str = Field(description="Robot identifier.", default="unknown")
25
  image_b64: str = Field(description="Base64 encoded image data.")
26
 
27
 
28
+ # ---------------------------------------------------
29
+ # Upload Helper
30
+ # ---------------------------------------------------
31
  def upload_image(image_b64: str, hf_token: str):
32
  try:
33
  image_bytes = base64.b64decode(image_b64)
 
34
  os.makedirs("/tmp", exist_ok=True)
35
+
36
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S_%f")
37
  local_path = f"/tmp/robot_img_{timestamp}.jpg"
38
 
 
41
 
42
  filename = f"robot_{timestamp}.jpg"
43
  api = HfApi()
44
+
45
  api.upload_file(
46
  path_or_fileobj=local_path,
47
  path_in_repo=f"tmp/{filename}",
 
50
  token=hf_token
51
  )
52
 
53
+ hf_url = f"https://huggingface.co/datasets/{HF_DATASET_REPO}/resolve/main/tmp/{filename}"
54
+ return local_path, hf_url, filename, len(image_bytes)
55
 
56
  except Exception:
57
  traceback.print_exc()
58
  return None, None, None, 0
59
 
60
 
61
+ # ---------------------------------------------------
62
+ # JSON Cleaning Helper
63
+ # ---------------------------------------------------
64
  def safe_parse_json_from_text(text: str):
65
  if not text:
66
  return None
 
82
 
83
 
84
  # ---------------------------------------------------
85
+ # TRUE MCP TOOL
86
  # ---------------------------------------------------
87
  @mcp.tool("robot_watch", description="Analyze a base64 image using Qwen VLM and return structured JSON.")
88
+ def robot_watch_tool(payload: RobotWatchPayload):
 
89
  hf_token = payload.hf_token
90
  image_b64 = payload.image_b64
91
  robot_id = payload.robot_id
92
 
 
 
 
 
 
93
  _, hf_url, _, size_bytes = upload_image(image_b64, hf_token)
94
  if not hf_url:
95
  return {"error": "Image upload failed"}
 
137
 
138
 
139
  # ---------------------------------------------------
140
+ # Gradio UI Placeholder
141
  # ---------------------------------------------------
142
+ def robot_watch_ui(payload):
143
+ return {"message": "Use an MCP Client to call the robot_watch tool."}
 
144
 
145
 
146
  app = gr.Interface(
147
+ fn=robot_watch_ui,
148
  inputs=gr.JSON(),
149
  outputs=gr.JSON(),
150
  title="Robot MCP Server",
151
+ description="A MCP Server to describe image obtained from the CV of a robot/webcam."
152
  )
153
 
154
  if __name__ == "__main__":
 
155
  app.launch(mcp_server=True)