Skip to content

Commit 3e90010

Browse files
authored
Merge pull request #41 from praekeltfoundation/updates-for-mcxp
Fix web app loading the model and ignore statuses from turn payload
2 parents 6b5e8e9 + f6ce695 commit 3e90010

6 files changed

Lines changed: 55 additions & 20 deletions

File tree

src/application.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from pydantic import ValidationError
77

88
from src.config import load_config
9-
from src.tasks import build_classify_and_update_chain
9+
from src.queueing import build_classify_and_update_chain
1010
from src.turn_webhook import TurnWebhook
1111
from src.utils import validate_turn_signature
1212

src/queueing.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
"""Celery task submission helpers for producer processes."""
2+
3+
from celery import chain
4+
5+
from src.celery_app import celery_app
6+
7+
CLASSIFY_TURN_MESSAGE_TASK = "src.tasks.classify_turn_message"
8+
UPDATE_TURN_MESSAGE_LABEL_TASK = "src.tasks.update_turn_message_label"
9+
10+
11+
def build_classify_and_update_chain(message_id: str, message_text: str):
12+
"""Build a Celery chain without importing worker-only task modules."""
13+
return chain(
14+
celery_app.signature(
15+
CLASSIFY_TURN_MESSAGE_TASK,
16+
args=(message_id, message_text),
17+
),
18+
celery_app.signature(UPDATE_TURN_MESSAGE_LABEL_TASK),
19+
)

src/tasks.py

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
1-
"""Celery tasks for async processing."""
1+
"""Celery task implementations for worker processes."""
22

33
import logging
44
from pathlib import Path
55

6-
from celery import chain
7-
86
from src.celery_app import celery_app
97
from src.intent_classifier import IntentClassifier
108
from src.turn_client import TurnAPIClient, TurnAPIServerError
@@ -140,11 +138,3 @@ def update_turn_message_label(classification: dict) -> dict:
140138
exc_info=True,
141139
)
142140
raise
143-
144-
145-
def build_classify_and_update_chain(message_id: str, message_text: str):
146-
"""Build a Celery chain that classifies then updates the Turn label."""
147-
return chain(
148-
classify_turn_message.s(message_id, message_text),
149-
update_turn_message_label.s(),
150-
)

src/turn_webhook.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from pydantic import BaseModel, ConfigDict
1+
from pydantic import BaseModel, ConfigDict, Field
22

33

44
class TurnBaseModel(BaseModel):
@@ -16,4 +16,5 @@ class TurnMessage(TurnBaseModel):
1616

1717

1818
class TurnWebhook(TurnBaseModel):
19-
messages: list[TurnMessage]
19+
messages: list[TurnMessage] = Field(default_factory=list)
20+
statuses: list[dict] = Field(default_factory=list)

tests/test_application.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ def test_nlu_invalid_payload(client):
105105
""""""
106106

107107
body = json.dumps(
108-
{"not_messages": []}, separators=(",", ":"), sort_keys=True
108+
{"messages": "not-a-list"}, separators=(",", ":"), sort_keys=True
109109
).encode()
110110
signature = _sign_payload(body, app.config["TURN_HMAC_SECRET"])
111111

@@ -117,3 +117,31 @@ def test_nlu_invalid_payload(client):
117117
)
118118
assert response.status_code == 400
119119
assert response.json["error"] == "invalid payload"
120+
121+
122+
def test_nlu_status_only_payload_is_ignored(client, mocker):
123+
"""Status webhooks should be accepted and ignored."""
124+
125+
mock_build_chain = mocker.patch("src.application.build_classify_and_update_chain")
126+
127+
payload = {
128+
"statuses": [
129+
{
130+
"id": "wamid.HBgLMjc4MzYzNzg1MzEVAgARGBI2QTBBOTM1MDdFNUEwRDJDOEMA",
131+
"status": "delivered",
132+
"timestamp": "1773842339",
133+
}
134+
]
135+
}
136+
body = json.dumps(payload, separators=(",", ":"), sort_keys=True).encode()
137+
signature = _sign_payload(body, app.config["TURN_HMAC_SECRET"])
138+
139+
response = client.post(
140+
"/nlu/",
141+
data=body,
142+
content_type="application/json",
143+
headers={"X-Turn-Hook-Signature": signature},
144+
)
145+
assert response.status_code == 200
146+
assert response.json == {"status": "ignored", "count": 0}
147+
mock_build_chain.assert_not_called()

tests/test_tasks.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,8 @@
33
import pytest
44

55
from src.celery_app import celery_app
6-
from src.tasks import (
7-
build_classify_and_update_chain,
8-
classify_turn_message,
9-
update_turn_message_label,
10-
)
6+
from src.queueing import build_classify_and_update_chain
7+
from src.tasks import classify_turn_message, update_turn_message_label
118
from src.turn_client import TurnAPIClientError, TurnAPIServerError
129

1310
# Enable eager mode for all tests in this module (run tasks synchronously)

0 commit comments

Comments
 (0)