This project implements a complete workflow for interacting with the Neurolabs Image Recognition API, including image submission, result retrieval, visualization, and data analysis.
- Robust API Integration: Retry logic with exponential backoff + jitter, rate limiting, concurrent result polling
- Image Visualization: Bounding box and modality visualization for cooler shelf images
- Data Analysis: Product distribution, shelf space analysis, and brand analysis with charts
- Production-Ready: Comprehensive logging, error handling, and configuration management
.
├── Main.py # Main orchestration script
├── data/
│ ├── coolers.csv # Cooler image URLs (2 images)
│ └── ambient.csv # Ambient image URLs (7 images)
├── src/
│ ├── api_client.py # Neurolabs API client with retry logic
│ ├── data_processor.py # Data processing and visualization
│ ├── app_config.py # Configuration management
│ └── config_check.py # API key validation
├── results/
│ ├── cooler_results.json # Cooler task results
│ ├── ambient_results.json # Ambient task results
│ ├── visualizations/ # Generated visualizations
│ └── notebooks/
│ └── analysis.ipynb # Data analysis notebook
└── tests/
└── test_api_client.py # Unit tests
- Python 3.8 or higher
- Neurolabs API key
- Clone the repository:
git clone <repository-url>
cd Neurolabs-Assignment- Install dependencies:
pip install -r requirements.txt- Configure API key:
Create a .env file in the project root:
NEUROLABS_API_KEY=your_api_key_hereAlternatively, set as environment variable:
# Windows PowerShell
$env:NEUROLABS_API_KEY="your_api_key_here"
# Linux/Mac
export NEUROLABS_API_KEY="your_api_key_here"Execute the complete workflow (submit images, retrieve results, visualize):
python Main.pyThis will:
- Fetch task UUIDs for "cooler" and "ambient" tasks
- Submit image URLs from CSV files to respective tasks
- Poll for results using individual result endpoints (not batch)
- Save results to
results/directory as JSON - Generate bounding box visualizations for cooler images with modality labels
Open the Jupyter notebook for analytical insights:
jupyter notebook results/notebooks/analysis.ipynbThe notebook generates:
- Product distribution pie chart (mapped products only)
- Top products by shelf space/area
- Brand distribution analysis (pie + bar charts)
All charts are saved to results/visualizations/analysis/
python -m pytest tests/| Variable | Default | Description |
|---|---|---|
NEUROLABS_API_KEY |
(required) | Your API key |
NEUROLABS_API_BASE_URL |
https://staging.api.neurolabs.ai/v2 |
API base URL |
SUBMIT_BATCH_SIZE |
1 |
URLs per batch submission |
SUBMIT_BATCH_DELAY |
5.0 |
Seconds between batches |
SUBMIT_MAX_ATTEMPTS |
20 |
Max retry attempts for submission |
RESULT_POLL_TIMEOUT |
300 |
Polling timeout (seconds) |
RESULT_POLL_INTERVAL |
5.0 |
Polling interval (seconds) |
RESULT_POLL_CONCURRENCY |
3 |
Concurrent polling workers |
GET_RESULTS_DELAY |
1.5 |
Delay between sequential result fetches |
Retry Logic: All API requests implement exponential backoff with jitter to handle transient failures and rate limits (429 responses). This ensures reliable operation even under poor network conditions.
Concurrency: Cooler results use concurrent polling (ThreadPoolExecutor) since they require waiting for processing completion. Ambient results use sequential fetching as they're typically ready immediately.
Rate Limiting: Conservative defaults (1 image per batch, 5-second delays) prevent API throttling. Configurable via environment variables for different use cases.
COCO Format: Bounding boxes follow COCO format [x, y, width, height] and are correctly converted to [x1, y1, x2, y2] for visualization.
EXIF Orientation: Images respect EXIF rotation data to ensure correct visualization orientation.
Flexible Parsing: Detection extraction handles multiple API response formats for robustness.
Cooler Only: Per requirements, only cooler images are visualized with bounding boxes and modality labels.
Color Coding: Red boxes with white text labels for clear visibility.
Coordinate Validation: Ensures valid bbox coordinates (x1 ≤ x2, y1 ≤ y2) to prevent drawing errors.
Unmapped Filtering: Analysis excludes unmapped/numeric product IDs (163 detections, 63.4%) to focus on meaningful catalog-mapped products.
Top Products: Charts show top 12 products + "Other" category to maintain readability.
Multi-Metric Analysis: Combines count-based (pie chart) and area-based (shelf space) metrics for comprehensive insights.
- CSV Format: CSV files have a column named
urlor any column containing HTTP URLs - Task Names: API tasks contain "cooler" or "ambient" in their names (case-insensitive)
- Result Structure: API returns results with
uuidfield and COCO-formatted annotations - Network Stability: Reasonable network connectivity (retry logic handles transient failures)
- Synchronous Processing: Tasks are processed sequentially (ambient then cooler). Could be parallelized for faster execution.
- No Result Caching: Re-running fetches fresh results from API. Could cache to reduce API calls.
- Limited Error Recovery: Fatal errors (e.g., invalid API key) exit immediately. Could implement graceful degradation.
- Fixed Visualization Style: Bounding box colors and labels are hardcoded. Could be made configurable.
- Memory Constraints: All results loaded into memory. Large datasets may require streaming approach.
- Some product detections return numeric IDs instead of UUIDs (63.4% unmapped). These are excluded from analysis.
- Bbox coordinates occasionally inverted in API responses; code validates and corrects.
results/cooler_submission_response.json- Raw submission responseresults/cooler_results.json- Detailed cooler results (68 boxes across 2 images)results/ambient_submission_response.json- Raw submission responseresults/ambient_results.json- Detailed ambient results
results/visualizations/cooler/*.png- Annotated cooler images with bounding boxesresults/visualizations/analysis/product_distribution.png- Product pie chartresults/visualizations/analysis/products_by_area.png- Shelf space analysisresults/visualizations/analysis/brand_analysis.png- Brand distribution charts
Note: Example PNG outputs are included in the GitHub repository for reference.
results/visualizations/analysis/products_by_area.csv- Area data exportresults/visualizations/analysis/brand_distribution.csv- Brand counts export
Uses /image-recognition/tasks to get task UUIDs
Uses /image-recognition/tasks/{task_uuid}/urls for submission
Uses /image-recognition/tasks/{task_uuid}/results/{result_uuid} for individual results (NOT batch endpoint)
Uses /catalog-items for product name mapping
Implements robust retry logic for 429 rate limits
Includes Authorization: Bearer <API_KEY> and X-API-Key headers
- Type Hints: Used throughout for better IDE support and documentation
- Logging: Comprehensive INFO/ERROR logging for debugging and monitoring
- Error Handling: Try-except blocks with specific exception handling
- Code Optimization: 47-58% reduction in code size vs. original while maintaining functionality
- Clean Code: Walrus operators, list comprehensions, and minimal redundancy
- Tests: Unit tests for critical API client functionality
- Cooler task: ~2 minutes (includes polling for processing completion)
- Ambient task: ~15 seconds (results ready immediately)
- Total runtime: ~2-3 minutes for full workflow
Implementation for Neurolabs Take-Home Assignment