Add Home Assistant inbound gateway
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, Depends, Request, status
|
||||
from fastapi.responses import PlainTextResponse, Response
|
||||
from pydantic import ValidationError
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.dependencies import get_db
|
||||
from app.schemas.homeassistant import HomeAssistantPublishEnvelope
|
||||
from app.services.homeassistant_inbound import (
|
||||
UnsupportedHomeAssistantMessage,
|
||||
handle_homeassistant_message,
|
||||
)
|
||||
|
||||
router = APIRouter(tags=["homeassistant"])
|
||||
logger = logging.getLogger(__name__)
|
||||
BAD_REQUEST_MESSAGE = "bad request"
|
||||
INTERNAL_SERVER_ERROR_MESSAGE = "internal server error"
|
||||
|
||||
|
||||
@router.post("/homeassistant/publish")
|
||||
async def publish_from_homeassistant(
|
||||
request: Request, db: Session = Depends(get_db)
|
||||
) -> Response:
|
||||
try:
|
||||
raw_payload = await request.body()
|
||||
data = json.loads(raw_payload)
|
||||
envelope = HomeAssistantPublishEnvelope.model_validate(data)
|
||||
handle_homeassistant_message(db, envelope)
|
||||
except json.JSONDecodeError as exc:
|
||||
logger.warning("Rejected Home Assistant publish request due to invalid JSON: %s", exc)
|
||||
return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=status.HTTP_400_BAD_REQUEST)
|
||||
except ValidationError as exc:
|
||||
logger.warning(
|
||||
"Rejected Home Assistant publish request due to validation failure: %s", exc
|
||||
)
|
||||
return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=status.HTTP_400_BAD_REQUEST)
|
||||
except UnsupportedHomeAssistantMessage as exc:
|
||||
logger.warning("Home Assistant publish target/action unsupported: %s", exc)
|
||||
return PlainTextResponse(
|
||||
INTERNAL_SERVER_ERROR_MESSAGE,
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
)
|
||||
except ValueError as exc:
|
||||
logger.warning("Rejected Home Assistant publish request due to invalid content: %s", exc)
|
||||
return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
return Response(status_code=status.HTTP_200_OK)
|
||||
@@ -1,7 +1,7 @@
|
||||
import json
|
||||
import logging
|
||||
|
||||
from fastapi import APIRouter, Depends, Request
|
||||
from fastapi import APIRouter, Depends, Request, status
|
||||
from fastapi.responses import PlainTextResponse, Response
|
||||
from pydantic import ValidationError
|
||||
from sqlalchemy.orm import Session
|
||||
@@ -24,12 +24,12 @@ async def create_location_record(request: Request, db: Session = Depends(get_db)
|
||||
record_location(db, payload)
|
||||
except json.JSONDecodeError as exc:
|
||||
logger.warning("Rejected location request due to invalid JSON: %s", exc)
|
||||
return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=400)
|
||||
return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=status.HTTP_400_BAD_REQUEST)
|
||||
except ValidationError as exc:
|
||||
logger.warning("Rejected location request due to payload validation failure: %s", exc)
|
||||
return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=400)
|
||||
return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=status.HTTP_400_BAD_REQUEST)
|
||||
except ValueError as exc:
|
||||
logger.warning("Rejected location request due to invalid numeric input: %s", exc)
|
||||
return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=400)
|
||||
return PlainTextResponse(BAD_REQUEST_MESSAGE, status_code=status.HTTP_400_BAD_REQUEST)
|
||||
|
||||
return Response(status_code=200)
|
||||
return Response(status_code=status.HTTP_200_OK)
|
||||
|
||||
Reference in New Issue
Block a user