Skip to content

Commit

Permalink
feat(analytics): Add analytics resources
Browse files Browse the repository at this point in the history
  • Loading branch information
ivannovosad committed Nov 15, 2023
1 parent ec9de82 commit 30d23b4
Show file tree
Hide file tree
Showing 21 changed files with 408 additions and 0 deletions.
20 changes: 20 additions & 0 deletions lago_python_client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@
from .events.clients import EventClient
from .fees.clients import FeeClient
from .functools_ext import callable_cached_property
from .gross_revenues.clients import GrossRevenueClient
from .invoices.clients import InvoiceClient
from .invoiced_usages.clients import InvoicedUsageClient
from .mrrs.clients import MrrClient
from .organizations.clients import OrganizationClient
from .outstanding_invoices.clients import OutstandingInvoiceClient
from .plans.clients import PlanClient
from .subscriptions.clients import SubscriptionClient
from .taxes.clients import TaxClient
Expand Down Expand Up @@ -71,14 +75,30 @@ def events(self) -> EventClient:
def fees(self) -> FeeClient:
return FeeClient(self.base_api_url, self.api_key)

@callable_cached_property
def gross_revenues(self) -> GrossRevenueClient:
return GrossRevenueClient(self.base_api_url, self.api_key)

@callable_cached_property
def invoices(self) -> InvoiceClient:
return InvoiceClient(self.base_api_url, self.api_key)

@callable_cached_property
def invoiced_usages(self) -> InvoicedUsageClient:
return InvoicedUsageClient(self.base_api_url, self.api_key)

@callable_cached_property
def mrrs(self) -> MrrClient:
return MrrClient(self.base_api_url, self.api_key)

@callable_cached_property
def organizations(self) -> OrganizationClient:
return OrganizationClient(self.base_api_url, self.api_key)

@callable_cached_property
def outstanding_invoices(self) -> OutstandingInvoiceClient:
return OutstandingInvoiceClient(self.base_api_url, self.api_key)

@callable_cached_property
def plans(self) -> PlanClient:
return PlanClient(self.base_api_url, self.api_key)
Expand Down
Empty file.
39 changes: 39 additions & 0 deletions lago_python_client/gross_revenues/clients.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import sys
from typing import Any, ClassVar, Type, Union

from ..base_client import BaseClient
from ..mixins import FindAllCommandMixin
from ..models.gross_revenue import GrossRevenueResponse
from ..services.request import make_headers, make_url, send_get_request
from ..services.response import get_response_data, prepare_index_response, Response

if sys.version_info >= (3, 9):
from collections.abc import Mapping
else:
from typing import Mapping


class GrossRevenueClient(
FindAllCommandMixin[GrossRevenueResponse],
BaseClient,
):
API_RESOURCE: ClassVar[str] = 'gross_revenues'
RESPONSE_MODEL: ClassVar[Type[GrossRevenueResponse]] = GrossRevenueResponse
ROOT_NAME: ClassVar[str] = 'gross_revenue'

def find_all(self, options: Mapping[str, Union[int, str]] = {}) -> Mapping[str, Any]:
api_response: Response = send_get_request(
url=make_url(
origin=self.base_url,
path_parts=('analytics', 'gross_revenue'),
query_pairs=options,
),
headers=make_headers(api_key=self.api_key),
)

# Process response data
return prepare_index_response(
api_resource=self.API_RESOURCE,
response_model=self.RESPONSE_MODEL,
data=get_response_data(response=api_response),
)
Empty file.
39 changes: 39 additions & 0 deletions lago_python_client/invoiced_usages/clients.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import sys
from typing import Any, ClassVar, Type, Union

from ..base_client import BaseClient
from ..mixins import FindAllCommandMixin
from ..models.invoiced_usage import InvoicedUsageResponse
from ..services.request import make_headers, make_url, send_get_request
from ..services.response import get_response_data, prepare_index_response, Response

if sys.version_info >= (3, 9):
from collections.abc import Mapping
else:
from typing import Mapping


class InvoicedUsageClient(
FindAllCommandMixin[InvoicedUsageResponse],
BaseClient,
):
API_RESOURCE: ClassVar[str] = 'invoiced_usages'
RESPONSE_MODEL: ClassVar[Type[InvoicedUsageResponse]] = InvoicedUsageResponse
ROOT_NAME: ClassVar[str] = 'invoiced_usage'

