REST API server for Shelly Manager built with Litestar.
- HTTP REST API for device management
- OpenAPI documentation at
/docs - Request/response validation
- Health monitoring endpoint
- CORS support for web integration
- Docker deployment ready
# Run API server
docker run -p 8000:8000 \
-v ./config.json:/app/config.json:ro \
ghcr.io/jfmlima/shelly-manager-api:latest
# Visit API documentation
open http://localhost:8000/docs# Install dependencies (from project root)
uv sync --package shelly-manager-api --extra dev
# Start development server
uv run --package shelly-manager-api python -m api.main
# API available at http://localhost:8000
# Docs available at http://localhost:8000/docsGET /api/health # Service health checkGET /api/devices/scan # Scan network for devices
?start_ip=192.168.1.1 # Start IP address
&end_ip=192.168.1.254 # End IP address
&use_predefined=true # Use predefined ranges
&use_mdns=false # Use mDNS discovery
&timeout=3.0 # Timeout per device
&max_workers=50 # Concurrent workersGET /api/devices/{ip}/status # Get device status
?include_updates=true # Include update information
POST /api/devices/{ip}/update # Update device firmware
?channel=stable # Update channel (stable/beta)
POST /api/devices/{ip}/reboot # Reboot device
POST /api/devices/bulk/update # Bulk firmware updates
# Body: {"device_ips": ["192.168.1.100", "192.168.1.101"], "channel": "stable"}
# Component Actions
GET /api/devices/{ip}/components/actions # Discover available actions
POST /api/devices/{ip}/components/{id}/action # Execute component actionThe Component Actions system provides dynamic action discovery and execution for individual device components.
GET /api/devices/{ip}/components/actions # Get all available actions for devicePOST /api/devices/{ip}/components/{component_id}/actionGET /api/healthcurl "http://localhost:8000/api/devices/scan?start_ip=192.168.1.1&end_ip=192.168.1.10"Response:
[
{
"ip": "192.168.1.100",
"status": "online",
"device_type": "shelly1pm",
"device_name": "Living Room Light",
"firmware_version": "20230913-112003",
"response_time": 0.123,
"last_seen": "2024-01-15T10:30:00Z"
}
]curl -X POST "http://localhost:8000/api/devices/192.168.1.100/update?channel=stable"Response:
{
"ip": "192.168.1.100",
"success": true,
"message": "Firmware update initiated",
"action_type": "firmware_update"
}curl "http://localhost:8000/api/devices/192.168.1.100/components/actions"Response Example:
{
"device_ip": "192.168.1.100",
"components": [
{
"component_id": "switch:0",
"component_type": "switch",
"available_actions": [
{
"action": "toggle",
"description": "Toggle switch state",
"parameters": {}
},
{
"action": "turn_on",
"description": "Turn switch on",
"parameters": {}
}
]
}
]
}curl -X POST "http://localhost:8000/api/devices/192.168.1.100/components/switch:0/action" \
-H "Content-Type: application/json" \
-d '{"action": "toggle", "params": {}}'Request Body:
{
"action": "toggle",
"params": {}
}Response:
{
"ip": "192.168.1.100",
"component_id": "switch:0",
"action": "toggle",
"success": true,
"result": {
"new_state": "on"
}
}curl -X POST "http://localhost:8000/api/devices/192.168.1.100/components/cover:0/action" \
-H "Content-Type: application/json" \
-d '{"action": "open", "params": {}}'{
"detail": "Device not reachable",
"status_code": 404,
"ip": "192.168.1.100"
}| Variable | Default | Description |
|---|---|---|
HOST |
127.0.0.1 |
API server host |
PORT |
8000 |
API server port |
DEBUG |
false |
Enable debug mode |
SHELLY_CONFIG_FILE |
config.json |
Path to configuration file |
Create a config.json file:
{
"device_ips": ["192.168.1.100", "192.168.1.101"],
"predefined_ranges": [
{
"start": "192.168.1.1",
"end": "192.168.1.254"
}
],
"timeout": 3.0,
"max_workers": 50
}docker run -d \
--name shelly-manager-api \
-p 8000:8000 \
-v ./config.json:/app/config.json:ro \
-e HOST=0.0.0.0 \
-e PORT=8000 \
ghcr.io/jfmlima/shelly-manager-api:latestservices:
api:
image: ghcr.io/jfmlima/shelly-manager-api:latest
ports:
- "8000:8000"
volumes:
- ./config.json:/app/config.json:ro
environment:
- HOST=0.0.0.0
- PORT=8000
- DEBUG=false
restart: unless-stoppedhealthcheck:
test: ["CMD-SHELL", "curl -f http://localhost:8000/api/health || exit 1"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s# From project root
cd shelly-manager
# Install with development dependencies
uv sync --package shelly-manager-api --extra dev
# Run with auto-reload
uv run --package shelly-manager-api python -m api.main
# Run tests
uv run --package shelly-manager-api pytest packages/api/tests/ -v
# Run linting
uv run ruff check packages/api/
uv run mypy packages/api/src/apiThe API uses Litestar's built-in OpenAPI generation:
- Interactive Docs: http://localhost:8000/docs (Swagger UI)
- OpenAPI Spec: http://localhost:8000/schema/openapi.json
- Create Controller: Add to
packages/api/src/api/controllers/ - Define DTOs: Add request/response models to
packages/api/src/api/presentation/dto/ - Add Route: Register controller in
packages/api/src/api/main.py - Add Tests: Create tests in
packages/api/tests/
Example controller:
from litestar import Controller, get
from api.presentation.dto.responses import DeviceResponse
class DeviceController(Controller):
path = "/devices"
@get("/{device_ip:str}/status")
async def get_device_status(self, device_ip: str) -> DeviceResponse:
# Implementation here
pass# Run all API tests
make test-api
# Run specific test files
uv run --package shelly-manager-api pytest packages/api/tests/unit/controllers/ -v
# Run with coverage
uv run --package shelly-manager-api pytest packages/api/tests/ --cov=api --cov-report=htmlThe API follows Clean Architecture principles:
packages/api/src/api/
├── controllers/ # HTTP request handlers
├── dependencies/ # Dependency injection container
├── main.py # Application entry point
└── presentation/
├── dto/ # Data Transfer Objects
└── serializers/ # Response serialization
- Litestar: Modern async web framework
- Pydantic: Data validation and serialization
- uvicorn: ASGI server
- Core Package: Business logic and domain models
- Port already in use: Change
PORTenvironment variable - Config file not found: Ensure
config.jsonexists and is mounted - CORS errors: Configure CORS settings for your web UI domain
- Health check failures: Verify API is responding on configured port
Enable debug mode for detailed error messages:
docker run -p 8000:8000 \
-e DEBUG=true \
ghcr.io/jfmlima/shelly-manager-api:latest# View container logs
docker logs shelly-manager-api
# Follow logs in real-time
docker logs -f shelly-manager-api- Main Documentation: ../../README.md
- Development Guide: ../../DEVELOPMENT.md
- Core Package: ../core/README.md
- CLI Package: ../cli/README.md