lago-python-client 0.30.0__tar.gz → 0.35.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/PKG-INFO +1 -1
  2. lago-python-client-0.35.0/lago_python_client/applied_taxes/clients.py +54 -0
  3. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/client.py +10 -0
  4. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/invoices/clients.py +8 -2
  5. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/__init__.py +4 -1
  6. lago-python-client-0.35.0/lago_python_client/models/applied_tax.py +18 -0
  7. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/charge.py +4 -2
  8. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/credit.py +1 -0
  9. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/credit_note.py +15 -11
  10. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/fee.py +4 -0
  11. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/invoice.py +34 -4
  12. lago-python-client-0.35.0/lago_python_client/models/tax.py +24 -0
  13. lago-python-client-0.35.0/lago_python_client/taxes/clients.py +18 -0
  14. lago-python-client-0.35.0/lago_python_client/version.py +1 -0
  15. lago-python-client-0.35.0/lago_python_client/webhooks/__init__.py +0 -0
  16. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client.egg-info/PKG-INFO +1 -1
  17. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client.egg-info/SOURCES.txt +10 -0
  18. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client.egg-info/requires.txt +1 -1
  19. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/setup.cfg +1 -1
  20. lago-python-client-0.35.0/tests/__init__.py +0 -0
  21. lago-python-client-0.35.0/tests/test_applied_tax_client.py +84 -0
  22. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_invoice_client.py +30 -11
  23. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_plan_client.py +2 -1
  24. lago-python-client-0.35.0/tests/test_tax_client.py +145 -0
  25. lago-python-client-0.30.0/lago_python_client/version.py +0 -1
  26. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/LICENSE +0 -0
  27. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/README.md +0 -0
  28. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/__init__.py +0 -0
  29. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/add_ons/__init__.py +0 -0
  30. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/add_ons/clients.py +0 -0
  31. {lago-python-client-0.30.0/lago_python_client/billable_metrics → lago-python-client-0.35.0/lago_python_client/applied_taxes}/__init__.py +0 -0
  32. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/base_client.py +0 -0
  33. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/base_model.py +0 -0
  34. {lago-python-client-0.30.0/lago_python_client/coupons → lago-python-client-0.35.0/lago_python_client/billable_metrics}/__init__.py +0 -0
  35. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/billable_metrics/clients.py +0 -0
  36. {lago-python-client-0.30.0/lago_python_client/credit_notes → lago-python-client-0.35.0/lago_python_client/coupons}/__init__.py +0 -0
  37. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/coupons/clients.py +0 -0
  38. {lago-python-client-0.30.0/lago_python_client/customers → lago-python-client-0.35.0/lago_python_client/credit_notes}/__init__.py +0 -0
  39. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/credit_notes/clients.py +0 -0
  40. {lago-python-client-0.30.0/lago_python_client/events → lago-python-client-0.35.0/lago_python_client/customers}/__init__.py +0 -0
  41. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/customers/clients.py +0 -0
  42. {lago-python-client-0.30.0/lago_python_client/fees → lago-python-client-0.35.0/lago_python_client/events}/__init__.py +0 -0
  43. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/events/clients.py +0 -0
  44. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/exceptions.py +0 -0
  45. {lago-python-client-0.30.0/lago_python_client/invoices → lago-python-client-0.35.0/lago_python_client/fees}/__init__.py +0 -0
  46. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/fees/clients.py +0 -0
  47. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/functools_ext.py +0 -0
  48. {lago-python-client-0.30.0/lago_python_client/organizations → lago-python-client-0.35.0/lago_python_client/invoices}/__init__.py +0 -0
  49. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/mixins.py +0 -0
  50. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/add_on.py +0 -0
  51. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/applied_add_on.py +0 -0
  52. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/applied_coupon.py +0 -0
  53. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/billable_metric.py +0 -0
  54. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/coupon.py +0 -0
  55. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/customer.py +0 -0
  56. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/customer_usage.py +0 -0
  57. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/event.py +0 -0
  58. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/group.py +0 -0
  59. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/invoice_item.py +0 -0
  60. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/organization.py +0 -0
  61. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/plan.py +0 -0
  62. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/subscription.py +0 -0
  63. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/wallet.py +0 -0
  64. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/models/wallet_transaction.py +0 -0
  65. {lago-python-client-0.30.0/lago_python_client/plans → lago-python-client-0.35.0/lago_python_client/organizations}/__init__.py +0 -0
  66. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/organizations/clients.py +0 -0
  67. {lago-python-client-0.30.0/lago_python_client/services → lago-python-client-0.35.0/lago_python_client/plans}/__init__.py +0 -0
  68. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/plans/clients.py +0 -0
  69. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/py.typed +0 -0
  70. {lago-python-client-0.30.0/lago_python_client/subscriptions → lago-python-client-0.35.0/lago_python_client/services}/__init__.py +0 -0
  71. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/services/json.py +0 -0
  72. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/services/request.py +0 -0
  73. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/services/response.py +0 -0
  74. {lago-python-client-0.30.0/lago_python_client/wallets → lago-python-client-0.35.0/lago_python_client/subscriptions}/__init__.py +0 -0
  75. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/subscriptions/clients.py +0 -0
  76. {lago-python-client-0.30.0/lago_python_client/webhooks → lago-python-client-0.35.0/lago_python_client/taxes}/__init__.py +0 -0
  77. {lago-python-client-0.30.0/tests → lago-python-client-0.35.0/lago_python_client/wallets}/__init__.py +0 -0
  78. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/wallets/clients.py +0 -0
  79. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client/webhooks/clients.py +0 -0
  80. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client.egg-info/dependency_links.txt +0 -0
  81. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/lago_python_client.egg-info/top_level.txt +0 -0
  82. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/pyproject.toml +0 -0
  83. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_add_on_client.py +0 -0
  84. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_applied_add_on_client.py +0 -0
  85. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_applied_coupon_client.py +0 -0
  86. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_billable_metric_client.py +0 -0
  87. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_client.py +0 -0
  88. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_coupon_client.py +0 -0
  89. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_credit_note_client.py +0 -0
  90. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_customer_client.py +0 -0
  91. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_event_client.py +0 -0
  92. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_fee_client.py +0 -0
  93. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_functools_ext.py +0 -0
  94. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_group_client.py +0 -0
  95. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_json_services.py +0 -0
  96. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_organization_client.py +0 -0
  97. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_request_services.py +0 -0
  98. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_response_services.py +0 -0
  99. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_subscription_client.py +0 -0
  100. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_wallet_client.py +0 -0
  101. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_wallet_transaction_client.py +0 -0
  102. {lago-python-client-0.30.0 → lago-python-client-0.35.0}/tests/test_webhook_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lago-python-client
