Spaces:
Runtime error
Runtime error
| import requests | |
| import io | |
| from PIL import Image | |
| from typing import Dict, Any | |
| import logging | |
| logger = logging.getLogger(__name__) | |
| class DermaScanAPIClient: | |
| """Client for external DermaScan AI API""" | |
| def __init__(self, base_url: str = "https://omarelrayes-api.hf.space"): | |
| self.base_url = base_url.rstrip('/') | |
| self.timeout = 60 | |
| def health_check(self) -> bool: | |
| """Check if external API is healthy""" | |
| try: | |
| response = requests.get(f"{self.base_url}/health", timeout=5) | |
| return response.status_code == 200 | |
| except Exception as e: | |
| logger.error(f"Health check failed: {e}") | |
| return False | |
| def upload_and_analyze_image(self, image: Image.Image, thread_id: str) -> Dict[str, Any]: | |
| """ | |
| Upload image and get full analysis (classification + segmentation) | |
| Returns dict with: label, confidence_pct, infection_pct, images | |
| """ | |
| try: | |
| # Convert PIL Image to bytes | |
| img_byte_arr = io.BytesIO() | |
| image.save(img_byte_arr, format='PNG') | |
| img_byte_arr.seek(0) | |
| # Upload and analyze | |
| files = {'file': ('image.png', img_byte_arr, 'image/png')} | |
| data = {'thread_id': thread_id} | |
| response = requests.post( | |
| f"{self.base_url}/analyze-image", | |
| files=files, | |
| data=data, | |
| timeout=self.timeout | |
| ) | |
| response.raise_for_status() | |
| result = response.json() | |
| if not result.get('ok'): | |
| return {'error': result.get('error', 'Analysis failed')} | |
| return { | |
| 'label': result.get('label', 'Unknown'), | |
| 'confidence_pct': result.get('confidence_pct', 0), | |
| 'infection_pct': result.get('infection_pct', 0), | |
| 'images': result.get('images', {}), | |
| 'patient': result.get('patient', {}), | |
| } | |
| except requests.exceptions.Timeout: | |
| return {'error': 'API request timed out'} | |
| except requests.exceptions.RequestException as e: | |
| return {'error': f'API request failed: {str(e)}'} | |
| except Exception as e: | |
| logger.error(f"Unexpected error in upload_and_analyze_image: {e}", exc_info=True) | |
| return {'error': f'Unexpected error: {str(e)}'} | |
| def book_appointment(self, thread_id: str, city: str = "") -> Dict[str, Any]: | |
| """Book appointment via external API""" | |
| try: | |
| response = requests.post( | |
| f"{self.base_url}/book-appointment", | |
| json={'thread_id': thread_id, 'city': city}, | |
| timeout=30 | |
| ) | |
| response.raise_for_status() | |
| return response.json() | |
| except Exception as e: | |
| return {'ok': False, 'error': str(e)} | |
| def get_patient_image(self, thread_id: str) -> Dict[str, Any]: | |
| """Get patient's uploaded image""" | |
| try: | |
| response = requests.get( | |
| f"{self.base_url}/patient-image", | |
| params={'thread_id': thread_id}, | |
| timeout=30 | |
| ) | |
| response.raise_for_status() | |
| return response.json() | |
| except Exception as e: | |
| return {'ok': False, 'error': str(e)} | |
| def segment_patient_image(self, thread_id: str) -> Dict[str, Any]: | |
| """Segment patient's image""" | |
| try: | |
| response = requests.post( | |
| f"{self.base_url}/segment-patient-image", | |
| json={'thread_id': thread_id}, | |
| timeout=60 | |
| ) | |
| response.raise_for_status() | |
| return response.json() | |
| except Exception as e: | |
| return {'ok': False, 'error': str(e)} | |
| def reanalyze_patient_image(self, thread_id: str) -> Dict[str, Any]: | |
| """Reanalyze patient's image""" | |
| try: | |
| response = requests.post( | |
| f"{self.base_url}/reanalyze-patient-image", | |
| json={'thread_id': thread_id}, | |
| timeout=60 | |
| ) | |
| response.raise_for_status() | |
| return response.json() | |
| except Exception as e: | |
| return {'ok': False, 'error': str(e)} |