AIcoder35235 commited on
Commit
f30e238
·
verified ·
1 Parent(s): cccf4f0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -14
app.py CHANGED
@@ -5,10 +5,11 @@ from transformers import pipeline
5
  from PIL import Image
6
  import base64
7
  import io
 
8
 
9
  app = FastAPI(title="STOA Chest X-Ray API")
10
 
11
- # Allow the frontend and OpenClaw to communicate with this node
12
  app.add_middleware(
13
  CORSMiddleware,
14
  allow_origins=["*"],
@@ -17,14 +18,18 @@ app.add_middleware(
17
  allow_headers=["*"],
18
  )
19
 
20
- # Load the ViT model into RAM (Downloads instantly because we cache it in Docker)
21
  print("Booting Pulmonology Agent. Loading ViT model into memory...")
22
  pipe = pipeline("image-classification", model="dima806/chest_xray_pneumonia_detection")
23
  print("Agent Ready!")
24
 
25
- # Define the expected JSON payload from OpenClaw
 
26
  class PredictRequest(BaseModel):
27
- image: str
 
 
 
28
 
29
  @app.get("/health")
30
  def health_check():
@@ -33,19 +38,31 @@ def health_check():
33
  @app.post("/predict")
34
  def predict(req: PredictRequest):
35
  try:
36
- # 1. Clean the base64 string if it contains the HTML data URI prefix
37
- b64_data = req.image
38
- if "," in b64_data:
39
- b64_data = b64_data.split(",")[1]
40
-
41
- # 2. Convert base64 string back into raw image bytes
42
- image_bytes = base64.b64decode(b64_data)
43
- img = Image.open(io.BytesIO(image_bytes)).convert("RGB")
44
 
45
- # 3. Execute Neural Network Math
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  results = pipe(img)
47
 
48
- # 4. Format the output to exactly match the Task 24 Spec
49
  top_pred = max(results, key=lambda x: x['score'])
50
  scores_dict = {res['label']: round(res['score'], 4) for res in results}
51
 
 
5
  from PIL import Image
6
  import base64
7
  import io
8
+ import requests
9
 
10
  app = FastAPI(title="STOA Chest X-Ray API")
11
 
12
+ # --- CORS ---
13
  app.add_middleware(
14
  CORSMiddleware,
15
  allow_origins=["*"],
 
18
  allow_headers=["*"],
19
  )
20
 
21
+ # --- MODEL LOADING ---
22
  print("Booting Pulmonology Agent. Loading ViT model into memory...")
23
  pipe = pipeline("image-classification", model="dima806/chest_xray_pneumonia_detection")
24
  print("Agent Ready!")
25
 
26
+ # --- REQUEST SCHEMA ---
27
+ # Pydantic allows either field to be optional, so the user can send one or the other
28
  class PredictRequest(BaseModel):
29
+ image: str | None = None
30
+ image_url: str | None = None
31
+
32
+ # --- ENDPOINTS ---
33
 
34
  @app.get("/health")
35
  def health_check():
 
38
  @app.post("/predict")
39
  def predict(req: PredictRequest):
40
  try:
41
+ img = None
 
 
 
 
 
 
 
42
 
43
+ # 1. Handle URL Input
44
+ if req.image_url:
45
+ response = requests.get(req.image_url, stream=True)
46
+ if response.status_code != 200:
47
+ raise Exception("Could not download image from URL.")
48
+ img = Image.open(response.raw).convert("RGB")
49
+
50
+ # 2. Handle Base64 Input
51
+ elif req.image:
52
+ b64_data = req.image
53
+ if "," in b64_data:
54
+ b64_data = b64_data.split(",")[1]
55
+ image_bytes = base64.b64decode(b64_data)
56
+ img = Image.open(io.BytesIO(image_bytes)).convert("RGB")
57
+
58
+ # 3. Handle Empty Request
59
+ else:
60
+ raise HTTPException(status_code=400, detail="Must provide 'image' (base64) or 'image_url'.")
61
+
62
+ # 4. Execute AI Math
63
  results = pipe(img)
64
 
65
+ # 5. Format to exact Task 24 specifications
66
  top_pred = max(results, key=lambda x: x['score'])
67
  scores_dict = {res['label']: round(res['score'], 4) for res in results}
68