3
- Version: 0.30.0
3
+ Version: 0.35.0
4
4
  Summary: Lago Python API Client
5
5
  Home-page: https://github.com/getlago/lago-python-client
6
6
  Author: Lovro Colic
@@ -0,0 +1,54 @@
1
+ from typing import ClassVar, Type
2
+
3
+ from pydantic import BaseModel
4
+ from ..base_client import BaseClient
5
+ from ..mixins import CreateCommandMixin, DestroyCommandMixin, FindAllCommandMixin, FindCommandMixin, UpdateCommandMixin
6
+ from ..services.json import to_json
7
+ from ..services.request import make_headers, make_url, send_post_request, send_delete_request
8
+ from ..models.applied_tax import AppliedTaxResponse
9
+ from ..services.response import get_response_data, prepare_object_response, Response
10
+
11
+
12
+ class AppliedTaxClient(
13
+ CreateCommandMixin[AppliedTaxResponse],
14
+ DestroyCommandMixin[AppliedTaxResponse],
15
+ BaseClient,
16
+ ):
17
+ API_RESOURCE: ClassVar[str] = 'applied_taxes'
18
+ RESPONSE_MODEL: ClassVar[Type[AppliedTaxResponse]] = AppliedTaxResponse
19
+ ROOT_NAME: ClassVar[str] = 'applied_tax'
20
+
21
+ def create(self, external_customer_id: str, input_object: BaseModel) -> AppliedTaxResponse:
22
+ api_response: Response = send_post_request(
23
+ url=make_url(
24
+ origin=self.base_url,
25
+ path_parts=('customers', external_customer_id, self.API_RESOURCE),
26
+ ),
27
+ content=to_json({
28
+ self.ROOT_NAME: input_object.dict(),
29
+ }),
30
+ headers=make_headers(api_key=self.api_key),
31
+ )
32
+
33
+ response_data = get_response_data(response=api_response, key=self.ROOT_NAME)
34
+ if not response_data:
35
+ return None
36
+
37
+ return prepare_object_response(
38
+ response_model=self.RESPONSE_MODEL,
39
+ data=response_data,
40
+ )
41
+
42
+ def destroy(self, external_customer_id: str, tax_rate_code: str) -> AppliedTaxResponse:
43
+ api_response: Response = send_delete_request(
44
+ url=make_url(
45
+ origin=self.base_url,
46
+ path_parts=('customers', external_customer_id, self.API_RESOURCE, tax_rate_code),
47
+ ),
48
+ headers=make_headers(api_key=self.api_key),
49
+ )
50
+
51
+ return prepare_object_response(
52
+ response_model=self.RESPONSE_MODEL,
53
+ data=get_response_data(response=api_response, key=self.ROOT_NAME),
54
+ )
@@ -1,6 +1,7 @@
1
1
  from urllib.parse import urljoin
2
2
 
3
3
  from .add_ons.clients import AddOnClient, AppliedAddOnClient
4
+ from .applied_taxes.clients import AppliedTaxClient
4
5
  from .billable_metrics.clients import BillableMetricClient, GroupClient
5
6
  from .coupons.clients import AppliedCouponClient, CouponClient
6
7
  from .credit_notes.clients import CreditNoteClient
@@ -12,6 +13,7 @@ from .invoices.clients import InvoiceClient
12
13
  from .organizations.clients import OrganizationClient
13
14
  from .plans.clients import PlanClient
14
15
  from .subscriptions.clients import SubscriptionClient
16
+ from .taxes.clients import TaxClient
15
17
  from .wallets.clients import WalletClient, WalletTransactionClient
16
18
  from .webhooks.clients import WebhookClient
17
19
 
