jpmschweitzerandClaude 6695215aeb build(make): prove setup worked instead of assuming pip's exit code (T-47)
pip install exits 0 whether the result is usable or not — that is the D-24
shape exactly, a step whose job is to not fail. On 2026-08-09 the venv here
existed and pip had already succeeded, but sqlalchemy was declared in
requirements.txt and not installed. That surfaced as 11 pytest collection
errors that read as broken imports rather than as an environment problem.

setup now ends with `pytest --collect-only tests/`, which exercises every
import the suite touches without running anything. pip check was considered
as a cheaper alternative and rejected: it only checks the installed set's
internal consistency against itself, so it would not have caught this case —
sqlalchemy was still present as another package's transitive dependency even
after being dropped from requirements.txt. collect-only checks declared vs.
actually usable directly, which is the axis that broke.

Verified: two clean runs (33.5s cold, 5.7s idempotent re-run, second changes
nothing). Reproduced the original failure by uninstalling sqlalchemy from an
otherwise-correct venv — collect-only alone then exits 2 with 11 collection
errors; make setup against that same state reinstalls it and exits 0 with
381/381 collected.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-08-17 12:05:28 +02: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%