Jeroen SchweitzerandClaude Opus 4.5 3bb3b01dbd
Build and Push / release (push) Successful in 3s
Build and Push / build (push) Successful in 1m15s
fix: OIDC audience validation - use string not list
python-jose jwt.decode() requires audience as string or None, not list.
Now extract and validate audience from unverified claims first,
then use token's actual audience for JWT decode.

Fixes "audience must be a string or None" error.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 15:35:05 +01:00
2025-12-31 11:15:01 +01:00
2026-01-04 21:51:21 +01:00

Core Code API

Central API service providing infrastructure management, home automation, and utility endpoints for the homelab ecosystem.

Features

Infrastructure Management

  • Portainer Integration: Stack and container management
  • NPM Integration: Nginx Proxy Manager domain and certificate management
  • Service Control: Start/stop services with container orchestration

Home Automation (Housekeeping API)

  • Device Control: Turn on/off, toggle, and set brightness for smart devices
  • Scene Activation: Trigger Home Assistant scenes
  • Script Execution: Run Home Assistant scripts
  • Automation Management: Enable/disable automations
  • State History: Query device state changes over time
  • Area Discovery: List rooms and areas

Utilities

  • DNS Lookup: Query DNS records (A, AAAA, MX, TXT, CNAME, NS, SOA, PTR)
  • Health Checks: Service health monitoring with database connectivity status

Architecture

src/
├── config.py                      # Global application settings
├── logging_config.py              # Logging configuration
├── base_controller.py             # Base controller pattern
├── main.py                        # FastAPI application entry point
├── auth/
│   └── oidc.py                    # OIDC authentication
├── clients/
│   ├── homeassistant_client.py    # Home Assistant REST client
│   ├── npm_client.py              # Nginx Proxy Manager client
│   └── portainer_client.py        # Portainer API client
├── controllers/
│   ├── health_controller.py       # Health endpoints
│   ├── housekeeping_controller.py # Home automation endpoints
│   ├── infrastructure_controller.py # Infrastructure management
│   ├── static_controller.py       # Static file serving
│   └── tools_controller.py        # DNS and utility tools
└── dns/
    ├── service.py                 # DNS lookup service
    └── exceptions.py              # DNS-specific exceptions

API Endpoints

Health

  • GET / - Service info and documentation links
  • GET /health - Basic health status
  • GET /health/full - Detailed component health
  • GET /health/diagnostics - Full diagnostic information

Infrastructure (/infrastructure)

  • GET /infrastructure/health - Portainer/NPM connection status
  • GET /infrastructure/services - List all services (stacks)
  • GET /infrastructure/services/{name} - Get service details
  • GET /infrastructure/services/{name}/status - Service status
  • POST /infrastructure/services/{name}/start - Start service
  • POST /infrastructure/services/{name}/stop - Stop service
  • GET /infrastructure/containers - List containers
  • GET /infrastructure/containers/{name} - Container details
  • GET /infrastructure/containers/{name}/logs - Container logs
  • GET /infrastructure/ports - List exposed ports
  • GET /infrastructure/domains - List proxy domains
  • GET /infrastructure/widget-data - Dashboard widget data

Housekeeping (/housekeeping)

  • GET /housekeeping/health - Home Assistant connection status
  • GET /housekeeping/devices - List controllable devices
  • GET /housekeeping/devices/{entity_id} - Device details
  • POST /housekeeping/devices/{entity_id}/control - Control device
  • GET /housekeeping/scenes - List scenes
  • POST /housekeeping/scenes/{scene_id}/activate - Activate scene
  • GET /housekeeping/scripts - List scripts
  • POST /housekeeping/scripts/{script_id}/run - Run script
  • GET /housekeeping/automations - List automations
  • POST /housekeeping/automations/{automation_id}/toggle - Toggle automation
  • GET /housekeeping/history - State history
  • GET /housekeeping/areas - List areas/rooms

Tools (/tools)

  • POST /tools/dns/lookup - DNS record lookup

Development

Requirements

  • Python 3.12+
  • Docker (for containerized deployment)

Local Development

# Install dependencies
pip install -r requirements.txt

# Run locally
uvicorn src.main:app --reload --host 0.0.0.0 --port 8083

Running Tests

# Run all tests
pytest

# Run with coverage
pytest --cov=src --cov-report=term-missing

# Run specific test file
pytest tests/test_housekeeping.py -v

Adding New Dependencies

Dependencies use major version pinning (~=) for automatic patch updates while preventing breaking changes.

  1. Add package to requirements.txt with major version constraint:

    package-name~=1.2.0  # Allows 1.2.x, blocks 1.3.0
    
  2. Restart the container to install:

    docker restart core-api
    

Docker Build

# Build image
docker build -t core-code:latest .

# Run container
docker run -p 8083:8083 core-code:latest

Deployment

Portainer Stack

  1. Navigate to Portainer UI
  2. Go to StacksAdd Stack
  3. Name: core-code
  4. Upload stacks/core-code.yml or paste contents
  5. Deploy

Environment Variables

Variable Description Default
PORTAINER_URL Portainer API URL http://localhost:9000
PORTAINER_API_KEY Portainer API key -
NPM_URL Nginx Proxy Manager URL http://localhost:81
NPM_EMAIL NPM admin email -
NPM_PASSWORD NPM admin password -
HOMEASSISTANT_URL Home Assistant URL http://localhost:8123
HOMEASSISTANT_TOKEN HA long-lived access token -
OIDC_ENABLED Enable OIDC auth false
OIDC_ISSUERS OIDC issuer URLs (comma-separated) See config.py
OIDC_AUDIENCES OIDC audiences (comma-separated) See config.py

API Documentation

Once deployed, access documentation at:

Health Checks

  • Basic: GET /health - Fast liveness check for container orchestration
  • Full: GET /health/full - Returns database status (503 if unhealthy)
  • Diagnostics: GET /health/diagnostics - Service info and configuration

Security

  • Runs as non-root user (uid 1000)
  • OIDC authentication support via Authentik
  • CORS configured for same-network access
  • Admin endpoints require authentication when OIDC enabled

License

Internal use only.

S
Description
the core system management api for the tower-of-joy system.
Readme
429 KiB
2026-01-08 21:49:05 +01:00
Languages
Python 95.9%
HTML 3.2%
Shell 0.4%
Makefile 0.4%