@@ -41,6 +43,10 @@ class Client:
41
43
  def add_ons(self) -> AddOnClient:
42
44
  return AddOnClient(self.base_api_url, self.api_key)
43
45
 
46
+ @callable_cached_property
47
+ def applied_taxes(self) -> AppliedTaxClient:
48
+ return AppliedTaxClient(self.base_api_url, self.api_key)
49
+
44
50
  @callable_cached_property
45
51
  def billable_metrics(self) -> BillableMetricClient:
46
52
  return BillableMetricClient(self.base_api_url, self.api_key)
@@ -89,6 +95,10 @@ class Client:
89
95
  def subscriptions(self) -> SubscriptionClient:
90
96
  return SubscriptionClient(self.base_api_url, self.api_key)
91
97
 
98
+ @callable_cached_property
99
+ def taxes(self) -> TaxClient:
100
+ return TaxClient(self.base_api_url, self.api_key)
101
+
92
102
  @callable_cached_property
93
103
  def wallets(self) -> WalletClient:
94
104
  return WalletClient(self.base_api_url, self.api_key)
@@ -1,13 +1,19 @@
1
1
  from typing import ClassVar, Optional, Type, Union
2
2
 
3
3
  from ..base_client import BaseClient
4
- from ..mixins import FindAllCommandMixin, FindCommandMixin, UpdateCommandMixin
4
+ from ..mixins import FindAllCommandMixin, FindCommandMixin, UpdateCommandMixin, CreateCommandMixin
5
5
  from ..models.invoice import InvoiceResponse
6
6
  from ..services.request import make_headers, make_url, send_post_request, send_put_request
7
7
  from ..services.response import get_response_data, prepare_object_response, Response
8
8
 
9
9
 
10
- class InvoiceClient(FindCommandMixin[InvoiceResponse], FindAllCommandMixin[InvoiceResponse], UpdateCommandMixin[InvoiceResponse], BaseClient):
10
+ class InvoiceClient(
11
+ FindCommandMixin[InvoiceResponse],
12
+ FindAllCommandMixin[InvoiceResponse],
13
+ UpdateCommandMixin[InvoiceResponse],
14
+ CreateCommandMixin[InvoiceResponse],
15
+ BaseClient,
16
+ ):
11
17
  API_RESOURCE: ClassVar[str] = 'invoices'
12
18
  RESPONSE_MODEL: ClassVar[Type[InvoiceResponse]] = InvoiceResponse
13
19
  ROOT_NAME: ClassVar[str] = 'invoice'
@@ -1,5 +1,6 @@
1
1
  from .applied_add_on import AppliedAddOn
2
2
  from .applied_coupon import AppliedCoupon
3
+ from .applied_tax import AppliedTax
3
4
  from .billable_metric import BillableMetric, BillableMetricGroup
4
5
  from .charge import Charge, Charges, ChargesResponse
5
6
  from .coupon import Coupon, LimitationConfiguration
@@ -11,9 +12,11 @@ from .organization import Organization, OrganizationBillingConfiguration
11
12
  from .event import Event, BatchEvent
12
13
  from .fee import Fee
13
14
  from .customer import Customer, CustomerBillingConfiguration, Metadata, MetadataList
14
- from .invoice import InvoicePaymentStatusChange, Invoice, InvoiceMetadata, InvoiceMetadataList
15
+ from .invoice import InvoicePaymentStatusChange, Invoice, InvoiceMetadata, InvoiceMetadataList,\
16
+ OneOffInvoice, InvoiceFeesList, InvoiceFee
15
17
  from .invoice_item import InvoiceItemResponse
16
18
  from .subscription import Subscription
17
19
  from .customer_usage import Metric, ChargeObject, ChargeUsage, CustomerUsageResponse
20
+ from .tax import Tax
18
21
  from .wallet import Wallet
19
22
  from .wallet_transaction import WalletTransaction
@@ -0,0 +1,18 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from ..base_model import BaseResponseModel
6
+
7
+
8
+ class AppliedTax(BaseModel):
9
+ tax_code: str
10
+
11
+
12
+ class AppliedTaxResponse(BaseResponseModel):
13
+ lago_id: str
14
+ lago_customer_id: str
15
+ lago_tax_id: str
16
+ tax_code: str
17
+ external_customer_id: str
18
+ created_at: str
@@ -14,7 +14,8 @@ class Charge(BaseModel):
14
14
  id: Optional[str]
15
15
  billable_metric_id: Optional[str]
16
16
  charge_model: Optional[str]
17
- instant: Optional[bool]
17
+ pay_in_advance: Optional[bool]
18
+ invoiceable: Optional[bool]
18
19
  min_amount_cents: Optional[int]
19
20
  properties: Optional[Dict[str, Any]]
20
21
  group_properties: Optional[GroupProperties]
@@ -29,7 +30,8 @@ class ChargeResponse(BaseResponseModel):
29
30
  lago_billable_metric_id: Optional[str]
30
31
  billable_metric_code: Optional[str]
31
32
  charge_model: Optional[str]
32
- instant: Optional[bool]
33
+ pay_in_advance: Optional[bool]
34
+ invoiceable: Optional[bool]
33
35
  min_amount_cents: Optional[int]
34
36
  properties: Optional[Dict[str, Any]]
