Polysort / plastic_client.py
vennsa's picture
Upload 6 files
105944b verified
Raw History Blame Contribute Delete
8.92 kB
"""
Plastic Detection API Client Library
A simple Python client for interacting with the Plastic Detection API.
Usage:
from plastic_client import PlasticDetectionClient
client = PlasticDetectionClient("http://localhost:8000")
results = client.predict("path/to/image.jpg")
print(results)
"""
import requests
import json
from typing import Dict, List, Optional
from pathlib import Path
class PlasticDetectionClient:
"""Client for Plastic Detection API"""
# Hardcoded API server URL
DEFAULT_API_URL = "http://localhost:8000"
def __init__(self, base_url: str = None):
"""
Initialize the client
Args:
base_url: Base URL of the API server (defaults to localhost:8000)
"""
if base_url is None:
base_url = self.DEFAULT_API_URL
self.base_url = base_url.rstrip('/')
self.session = requests.Session()
def health_check(self) -> bool:
"""
Check if the API server is running
Returns:
True if server is running, False otherwise
"""
try:
response = self.session.get(f"{self.base_url}/")
return response.status_code == 200
except requests.exceptions.ConnectionError:
return False
def get_classes(self) -> Dict[int, str]:
"""
Get all detectable plastic classes
Returns:
Dictionary mapping class IDs to class names
"""
response = self.session.get(f"{self.base_url}/classes")
response.raise_for_status()
data = response.json()
return data.get('classes', {})
def predict(self, image_path: str, confidence_threshold: float = 0.25) -> Dict:
"""
Predict plastic types in an image
Args:
image_path: Path to the image file
confidence_threshold: Minimum confidence score (0.0-1.0)
Returns:
Dictionary containing detection results
Raises:
FileNotFoundError: If image file doesn't exist
requests.exceptions.RequestException: If API call fails
"""
image_path = Path(image_path)
if not image_path.exists():
raise FileNotFoundError(f"Image not found: {image_path}")
with open(image_path, 'rb') as f:
files = {'file': f}
response = self.session.post(f"{self.base_url}/predict", files=files)
response.raise_for_status()
return response.json()
def predict_bytes(self, image_bytes: bytes, filename: str = "image.jpg") -> Dict:
"""
Predict plastic types from image bytes
Args:
image_bytes: Image file content as bytes
filename: Original filename for reference
Returns:
Dictionary containing detection results
"""
files = {'file': (filename, image_bytes)}
response = self.session.post(f"{self.base_url}/predict", files=files)
response.raise_for_status()
return response.json()
def predict_multiple(self, image_paths: List[str]) -> List[Dict]:
"""
Predict on multiple images
Args:
image_paths: List of image file paths
Returns:
List of prediction results
"""
results = []
for image_path in image_paths:
try:
result = self.predict(image_path)
results.append({
'image': str(image_path),
'success': True,
'data': result
})
except Exception as e:
results.append({
'image': str(image_path),
'success': False,
'error': str(e)
})
return results
def filter_detections(self, predictions: Dict, min_confidence: float = 0.5,
classes: Optional[List[str]] = None) -> Dict:
"""
Filter detections by confidence and class
Args:
predictions: Prediction result from predict()
min_confidence: Minimum confidence threshold
classes: List of class names to filter by (None = all)
Returns:
Filtered prediction results
"""
filtered_detections = []
for det in predictions.get('detections', []):
# Filter by confidence
if det['confidence'] < min_confidence:
continue
# Filter by class
if classes and det['class'] not in classes:
continue
filtered_detections.append(det)
predictions_copy = predictions.copy()
predictions_copy['detections'] = filtered_detections
predictions_copy['count'] = len(filtered_detections)
return predictions_copy
def get_statistics(self, predictions: Dict) -> Dict:
"""
Get statistics from predictions
Args:
predictions: Prediction result from predict()
Returns:
Dictionary with statistics
"""
detections = predictions.get('detections', [])
if not detections:
return {
'total_detections': 0,
'classes': {},
'average_confidence': 0.0,
'max_confidence': 0.0,
'min_confidence': 0.0
}
classes_count = {}
confidences = []
for det in detections:
classes_count[det['class']] = classes_count.get(det['class'], 0) + 1
confidences.append(det['confidence'])
return {
'total_detections': len(detections),
'classes': classes_count,
'average_confidence': sum(confidences) / len(confidences),
'max_confidence': max(confidences),
'min_confidence': min(confidences)
}
def save_results_json(self, predictions: Dict, output_path: str):
"""
Save prediction results to JSON file
Args:
predictions: Prediction result from predict()
output_path: Path to save JSON file
"""
with open(output_path, 'w') as f:
json.dump(predictions, f, indent=2)
def close(self):
"""Close the session"""
self.session.close()
def __enter__(self):
return self
def __exit__(self, exc_type, exc_val, exc_tb):
self.close()
# Example usage
if __name__ == "__main__":
import sys
print("Plastic Detection API Client Example")
print("=" * 50)
# Initialize client
client = PlasticDetectionClient("http://localhost:8000")
# Check health
print("\n✓ Checking server health...")
if client.health_check():
print(" Server is running!")
else:
print(" ✗ Server is not responding")
sys.exit(1)
# Get classes
print("\n✓ Available classes:")
classes = client.get_classes()
for cls_id, cls_name in classes.items():
print(f" {cls_id}: {cls_name}")
# Test prediction
test_image = "test/images/00000062_jpg.rf.e4f04e59310a48547b50edcdebc1c286.jpg"
try:
print(f"\n✓ Running prediction on {test_image}...")
results = client.predict(test_image)
print(f" Detections: {results['count']}")
if results['detections']:
print(" Objects found:")
for det in results['detections']:
print(f" - {det['class']}: {det['confidence']:.2%}")
# Get statistics
stats = client.get_statistics(results)
print(f"\n Statistics:")
print(f" Total: {stats['total_detections']}")
print(f" Avg Confidence: {stats['average_confidence']:.2%}")
print(f" Classes: {stats['classes']}")
# Filter by confidence
filtered = client.filter_detections(results, min_confidence=0.8)
print(f"\n After filtering (conf > 0.8): {filtered['count']} detections")
except FileNotFoundError:
print(f" ✗ Test image not found: {test_image}")
except Exception as e:
print(f" ✗ Error: {e}")
finally:
client.close()
print("\n" + "=" * 50)
print("Example completed!")