From 6d831b88d4fb2ba029b2321a187fca47c9442bb9 Mon Sep 17 00:00:00 2001 From: Vincent Pochet Date: Thu, 24 Oct 2024 17:52:53 +0200 Subject: [PATCH] feat(felixible aggregation): Add documentation for expression evaluation endpoint --- .../billable_metrics/clients.py | 20 +++++++++-- lago_python_client/models/__init__.py | 3 ++ lago_python_client/models/billable_metric.py | 14 +++++++- .../billable_metric_evaluate_expression.json | 5 +++ tests/test_billable_metric_client.py | 34 +++++++++++++++++++ 5 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 tests/fixtures/billable_metric_evaluate_expression.json diff --git a/lago_python_client/billable_metrics/clients.py b/lago_python_client/billable_metrics/clients.py index 568a8d5..4473a08 100644 --- a/lago_python_client/billable_metrics/clients.py +++ b/lago_python_client/billable_metrics/clients.py @@ -8,8 +8,9 @@ FindCommandMixin, UpdateCommandMixin, ) -from ..models.billable_metric import BillableMetricResponse - +from ..models.billable_metric import BillableMetricEvaluateExpression, BillableMetricEvaluateExpressionResponse, BillableMetricResponse +from ..services.request import make_headers, make_url, send_post_request +from ..services.response import Response, prepare_object_response, get_response_data class BillableMetricClient( CreateCommandMixin[BillableMetricResponse], @@ -22,3 +23,18 @@ class BillableMetricClient( API_RESOURCE: ClassVar[str] = "billable_metrics" RESPONSE_MODEL: ClassVar[Type[BillableMetricResponse]] = BillableMetricResponse ROOT_NAME: ClassVar[str] = "billable_metric" + + + def evaluate_expression(self, input_object: BillableMetricEvaluateExpression) -> BillableMetricEvaluateExpressionResponse: + api_response: Response = send_post_request( + url=make_url( + origin=self.base_url, + path_parts=(self.API_RESOURCE, "evaluate_expression"), + ), + headers=make_headers(api_key=self.api_key), + ) + + return prepare_object_response( + response_model=BillableMetricEvaluateExpressionResponse, + data=get_response_data(response=api_response, key='expression_result'), + ) diff --git a/lago_python_client/models/__init__.py b/lago_python_client/models/__init__.py index fe98c20..13730de 100644 --- a/lago_python_client/models/__init__.py +++ b/lago_python_client/models/__init__.py @@ -3,6 +3,9 @@ BillableMetric as BillableMetric, BillableMetricFilter as BillableMetricFilter, BillableMetricFilters as BillableMetricFilters, + BillableMetricEvaluateExpressionEvent as BillableMetricEvaluateExpressionEvent, + BillableMetricEvaluateExpression as BillableMetricEvaluateExpression, + BillableMetricEvaluateExpressionResponse as BillableMetricEvaluateExpressionResponse, ) from .charge import ( Charge as Charge, diff --git a/lago_python_client/models/billable_metric.py b/lago_python_client/models/billable_metric.py index e81828e..8ef18db 100644 --- a/lago_python_client/models/billable_metric.py +++ b/lago_python_client/models/billable_metric.py @@ -1,4 +1,4 @@ -from typing import List, Optional +from typing import Any, Dict, List, Optional, Union from lago_python_client.base_model import BaseModel @@ -41,3 +41,15 @@ class BillableMetricResponse(BaseResponseModel): active_subscriptions_count: int draft_invoices_count: int plans_count: int + +class BillableMetricEvaluateExpressionEvent(BaseModel): + code: Optional[str] + timestamp: Optional[Union[str, int]] + properties: Optional[Dict[str, Any]] + +class BillableMetricEvaluateExpression(BaseModel): + expression: str + event: BillableMetricEvaluateExpressionEvent + +class BillableMetricEvaluateExpressionResponse(BaseResponseModel): + value: Union[str, int, float] diff --git a/tests/fixtures/billable_metric_evaluate_expression.json b/tests/fixtures/billable_metric_evaluate_expression.json new file mode 100644 index 0000000..0f43e3c --- /dev/null +++ b/tests/fixtures/billable_metric_evaluate_expression.json @@ -0,0 +1,5 @@ +{ + "expression_result": { + "value": "2.0" + } +} diff --git a/tests/test_billable_metric_client.py b/tests/test_billable_metric_client.py index 787f5f0..c9651a5 100644 --- a/tests/test_billable_metric_client.py +++ b/tests/test_billable_metric_client.py @@ -9,6 +9,8 @@ BillableMetric, BillableMetricFilter, BillableMetricFilters, + BillableMetricEvaluateExpression, + BillableMetricEvaluateExpressionEvent, ) @@ -25,6 +27,17 @@ def billable_metric_object(): ) +def billable_metric_evaluate_expression_object(): + return BillableMetricEvaluateExpression( + expression="round(event.properties.value * event.properties.units)", + event=BillableMetricEvaluateExpressionEvent( + code="event_code", + timestamp=1651240791, + properties={"value": 10, "units": 2}, + ) + ) + + def filters(): return BillableMetricFilters(__root__=[BillableMetricFilter(key="country", values=["france", "italy", "spain"])]) @@ -45,6 +58,14 @@ def mock_collection_response(): return billable_metric_response.read() +def mock_evaluate_expression_response(): + this_dir = os.path.dirname(os.path.abspath(__file__)) + data_path = os.path.join(this_dir, "fixtures/billable_metric_evaluate_expression.json") + + with open(data_path, "rb") as evaluate_expression_response: + return evaluate_expression_response.read() + + def test_valid_create_billable_metric_request(httpx_mock: HTTPXMock): client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") @@ -204,3 +225,16 @@ def test_invalid_find_all_billable_metric_request(httpx_mock: HTTPXMock): with pytest.raises(LagoApiError): client.billable_metrics.find_all() + + +def test_valid_evaluate_billable_metric_expression(httpx_mock: HTTPXMock): + client = Client(api_key="886fe239-927d-4072-ab72-6dd345e8dd0d") + + httpx_mock.add_response( + method="POST", + url="https://api.getlago.com/api/v1/billable_metrics/evaluate_expression", + content=mock_evaluate_expression_response(), + ) + response = client.billable_metrics.evaluate_expression(billable_metric_evaluate_expression_object()) + + assert response.value == "2.0"