35
37
  group_properties: Optional[GroupProperties]
@@ -15,6 +15,7 @@ class CreditResponse(BaseResponseModel):
15
15
  lago_id: Optional[str]
16
16
  amount_cents: Optional[int]
17
17
  amount_currency: Optional[str]
18
+ before_vat: bool
18
19
  item: Optional[InvoiceItemResponse]
19
20
  invoice: Optional[InvoiceShortDetails]
20
21
 
@@ -28,22 +28,26 @@ class CreditNoteResponse(BaseResponseModel):
28
28
  credit_status: Optional[str]
29
29
  refund_status: Optional[str]
30
30
  reason: Optional[str]
31
- total_amount_cents: Optional[int]
31
+ currency: str
32
+ total_amount_cents: int
33
+ credit_amount_cents: int
34
+ balance_amount_cents: int
35
+ refund_amount_cents: int
36
+ vat_amount_cents: str
37
+ sub_total_vat_excluded_amount_cents: int
38
+ coupons_adjustement_amount_cents: int
39
+ file_url: Optional[str]
40
+ created_at: Optional[str]
41
+ updated_at: Optional[str]
42
+ items: Optional[ItemsResponse]
43
+
44
+ # NOTE(legacy): Deprecated fields that will be removed in the future
32
45
  total_amount_currency: Optional[str]
33
- credit_amount_cents: Optional[int]
34
46
  credit_amount_currency: Optional[str]
35
- balance_amount_cents: Optional[int]
36
- balance_amount_currency: Optional[str]
37
- refund_amount_cents: Optional[int]
38
47
  refund_amount_currency: Optional[str]
39
- vat_amount_cents: Optional[str]
48
+ balance_amount_currency: Optional[str]
40
49
  vat_amount_currency: Optional[str]
41
- sub_total_vat_excluded_amount_cents: Optional[str]
42
50
  sub_total_vat_excluded_amount_currency: Optional[str]
43
- file_url: Optional[str]
44
- created_at: Optional[str]
45
- updated_at: Optional[str]
46
- items: Optional[ItemsResponse]
47
51
 
48
52
 
49
53
  class Item(BaseModel):
@@ -18,11 +18,15 @@ class FeeResponse(BaseResponseModel):
18
18
  vat_amount_cents: Optional[int]
19
19
  vat_amount_currency: Optional[str]
20
20
  total_amount_cents: Optional[int]
21
+ unit_amount_cents: Optional[int]
21
22
  total_amount_currency: Optional[str]
22
23
  units: Optional[float]
23
24
  events_count: Optional[int]
24
25
  payment_status: Optional[str]
25
26
  created_at: Optional[str]
27
+ description: Optional[str]
28
+ pay_in_advance: Optional[bool]
29
+ invoiceable: Optional[bool]
26
30
  succeeded_at: Optional[str]
27
31
  failed_at: Optional[str]
28
32
  refunded_at: Optional[str]
@@ -20,32 +20,62 @@ class InvoiceMetadata(BaseModel):
20
20
  value: Optional[str]
21
21
 
22
22
 
23
+ class InvoiceFee(BaseModel):
24
+ add_on_code: Optional[str]
25
+ unit_amount_cents: Optional[int]
26
+ units: Optional[float]
27
+ description: Optional[str]
28
+
29
+
23
30
  class InvoiceMetadataList(BaseModel):
24
31
  __root__: List[InvoiceMetadata]
25
32
 
26
33
 
34
+ class InvoiceFeesList(BaseModel):
35
+ __root__: List[InvoiceFee]
36
+
37
+
27
38
  class Invoice(BaseModel):
28
39
  payment_status: Optional[str]
29
40
  metadata: Optional[InvoiceMetadataList]
30
41
 
31
42
 
43
+ class OneOffInvoice(BaseModel):
44
+ external_customer_id: Optional[str]
45
+ currency: Optional[str]
46
+ fees: Optional[InvoiceFeesList]
47
+
48
+
32
49
  class InvoiceResponse(BaseResponseModel):
33
50
  lago_id: str
34
51
  sequential_id: int
35
52
  number: str
36
53
  issuing_date: Optional[str]
37
54
  invoice_type: str
55
+ version_number: int
38
56
  status: str
39
57
  payment_status: str
40
- amount_cents: int
41
- amount_currency: str
58
+ currency: str
59
+ fees_amount_cents: int
60
+ coupons_amount_cents: int
42
61
  vat_amount_cents: int
43
- vat_amount_currency: str
62
+ credit_notes_amount_cents: int
63
+ sub_total_vat_excluded_amount_cents: int
64
+ sub_total_vat_included_amount_cents: int
44
65
  total_amount_cents: int
45
- total_amount_currency: str
66
+ prepaid_credit_amount_cents: int
46
67
  file_url: Optional[str]
47
68
  customer: Optional[CustomerResponse]
48
69
  subscriptions: Optional[SubscriptionsResponse]
49
70
  fees: Optional[FeesResponse]
50
71
  credits: Optional[CreditsResponse]
51
72
  metadata: Optional[InvoiceMetadataList]