def find_all(self, options: Mapping[str, Union[int, str]] = {}) -> Mapping[str, Any]:
api_response: Response = send_get_request(
url=make_url(
origin=self.base_url,
path_parts=('analytics', 'invoiced_usage'),
query_pairs=options,
),
headers=make_headers(api_key=self.api_key),
)

# Process response data
return prepare_index_response(
api_resource=self.API_RESOURCE,
response_model=self.RESPONSE_MODEL,
data=get_response_data(response=api_response),
)
13 changes: 13 additions & 0 deletions lago_python_client/models/gross_revenue.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import List, Optional

from ..base_model import BaseModel, BaseResponseModel


class GrossRevenueResponse(BaseResponseModel):
amount_cents: Optional[int]
currency: Optional[str]
month: str


class GrossRevenuesResponse(BaseResponseModel):
__root__: List[GrossRevenueResponse]
14 changes: 14 additions & 0 deletions lago_python_client/models/invoiced_usage.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from typing import List, Optional

from ..base_model import BaseModel, BaseResponseModel


class InvoicedUsageResponse(BaseResponseModel):
amount_cents: int
code: Optional[str]
currency: str
month: str


class InvoicedUsagesResponse(BaseResponseModel):
__root__: List[InvoicedUsageResponse]
13 changes: 13 additions & 0 deletions lago_python_client/models/mrr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from typing import List, Optional

from ..base_model import BaseModel, BaseResponseModel


class MrrResponse(BaseResponseModel):
amount_cents: Optional[int]
currency: Optional[str]
month: str


class MrrsResponse(BaseResponseModel):
__root__: List[MrrResponse]
15 changes: 15 additions & 0 deletions lago_python_client/models/outstanding_invoice.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from typing import List, Optional

from ..base_model import BaseModel, BaseResponseModel


class OutstandingInvoiceResponse(BaseResponseModel):
amount_cents: int
currency: Optional[str]
month: str
invoices_count: int
payment_status: Optional[str]


class OutstandingInvoicesResponse(BaseResponseModel):
__root__: List[OutstandingInvoiceResponse]
Empty file.
39 changes: 39 additions & 0 deletions lago_python_client/mrrs/clients.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import sys
from typing import Any, ClassVar, Type, Union

from ..base_client import BaseClient
from ..mixins import FindAllCommandMixin
from ..models.mrr import MrrResponse
from ..services.request import make_headers, make_url, send_get_request
from ..services.response import get_response_data, prepare_index_response, Response

if sys.version_info >= (3, 9):
from collections.abc import Mapping
else:
from typing import Mapping


class MrrClient(
FindAllCommandMixin[MrrResponse],
BaseClient,
):
API_RESOURCE: ClassVar[str] = 'mrrs'
RESPONSE_MODEL: ClassVar[Type[MrrResponse]] = MrrResponse
ROOT_NAME: ClassVar[str] = 'mrr'

def find_all(self, options: Mapping[str, Union[int, str]] = {}) -> Mapping[str, Any]:
api_response: Response = send_get_request(
url=make_url(
origin=self.base_url,
path_parts=('analytics', 'mrr'),
query_pairs=options,
),
headers=make_headers(api_key=self.api_key),
)

# Process response data
return prepare_index_response(
api_resource=self.API_RESOURCE,
response_model=self.RESPONSE_MODEL,
data=get_response_data(response=api_response),
)
Empty file.
39 changes: 39 additions & 0 deletions lago_python_client/outstanding_invoices/clients.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import sys
from typing import Any, ClassVar, Type, Union

from ..base_client import BaseClient
from ..mixins import FindAllCommandMixin
from ..models.outstanding_invoice import OutstandingInvoiceResponse
from ..services.request import make_headers, make_url, send_get_request
from ..services.response import get_response_data, prepare_index_response, Response

if sys.version_info >= (3, 9):
from collections.abc import Mapping
else:
from typing import Mapping


class OutstandingInvoiceClient(
FindAllCommandMixin[OutstandingInvoiceResponse],
BaseClient,
):
API_RESOURCE: ClassVar[str] = 'outstanding_invoices'
RESPONSE_MODEL: ClassVar[Type[OutstandingInvoiceResponse]] = OutstandingInvoiceResponse
ROOT_NAME: ClassVar[str] = 'outstanding_invoice'

