Skip to content

Commit

Permalink
feat(felixible aggregation): Expose expression in API (#281)
Browse files Browse the repository at this point in the history
* feat(felixible aggregation): Expose expression in API

* feat(felixible aggregation): Add documentation for expression evaluation endpoint
  • Loading branch information
vincent-pochet authored Nov 4, 2024
1 parent 623e89a commit a544990
Show file tree
Hide file tree
Showing 7 changed files with 87 additions and 7 deletions.
24 changes: 23 additions & 1 deletion lago_python_client/billable_metrics/clients.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
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(
Expand All @@ -22,3 +28,19 @@ 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"),
)
3 changes: 3 additions & 0 deletions lago_python_client/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
19 changes: 18 additions & 1 deletion lago_python_client/models/billable_metric.py
Original file line number Diff line number Diff line change
@@ -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

Expand All @@ -21,6 +21,7 @@ class BillableMetric(BaseModel):
recurring: Optional[bool]
aggregation_type: Optional[str]
weighted_interval: Optional[str]
expression: Optional[str]
field_name: Optional[str]
filters: Optional[BillableMetricFilters]

Expand All @@ -33,9 +34,25 @@ class BillableMetricResponse(BaseResponseModel):
recurring: Optional[bool]
aggregation_type: Optional[str]
weighted_interval: Optional[str]
expression: Optional[str]
field_name: Optional[str]
created_at: str
filters: BillableMetricFilters
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]
7 changes: 2 additions & 5 deletions tests/fixtures/billable_metric.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,13 @@
"aggregation_type": "sum_agg",
"weighted_interval": null,
"recurring": false,
"expression": "1 + 2",
"field_name": "amount_sum",
"created_at": "2022-04-29T08:59:51Z",
"filters": [
{
"key": "country",
"values": [
"france",
"italy",
"spain"
]
"values": ["france", "italy", "spain"]
}
],
"active_subscriptions_count": 0,
Expand Down
5 changes: 5 additions & 0 deletions tests/fixtures/billable_metric_evaluate_expression.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"expression_result": {
"value": "2.0"
}
}
2 changes: 2 additions & 0 deletions tests/fixtures/billable_metric_index.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"aggregation_type": "sum_agg",
"weighted_interval": null,
"recurring": false,
"expression": "1 + 2",
"field_name": "amount_sum",
"created_at": "2022-04-29T08:59:51Z",
"filters": [],
Expand All @@ -23,6 +24,7 @@
"aggregation_type": "sum_agg",
"weighted_interval": null,
"recurring": false,
"expression": "1 + 2",
"field_name": "amount_sum",
"created_at": "2022-04-30T08:59:51Z",
"filters": [],
Expand Down
34 changes: 34 additions & 0 deletions tests/test_billable_metric_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
BillableMetric,
BillableMetricFilter,
BillableMetricFilters,
BillableMetricEvaluateExpression,
BillableMetricEvaluateExpressionEvent,
)


Expand All @@ -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"])])

Expand All @@ -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")

Expand Down Expand Up @@ -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"

0 comments on commit a544990

Please sign in to comment.