73
+
74
+ # NOTE(legacy): Deprecated fields that will be removed in the future
75
+ legacy: bool
76
+ amount_cents: int
77
+ credit_amount_cents: int
78
+ amount_currency: str
79
+ vat_amount_currency: str
80
+ credit_amount_currency: str
81
+ total_amount_currency: str
@@ -0,0 +1,24 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel
4
+
5
+ from ..base_model import BaseResponseModel
6
+
7
+
8
+ class Tax(BaseModel):
9
+ name: Optional[str]
10
+ code: Optional[str]
11
+ rate: Optional[float]
12
+ description: Optional[str]
13
+ applied_to_organization: Optional[bool]
14
+
15
+
16
+ class TaxResponse(BaseResponseModel):
17
+ lago_id: str
18
+ name: str
19
+ code: str
20
+ rate: float
21
+ description: Optional[str]
22
+ customers_count: int
23
+ applied_to_organization: bool
24
+ created_at: str
@@ -0,0 +1,18 @@
1
+ from typing import ClassVar, Type
2
+
3
+ from ..base_client import BaseClient
4
+ from ..mixins import CreateCommandMixin, DestroyCommandMixin, FindAllCommandMixin, FindCommandMixin, UpdateCommandMixin
5
+ from ..models.tax import TaxResponse
6
+
7
+
8
+ class TaxClient(
9
+ CreateCommandMixin[TaxResponse],
10
+ DestroyCommandMixin[TaxResponse],
11
+ FindAllCommandMixin[TaxResponse],
12
+ FindCommandMixin[TaxResponse],
13
+ UpdateCommandMixin[TaxResponse],
14
+ BaseClient,
15
+ ):
16
+ API_RESOURCE: ClassVar[str] = 'taxes'
17
+ RESPONSE_MODEL: ClassVar[Type[TaxResponse]] = TaxResponse
18
+ ROOT_NAME: ClassVar[str] = 'tax'
@@ -0,0 +1 @@
1
+ LAGO_VERSION = '0.35.0'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: lago-python-client
3
- Version: 0.30.0
3
+ Version: 0.35.0
4
4
  Summary: Lago Python API Client
5
5
  Home-page: https://github.com/getlago/lago-python-client
6
6
  Author: Lovro Colic
@@ -13,6 +13,8 @@ setup.cfg
13
13
  ./lago_python_client/version.py
14
14
  ./lago_python_client/add_ons/__init__.py
15
15
  ./lago_python_client/add_ons/clients.py
16
+ ./lago_python_client/applied_taxes/__init__.py
17
+ ./lago_python_client/applied_taxes/clients.py
16
18
  ./lago_python_client/billable_metrics/__init__.py
17
19
  ./lago_python_client/billable_metrics/clients.py
18
20
  ./lago_python_client/coupons/__init__.py
@@ -31,6 +33,7 @@ setup.cfg
31
33
  ./lago_python_client/models/add_on.py
32
34
  ./lago_python_client/models/applied_add_on.py
33
35
  ./lago_python_client/models/applied_coupon.py
36
+ ./lago_python_client/models/applied_tax.py
34
37
  ./lago_python_client/models/billable_metric.py
35
38
  ./lago_python_client/models/charge.py
36
39
  ./lago_python_client/models/coupon.py
@@ -46,6 +49,7 @@ setup.cfg
46
49
  ./lago_python_client/models/organization.py
47
50
  ./lago_python_client/models/plan.py
48
51
  ./lago_python_client/models/subscription.py
52
+ ./lago_python_client/models/tax.py
49
53
  ./lago_python_client/models/wallet.py
50
54
  ./lago_python_client/models/wallet_transaction.py
51
55
  ./lago_python_client/organizations/__init__.py
@@ -58,6 +62,8 @@ setup.cfg
58
62
  ./lago_python_client/services/response.py
59
63
  ./lago_python_client/subscriptions/__init__.py
60
64
  ./lago_python_client/subscriptions/clients.py
65
+ ./lago_python_client/taxes/__init__.py
66
+ ./lago_python_client/taxes/clients.py
61
67
  ./lago_python_client/wallets/__init__.py
62
68
  ./lago_python_client/wallets/clients.py
63
69
  ./lago_python_client/webhooks/__init__.py
@@ -66,6 +72,7 @@ setup.cfg
66
72
  ./tests/test_add_on_client.py
67
73
  ./tests/test_applied_add_on_client.py
68
74
  ./tests/test_applied_coupon_client.py
75
+ ./tests/test_applied_tax_client.py
69
76
  ./tests/test_billable_metric_client.py
70
77
  ./tests/test_client.py
71
78
  ./tests/test_coupon_client.py
@@ -82,6 +89,7 @@ setup.cfg
82
89
  ./tests/test_request_services.py
83
90
  ./tests/test_response_services.py
84
91
  ./tests/test_subscription_client.py
92
+ ./tests/test_tax_client.py
85
93
  ./tests/test_wallet_client.py
86
94
  ./tests/test_wallet_transaction_client.py
87
95
  ./tests/test_webhook_client.py
@@ -93,6 +101,7 @@ lago_python_client.egg-info/top_level.txt
93
101
  tests/test_add_on_client.py
94
102
  tests/test_applied_add_on_client.py
95
103
  tests/test_applied_coupon_client.py
104
+ tests/test_applied_tax_client.py
96
105
  tests/test_billable_metric_client.py
