diff --git a/generated/.openapi-generator/FILES b/generated/.openapi-generator/FILES index 0ea0904a..27ddbd5d 100644 --- a/generated/.openapi-generator/FILES +++ b/generated/.openapi-generator/FILES @@ -142,6 +142,4 @@ setup.cfg setup.py test-requirements.txt test/__init__.py -test/test_payload_template.py -test/test_payload_template_request.py tox.ini diff --git a/generated/docs/PayloadTemplate.md b/generated/docs/PayloadTemplate.md index a2c716c0..b2f39495 100644 --- a/generated/docs/PayloadTemplate.md +++ b/generated/docs/PayloadTemplate.md @@ -5,6 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **template** | **str** | | +**headers** | **{str: (str,)}, none_type** | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/generated/docs/PayloadTemplateRequest.md b/generated/docs/PayloadTemplateRequest.md index ff584274..83e8c3c3 100644 --- a/generated/docs/PayloadTemplateRequest.md +++ b/generated/docs/PayloadTemplateRequest.md @@ -5,6 +5,7 @@ Name | Type | Description | Notes ------------ | ------------- | ------------- | ------------- **template** | **str** | | +**headers** | **{str: (str,)}, none_type** | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] [[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) diff --git a/generated/groundlight_openapi_client/model/payload_template.py b/generated/groundlight_openapi_client/model/payload_template.py index 2cf74e03..a721bb4c 100644 --- a/generated/groundlight_openapi_client/model/payload_template.py +++ b/generated/groundlight_openapi_client/model/payload_template.py @@ -89,6 +89,10 @@ def openapi_types(): """ return { "template": (str,), # noqa: E501 + "headers": ( + {str: (str,)}, + none_type, + ), # noqa: E501 } @cached_property @@ -97,6 +101,7 @@ def discriminator(): attribute_map = { "template": "template", # noqa: E501 + "headers": "headers", # noqa: E501 } read_only_vars = {} @@ -142,6 +147,7 @@ def _from_openapi_data(cls, template, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) + headers ({str: (str,)}, none_type): [optional] # noqa: E501 """ _check_type = kwargs.pop("_check_type", True) @@ -230,6 +236,7 @@ def __init__(self, template, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) + headers ({str: (str,)}, none_type): [optional] # noqa: E501 """ _check_type = kwargs.pop("_check_type", True) diff --git a/generated/groundlight_openapi_client/model/payload_template_request.py b/generated/groundlight_openapi_client/model/payload_template_request.py index 7e34645e..3a0f12a2 100644 --- a/generated/groundlight_openapi_client/model/payload_template_request.py +++ b/generated/groundlight_openapi_client/model/payload_template_request.py @@ -93,6 +93,10 @@ def openapi_types(): """ return { "template": (str,), # noqa: E501 + "headers": ( + {str: (str,)}, + none_type, + ), # noqa: E501 } @cached_property @@ -101,6 +105,7 @@ def discriminator(): attribute_map = { "template": "template", # noqa: E501 + "headers": "headers", # noqa: E501 } read_only_vars = {} @@ -146,6 +151,7 @@ def _from_openapi_data(cls, template, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) + headers ({str: (str,)}, none_type): [optional] # noqa: E501 """ _check_type = kwargs.pop("_check_type", True) @@ -234,6 +240,7 @@ def __init__(self, template, *args, **kwargs): # noqa: E501 Animal class but this time we won't travel through its discriminator because we passed in _visited_composed_classes = (Animal,) + headers ({str: (str,)}, none_type): [optional] # noqa: E501 """ _check_type = kwargs.pop("_check_type", True) diff --git a/generated/model.py b/generated/model.py index fed5dfdf..767e43c9 100644 --- a/generated/model.py +++ b/generated/model.py @@ -1,6 +1,6 @@ # generated by datamodel-codegen: # filename: public-api.yaml -# timestamp: 2025-02-24T22:54:15+00:00 +# timestamp: 2025-02-25T19:28:25+00:00 from __future__ import annotations @@ -111,10 +111,12 @@ class NoteRequest(BaseModel): class PayloadTemplate(BaseModel): template: str + headers: Optional[Dict[str, str]] = None class PayloadTemplateRequest(BaseModel): template: constr(min_length=1) + headers: Optional[Dict[str, constr(min_length=1)]] = None class ROI(BaseModel): diff --git a/spec/public-api.yaml b/spec/public-api.yaml index 771b2077..d09fec91 100644 --- a/spec/public-api.yaml +++ b/spec/public-api.yaml @@ -1343,6 +1343,11 @@ components: properties: template: type: string + headers: + type: object + additionalProperties: + type: string + nullable: true required: - template PayloadTemplateRequest: @@ -1351,6 +1356,12 @@ components: template: type: string minLength: 1 + headers: + type: object + additionalProperties: + type: string + minLength: 1 + nullable: true required: - template ROI: diff --git a/src/groundlight/experimental_api.py b/src/groundlight/experimental_api.py index df9ce0b5..c464e299 100644 --- a/src/groundlight/experimental_api.py +++ b/src/groundlight/experimental_api.py @@ -188,11 +188,11 @@ def make_webhook_action( payload_template=payload_template, ) - def make_payload_template(self, template: str) -> PayloadTemplate: + def make_payload_template(self, template: str, headers: Optional[Dict[str, str]] = None) -> PayloadTemplate: """ Creates a PayloadTemplate object for use in creating alerts """ - return PayloadTemplate(template=template) + return PayloadTemplate(template=template, headers=headers) def create_alert( # pylint: disable=too-many-locals, too-many-arguments # noqa: PLR0913 self, @@ -282,7 +282,10 @@ def create_alert( # pylint: disable=too-many-locals, too-many-arguments # noqa url=str(webhook_action.url), include_image=webhook_action.include_image, payload_template=( - PayloadTemplateRequest(template=webhook_action.payload_template.template) + PayloadTemplateRequest( + template=webhook_action.payload_template.template, + headers=webhook_action.payload_template.headers, + ) if webhook_action.payload_template else None ), diff --git a/test/unit/test_actions.py b/test/unit/test_actions.py index eb6bf1ee..6d4686db 100644 --- a/test/unit/test_actions.py +++ b/test/unit/test_actions.py @@ -154,3 +154,42 @@ def test_create_alert_webhook_action_with_invalid_payload_template(gl_experiment with pytest.raises(ApiException) as e: gl_experimental.create_alert(det, f"test_alert_{name}", condition, webhook_actions=webhook_action) assert e.value.status == bad_request_exception_status_code + + +def test_create_alert_webhook_action_headers(gl_experimental: ExperimentalApi): + name = f"Test {datetime.utcnow()}" + det = gl_experimental.get_or_create_detector(name, "test_query") + condition = gl_experimental.make_condition("ANSWERED_CONSECUTIVELY", {"num_consecutive_labels": 1, "label": "YES"}) + + test_api_key = "test_api_key" + url = "https://example.com/webhook" + headers = { + "Authorization": f"Bearer {test_api_key}", + } + + template = """{"records": [{"fields": {"detector_id": "{{ detector_id }}" } }]}""" + + payload_template = {"template": template, "headers": headers} + webhook_action = gl_experimental.make_webhook_action( + url=url, include_image=False, payload_template=payload_template + ) + + alert = gl_experimental.create_alert( + det, + f"test_alert_{name}", + condition, + webhook_actions=webhook_action, + ) + + assert len(alert.webhook_action) == 1 + assert alert.webhook_action[0].payload_template.template == template + assert alert.webhook_action[0].payload_template.headers == headers + + +def test_create_invalid_payload_template_headers(gl_experimental: ExperimentalApi): + with pytest.raises(Exception) as e: + gl_experimental.make_payload_template( + '{"template": "This is a fine template"}', headers="bad headers" # type: ignore + ) + assert e.typename == "ValidationError" + assert "Input should be a valid dictionary" in str(e.value)