Download plastic_client.py from vennsa/Polysort: direct link, hf CLI and curl.
- Browser
- Download file 8.92 kB
-
https://huggingface.co/vennsa/Polysort/resolve/main/plastic_client.py
- Command line
-
hf download hf://vennsa/Polysort/plastic_client.py
-
curl -L -o plastic_client.py https://huggingface.co/vennsa/Polysort/resolve/main/plastic_client.py
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!") | |