97
106
  tests/test_client.py
98
107
  tests/test_coupon_client.py
@@ -109,6 +118,7 @@ tests/test_plan_client.py
109
118
  tests/test_request_services.py
110
119
  tests/test_response_services.py
111
120
  tests/test_subscription_client.py
121
+ tests/test_tax_client.py
112
122
  tests/test_wallet_client.py
113
123
  tests/test_wallet_transaction_client.py
114
124
  tests/test_webhook_client.py
@@ -1,5 +1,5 @@
1
1
  classes~=0.4.1
2
- httpx~=0.23.3
2
+ httpx~=0.24.0
3
3
  orjson~=3.8
4
4
  pydantic~=1.10
5
5
  typeguard~=3.0.2
@@ -28,7 +28,7 @@ packages = find:
28
28
  python_requires = >3.6
29
29
  install_requires =
30
30
  classes~=0.4.1 # bugfix auto updates allowed
31
- httpx~=0.23.3 # bugfix auto updates allowed
31
+ httpx~=0.24.0 # bugfix auto updates allowed
32
32
  orjson~=3.8 # minor auto updates allowed
33
33
  pydantic~=1.10 # minor auto updates allowed
34
34
  typeguard~=3.0.2 # bugfix auto updates allowed
File without changes
@@ -0,0 +1,84 @@
1
+ import os
2
+
3
+ import pytest
4
+ from pytest_httpx import HTTPXMock
5
+
6
+ from lago_python_client.client import Client
7
+ from lago_python_client.exceptions import LagoApiError
8
+ from lago_python_client.models.applied_tax import AppliedTax
9
+
10
+
11
+ def applied_tax_object():
12
+ return AppliedTax(
13
+ tax_code='tax_code'
14
+ )
15
+
16
+
17
+ def mock_response():
18
+ this_dir = os.path.dirname(os.path.abspath(__file__))
19
+ data_path = os.path.join(this_dir, 'fixtures/applied_tax.json')
20
+
21
+ with open(data_path, 'rb') as applied_tax_response:
22
+ return applied_tax_response.read()
23
+
24
+
25
+ def test_valid_create_applied_tax_request(httpx_mock: HTTPXMock):
26
+ client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
27
+ external_customer_id = 'external_id'
28
+
29
+ httpx_mock.add_response(
30
+ method='POST',
31
+ url='https://api.getlago.com/api/v1/customers/' + external_customer_id + '/applied_taxes',
32
+ content=mock_response()
33
+ )
34
+ response = client.applied_taxes.create(external_customer_id, applied_tax_object())
35
+
36
+ assert response.lago_id == 'b7ab2926-1de8-4428-9bcd-779314ac129b'
37
+ assert response.tax_code == 'tax_code'
38
+
39
+
40
+ def test_invalid_create_applied_tax_request(httpx_mock: HTTPXMock):
41
+ client = Client(api_key='invalid')
42
+ external_customer_id = 'external_customer_id'
43
+
44
+ httpx_mock.add_response(
45
+ method='POST',
46
+ url='https://api.getlago.com/api/v1/customers/' + external_customer_id + '/applied_taxes',
47
+ status_code=401,
48
+ content=b''
49
+ )
50
+
51
+ with pytest.raises(LagoApiError):
52
+ client.applied_taxes.create(external_customer_id, applied_tax_object())
53
+
54
+
55
+ def test_valid_destroy_applied_tax_request(httpx_mock: HTTPXMock):
56
+ client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
57
+ external_customer_id = 'external_customer_id'
58
+ tax_code = 'tax_code'
59
+
60
+ httpx_mock.add_response(
61
+ method='DELETE',
62
+ url='https://api.getlago.com/api/v1/customers/' + external_customer_id + '/applied_taxes/' + tax_code,
63
+ content=mock_response()
64
+ )
65
+ response = client.applied_taxes.destroy(external_customer_id, tax_code)
66
+
67
+ assert response.lago_id == 'b7ab2926-1de8-4428-9bcd-779314ac129b'
68
+ assert response.tax_code == tax_code
69
+
70
+
71
+ def test_invalid_destroy_applied_tax_request(httpx_mock: HTTPXMock):
72
+ client = Client(api_key='invalid')
73
+ external_customer_id = 'external_customer_id'
74
+ tax_code = 'invalid'
75
+
76
+ httpx_mock.add_response(
77
+ method='DELETE',
78
+ url='https://api.getlago.com/api/v1/customers/' + external_customer_id + '/applied_taxes/' + tax_code,
79
+ status_code=404,
80
+ content=b''
81
+ )
82
+
83
+ with pytest.raises(LagoApiError):
84
+ client.applied_taxes.destroy(external_customer_id, tax_code)
@@ -5,7 +5,8 @@ from pytest_httpx import HTTPXMock
5
5
 
6
6
  from lago_python_client.client import Client
7
7
  from lago_python_client.exceptions import LagoApiError
8
- from lago_python_client.models import Invoice, InvoiceMetadata, InvoiceMetadataList
8
+ from lago_python_client.models import Invoice, InvoiceMetadata, InvoiceMetadataList,\
9
+ OneOffInvoice, InvoiceFeesList, InvoiceFee
9
10
 