def find_all(self, options: Mapping[str, Union[int, str]] = {}) -> Mapping[str, Any]:
api_response: Response = send_get_request(
url=make_url(
origin=self.base_url,
path_parts=('analytics', self.API_RESOURCE),
query_pairs=options,
),
headers=make_headers(api_key=self.api_key),
)

# Process response data
return prepare_index_response(
api_resource=self.API_RESOURCE,
response_model=self.RESPONSE_MODEL,
data=get_response_data(response=api_response),
)
15 changes: 15 additions & 0 deletions tests/fixtures/gross_revenue_index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"gross_revenues": [
{
"month": "2023-11-01T00:00:00.000Z",
"amount_cents": 100,
"currency": "EUR"
},
{
"month": "2023-12-01T00:00:00.000Z",
"amount_cents": 200,
"currency": "USD"
}
],
"meta": {}
}
17 changes: 17 additions & 0 deletions tests/fixtures/invoiced_usage_index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"invoiced_usages": [
{
"month": "2023-11-01T00:00:00.000Z",
"amount_cents": 100,
"currency": "EUR",
"code": "code"
},
{
"month": "2023-12-01T00:00:00.000Z",
"amount_cents": 200,
"currency": "USD",
"code": "code"
}
],
"meta": {}
}
15 changes: 15 additions & 0 deletions tests/fixtures/mrr_index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"mrrs": [
{
"month": "2023-11-01T00:00:00.000Z",
"amount_cents": 100,
"currency": "EUR"
},
{
"month": "2023-12-01T00:00:00.000Z",
"amount_cents": 200,
"currency": "USD"
}
],
"meta": {}
}
19 changes: 19 additions & 0 deletions tests/fixtures/outstanding_invoice_index.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"outstanding_invoices": [
{
"month": "2023-11-01T00:00:00.000Z",
"amount_cents": 100,
"currency": "EUR",
"invoices_count": 10,
"payment_status": "pending"
},
{
"month": "2023-12-01T00:00:00.000Z",
"amount_cents": 200,
"currency": "USD",
"invoices_count": 5,
"payment_status": "pending"
}
],
"meta": {}
}
27 changes: 27 additions & 0 deletions tests/test_gross_revenue_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os

import pytest
from pytest_httpx import HTTPXMock

from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models.gross_revenue import GrossRevenueResponse


def mock_collection_response():
current_dir = os.path.dirname(os.path.abspath(__file__))
data_path = os.path.join(current_dir, 'fixtures/gross_revenue_index.json')

with open(data_path, 'rb') as gross_revenues_response:
return gross_revenues_response.read()


def test_valid_find_all_gross_revenues_request(httpx_mock: HTTPXMock):
client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')

httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/analytics/gross_revenue', content=mock_collection_response())
response = client.gross_revenues.find_all()

assert response['gross_revenues'][0].currency == 'EUR'
assert response['gross_revenues'][0].amount_cents == 100
assert response['gross_revenues'][0].month == '2023-11-01T00:00:00.000Z'
28 changes: 28 additions & 0 deletions tests/test_invoiced_usage_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import os

import pytest
from pytest_httpx import HTTPXMock

from lago_python_client.client import Client
from lago_python_client.exceptions import LagoApiError
from lago_python_client.models.invoiced_usage import InvoicedUsageResponse


def mock_collection_response():
current_dir = os.path.dirname(os.path.abspath(__file__))
data_path = os.path.join(current_dir, 'fixtures/invoiced_usage_index.json')

with open(data_path, 'rb') as invoiced_usages_response:
return invoiced_usages_response.read()


def test_valid_find_all_invoiced_usages_request(httpx_mock: HTTPXMock):
client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')

httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/analytics/invoiced_usage', content=mock_collection_response())
response = client.invoiced_usages.find_all()

assert response['invoiced_usages'][0].currency == 'EUR'
assert response['invoiced_usages'][0].amount_cents == 100
assert response['invoiced_usages'][0].code == 'code'
assert response['invoiced_usages'][0].month == '2023-11-01T00:00:00.000Z'
Loading

0 comments on commit 30d23b4

Please sign in to comment.