10
11
 
11
12
  def update_invoice_object():
@@ -15,19 +16,18 @@ def update_invoice_object():
15
16
  return Invoice(payment_status='failed', metadata=metadata_list)
16
17
 
17
18
 
18
- def mock_response():
19
- this_dir = os.path.dirname(os.path.abspath(__file__))
20
- my_data_path = os.path.join(this_dir, 'fixtures/invoice.json')
19
+ def one_off_invoice_object():
20
+ fee = InvoiceFee(add_on_code='123', description='desc')
21
+ fees_list = InvoiceFeesList(__root__=[fee])
21
22
 
22
- with open(my_data_path, 'rb') as invoice_response:
23
- return invoice_response.read()
23
+ return OneOffInvoice(customer_external_id='external', currency='EUR', fees=fees_list)
24
24
 
25
25
 
26
- def mock_collection_response():
26
+ def mock_response(mock='invoice'):
27
27
  this_dir = os.path.dirname(os.path.abspath(__file__))
28
- data_path = os.path.join(this_dir, 'fixtures/invoice_index.json')
28
+ my_data_path = os.path.join(this_dir, 'fixtures/' + mock + '.json')
29
29
 
30
- with open(data_path, 'rb') as invoice_response:
30
+ with open(my_data_path, 'rb') as invoice_response:
31
31
  return invoice_response.read()
32
32
 
33
33
 
@@ -44,6 +44,25 @@ def test_valid_update_invoice_request(httpx_mock: HTTPXMock):
44
44
  assert response.metadata.__root__[0].value == 'value'
45
45
 
46
46
 
47
+ def test_valid_create_invoice_request(httpx_mock: HTTPXMock):
48
+ client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
49
+
50
+ httpx_mock.add_response(method='POST', url='https://api.getlago.com/api/v1/invoices', content=mock_response(mock='one_off_invoice'))
51
+ response = client.invoices.create(one_off_invoice_object())
52
+
53
+ assert response.lago_id == '5eb02857-a71e-4ea2-bcf9-57d3a41bc6ba'
54
+ assert response.invoice_type == 'one_off'
55
+
56
+
57
+ def test_invalid_create_invoice_request(httpx_mock: HTTPXMock):
58
+ client = Client(api_key='invalid')
59
+
60
+ httpx_mock.add_response(method='POST', url='https://api.getlago.com/api/v1/invoices', status_code=401, content=b'')
61
+
62
+ with pytest.raises(LagoApiError):
63
+ client.invoices.create(one_off_invoice_object())
64
+
65
+
47
66
  def test_invalid_update_invoice_request(httpx_mock: HTTPXMock):
48
67
  client = Client(api_key='invalid')
49
68
 
@@ -76,7 +95,7 @@ def test_invalid_find_invoice_request(httpx_mock: HTTPXMock):
76
95
  def test_valid_find_all_invoice_request(httpx_mock: HTTPXMock):
77
96
  client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
78
97
 
79
- httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/invoices', content=mock_collection_response())
98
+ httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/invoices', content=mock_response(mock='invoice_index'))
80
99
  response = client.invoices.find_all()
81
100
 
82
101
  assert response['invoices'][0].lago_id == 'b7ab2926-1de8-4428-9bcd-779314ac1111'
@@ -86,7 +105,7 @@ def test_valid_find_all_invoice_request(httpx_mock: HTTPXMock):
86
105
  def test_valid_find_all_invoice_request_with_options(httpx_mock: HTTPXMock):
87
106
  client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
88
107
 
89
- httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/invoices?per_page=2&page=1', content=mock_collection_response())
108
+ httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/invoices?per_page=2&page=1', content=mock_response(mock='invoice_index'))
90
109
  response = client.invoices.find_all({'per_page': 2, 'page': 1})
91
110
 
92
111
  assert response['invoices'][1].lago_id == 'b7ab2926-1de8-4428-9bcd-779314ac1222'
@@ -13,7 +13,8 @@ def plan_object():
13
13
  billable_metric_id='id',
14
14
  charge_model='standard',
15
15
  amount_currency='EUR',
16
- instant=True,
16
+ pay_in_advance=True,
17
+ invoiceable=False,
17
18
  min_amount_cents=0,
18
19
  group_properties = [
19
20
  {
@@ -0,0 +1,145 @@
1
+ import os
2
+
3
+ import pytest
4
+ from pytest_httpx import HTTPXMock
5
+
6
+ from lago_python_client.client import Client
7
+ from lago_python_client.exceptions import LagoApiError
8
+ from lago_python_client.models.tax import Tax
9
+
10
+
11
+ def tax_object():
12
+ return Tax(
13
+ name='name',
14
+ code='tax_first',
15
+ rate=15.0,
16
+ description='desc',
17
+ applied_to_organization=False
18
+ )
19
+
20
+
21
+ def mock_response():
22
+ this_dir = os.path.dirname(os.path.abspath(__file__))
23
+ data_path = os.path.join(this_dir, 'fixtures/tax.json')
24
+
25
+ with open(data_path, 'rb') as tax_response:
26
+ return tax_response.read()
27
+
28
+
29
+ def mock_collection_response():
30
+ this_dir = os.path.dirname(os.path.abspath(__file__))
31
+ data_path = os.path.join(this_dir, 'fixtures/tax_index.json')
32
+
33
+ with open(data_path, 'rb') as tax_response:
34
+ return tax_response.read()
35
+
36
+
37
+ def test_valid_create_tax_request(httpx_mock: HTTPXMock):
38
+ client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
39
+
40
+ httpx_mock.add_response(method='POST', url='https://api.getlago.com/api/v1/taxes', content=mock_response())
41
+ response = client.taxes.create(tax_object())
42
+
43
+ assert response.lago_id == 'b7ab2926-1de8-4428-9bcd-779314ac129b'
44
+ assert response.code == 'tax_code'
45
+
46
+
47
+ def test_invalid_create_tax_request(httpx_mock: HTTPXMock):
48
+ client = Client(api_key='invalid')
49
+
50
+ httpx_mock.add_response(method='POST', url='https://api.getlago.com/api/v1/taxes', status_code=401, content=b'')
51
+
52
+ with pytest.raises(LagoApiError):
53
+ client.taxes.create(tax_object())
54
+
55
+
56
+ def test_valid_update_tax_request(httpx_mock: HTTPXMock):
57
+ client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
58
+ code = 'tax_code'
59
+
60
+ httpx_mock.add_response(method='PUT', url='https://api.getlago.com/api/v1/taxes/' + code, content=mock_response())
61
+ response = client.taxes.update(tax_object(), code)
62
+
63
+ assert response.lago_id == 'b7ab2926-1de8-4428-9bcd-779314ac129b'
64
+ assert response.code == code
65
+
66
+
67
+ def test_invalid_update_tax_request(httpx_mock: HTTPXMock):
68
+ client = Client(api_key='invalid')
69
+ code = 'invalid'
70
+
71
+ httpx_mock.add_response(method='PUT', url='https://api.getlago.com/api/v1/taxes/' + code, status_code=401, content=b'')
72
+
73
+ with pytest.raises(LagoApiError):
74
+ client.taxes.update(tax_object(), code)
75
+
76
+
77
+ def test_valid_find_tax_request(httpx_mock: HTTPXMock):
78
+ client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
79
+ code = 'tax_code'
80
+
81
+ httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/taxes/' + code, content=mock_response())
82
+ response = client.taxes.find(code)
83
+
84
+ assert response.lago_id == 'b7ab2926-1de8-4428-9bcd-779314ac129b'
85
+ assert response.code == code
86
+
87
+
88
+ def test_invalid_find_tax_request(httpx_mock: HTTPXMock):
89
+ client = Client(api_key='invalid')
90
+ code = 'invalid'
91
+
92
+ httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/taxes/' + code, status_code=404, content=b'')
93
+
94
+ with pytest.raises(LagoApiError):
95
+ client.taxes.find(code)
96
+
97
+
98
+ def test_valid_destroy_tax_request(httpx_mock: HTTPXMock):
99
+ client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
100
+ code = 'tax_code'
101
+
102
+ httpx_mock.add_response(method='DELETE', url='https://api.getlago.com/api/v1/taxes/' + code, content=mock_response())
103
+ response = client.taxes.destroy(code)
104
+
105
+ assert response.lago_id == 'b7ab2926-1de8-4428-9bcd-779314ac129b'
106
+ assert response.code == code
107
+
108
+
109
+ def test_invalid_destroy_tax_request(httpx_mock: HTTPXMock):
110
+ client = Client(api_key='invalid')
111
+ code = 'invalid'
112
+
113
+ httpx_mock.add_response(method='DELETE', url='https://api.getlago.com/api/v1/taxes/' + code, status_code=404, content=b'')
114
+
115
+ with pytest.raises(LagoApiError):
116
+ client.taxes.destroy(code)
117
+
118
+
119
+ def test_valid_find_all_taxes_request(httpx_mock: HTTPXMock):
120
+ client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
121
+
122
+ httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/taxes', content=mock_collection_response())
123
+ response = client.taxes.find_all()
124
+
125
+ assert response['taxes'][0].lago_id == 'b7ab2926-1de8-4428-9bcd-779314ac1111'
126
+ assert response['meta']['current_page'] == 1
127
+
128
+
129
+ def test_valid_find_all_taxes_request_with_options(httpx_mock: HTTPXMock):
130
+ client = Client(api_key='886fe239-927d-4072-ab72-6dd345e8dd0d')
131
+
132
+ httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/taxes?per_page=2&page=1', content=mock_collection_response())
133
+ response = client.taxes.find_all({'per_page': 2, 'page': 1})
134
+
135
+ assert response['taxes'][1].lago_id == 'b7ab2926-1de8-4428-9bcd-779314ac1222'
136
+ assert response['meta']['current_page'] == 1
137
+
138
+
139
+ def test_invalid_find_all_taxes_request(httpx_mock: HTTPXMock):
140
+ client = Client(api_key='invalid')
141
+
142
+ httpx_mock.add_response(method='GET', url='https://api.getlago.com/api/v1/taxes', status_code=404, content=b'')
143
+
144
+ with pytest.raises(LagoApiError):
145
+ client.taxes.find_all()
@@ -1 +0,0 @@
1
- LAGO_VERSION = '0.30.0'