Skip to content

Commit f4f4850

Browse files
chore: regenerate SDK with Switch charge and full public API surface
Sync Python SDK manifest and services with the TypeScript canonical output so merchants get create_switch_charge and the previously missing public endpoints. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent d22736c commit f4f4850

29 files changed

Lines changed: 392 additions & 80 deletions

lomi/client.py

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,13 @@ def _flatten_data(data):
1919
class LomiClient:
2020
"""Merchant API client (public routes only)."""
2121

22-
DEFAULT_TIMEOUT = 30
23-
2422
def __init__(
2523
self,
2624
api_key: str,
2725
base_url: str = "https://api.lomi.africa",
2826
environment: str = "live",
29-
timeout: Optional[int] = None,
3027
):
3128
self.api_key = api_key
32-
self.timeout = timeout if timeout is not None else self.DEFAULT_TIMEOUT
3329
test_host = environment in ("test", "sandbox") or (
3430
isinstance(environment, str) and environment.lower() == "test"
3531
)
@@ -46,16 +42,24 @@ def __init__(
4642
self.customers = CustomersService(self)
4743
self.customer_subscriptions = CustomerSubscriptionsService(self)
4844
self.discount_coupons = DiscountCouponsService(self)
45+
self.disputes = DisputesService(self)
4946
self.merchants = MerchantsService(self)
47+
self.meters = MetersService(self)
48+
self.organization = OrganizationService(self)
5049
self.organizations = OrganizationsService(self)
5150
self.payment_links = PaymentLinksService(self)
5251
self.payment_requests = PaymentRequestsService(self)
5352
self.payouts = PayoutsService(self)
5453
self.products = ProductsService(self)
5554
self.providers = ProvidersService(self)
5655
self.refunds = RefundsService(self)
56+
self.risk_assessments = RiskAssessmentsService(self)
57+
self.settlements = SettlementsService(self)
5758
self.subscriptions = SubscriptionsService(self)
5859
self.transactions = TransactionsService(self)
60+
self.usage_billing = UsageBillingService(self)
61+
self.usage_events = UsageEventsService(self)
62+
self.usage_subscriptions = UsageSubscriptionsService(self)
5963
self.webhook_delivery_logs = WebhookDeliveryLogsService(self)
6064
self.webhooks = WebhooksService(self)
6165

@@ -74,7 +78,6 @@ def _request(
7478
url=url,
7579
params=params,
7680
json=json_data,
77-
timeout=self.timeout,
7881
)
7982

8083
if response.status_code == 401:

lomi/client_base.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,14 @@
11

22
from typing import Optional, Dict, Any, TYPE_CHECKING
3-
from urllib.parse import quote
3+
import warnings
4+
import requests
45

56
from .exceptions import LomiError, LomiAuthError, LomiNotFoundError
67

78
if TYPE_CHECKING:
89
from .client import LomiClient
910

1011

11-
def _safe_path_param(value: Any) -> str:
12-
"""URL-encode a value for safe interpolation into a URL path segment."""
13-
return quote(str(value), safe="")
14-
15-
1612
class ClientBase:
1713
"""HTTP helpers shared by generated services."""
1814

lomi/sdk_python_methods.json

Lines changed: 85 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"generatedAt": "2026-06-11T16:10:16.461Z",
2+
"generatedAt": "2026-06-30T10:04:38.745Z",
33
"language": "python",
44
"naming": "ts_method_names_manifest_pep8_sdk_methods_are_snake_case_in_code",
55
"sdk": {
@@ -12,6 +12,7 @@
1212
"cancelCardCharge",
1313
"createCardCharge",
1414
"createMtnCharge",
15+
"createSwitchCharge",
1516
"createWaveCharge",
1617
"getCardCharge"
1718
],
@@ -42,12 +43,27 @@
4243
"getPerformance",
4344
"list"
4445
],
46+
"disputes": [
47+
"get",
48+
"list"
49+
],
4550
"merchants": [
4651
"get",
4752
"getArr",
4853
"getBalance",
4954
"getMrr"
5055
],
56+
"meters": [
57+
"create",
58+
"get",
59+
"getCustomerBalance",
60+
"list",
61+
"update"
62+
],
63+
"organization": [
64+
"getSettings",
65+
"updateSettings"
66+
],
5167
"organizations": [
5268
"get",
5369
"getMetrics",
@@ -83,17 +99,43 @@
8399
"get",
84100
"list"
85101
],
102+
"riskAssessments": [
103+
"findOne",
104+
"listAssessments"
105+
],
106+
"settlements": [
107+
"findAll",
108+
"findTransactions"
109+
],
86110
"subscriptions": [
87111
"cancel",
112+
"changePlan",
88113
"findByCustomer",
89114
"get",
90115
"list",
116+
"uncancel",
91117
"update"
92118
],
93119
"transactions": [
94120
"get",
95121
"list"
96122
],
123+
"usageBilling": [
124+
"checkEntitlement",
125+
"createEntitlement",
126+
"getRevenue",
127+
"getSubscriptionUsage",
128+
"grantCredits",
129+
"listPeriods"
130+
],
131+
"usageEvents": [
132+
"create",
133+
"get",
134+
"list"
135+
],
136+
"usageSubscriptions": [
137+
"create"
138+
],
97139
"webhookDeliveryLogs": [
98140
"get",
99141
"list"
@@ -118,6 +160,7 @@
118160
"cancel_card_charge",
119161
"create_card_charge",
120162
"create_mtn_charge",
163+
"create_switch_charge",
121164
"create_wave_charge",
122165
"get_card_charge"
123166
],
@@ -148,12 +191,27 @@
148191
"get_performance",
149192
"list"
150193
],
194+
"disputes": [
195+
"get",
196+
"list"
197+
],
151198
"merchants": [
152199
"get",
153200
"get_arr",
154201
"get_balance",
155202
"get_mrr"
156203
],
204+
"meters": [
205+
"create",
206+
"get",
207+
"get_customer_balance",
208+
"list",
209+
"update"
210+
],
211+
"organization": [
212+
"get_settings",
213+
"update_settings"
214+
],
157215
"organizations": [
158216
"get",
159217
"get_metrics",
@@ -189,17 +247,43 @@
189247
"get",
190248
"list"
191249
],
250+
"risk_assessments": [
251+
"find_one",
252+
"list_assessments"
253+
],
254+
"settlements": [
255+
"find_all",
256+
"find_transactions"
257+
],
192258
"subscriptions": [
193259
"cancel",
260+
"change_plan",
194261
"find_by_customer",
195262
"get",
196263
"list",
264+
"uncancel",
197265
"update"
198266
],
199267
"transactions": [
200268
"get",
201269
"list"
202270
],
271+
"usage_billing": [
272+
"check_entitlement",
273+
"create_entitlement",
274+
"get_revenue",
275+
"get_subscription_usage",
276+
"grant_credits",
277+
"list_periods"
278+
],
279+
"usage_events": [
280+
"create",
281+
"get",
282+
"list"
283+
],
284+
"usage_subscriptions": [
285+
"create"
286+
],
203287
"webhook_delivery_logs": [
204288
"get",
205289
"list"

lomi/services/__init__.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,23 @@
44
from .customer_subscriptions import CustomerSubscriptionsService
55
from .customers import CustomersService
66
from .discount_coupons import DiscountCouponsService
7+
from .disputes import DisputesService
78
from .merchants import MerchantsService
9+
from .meters import MetersService
10+
from .organization import OrganizationService
811
from .organizations import OrganizationsService
912
from .payment_links import PaymentLinksService
1013
from .payment_requests import PaymentRequestsService
1114
from .payouts import PayoutsService
1215
from .products import ProductsService
1316
from .providers import ProvidersService
1417
from .refunds import RefundsService
18+
from .risk_assessments import RiskAssessmentsService
19+
from .settlements import SettlementsService
1520
from .subscriptions import SubscriptionsService
1621
from .transactions import TransactionsService
22+
from .usage_billing import UsageBillingService
23+
from .usage_events import UsageEventsService
24+
from .usage_subscriptions import UsageSubscriptionsService
1725
from .webhook_delivery_logs import WebhookDeliveryLogsService
1826
from .webhooks import WebhooksService

lomi/services/accounts.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from typing import Any, Dict, Optional
44

5-
from ..client_base import ClientBase, _safe_path_param
5+
from ..client_base import ClientBase
66

77

88
class AccountsService(ClientBase):
@@ -11,7 +11,7 @@ class AccountsService(ClientBase):
1111
def check_balance(self, currency: str) -> Any:
1212
"""Vérifier le solde disponible"""
1313
path = "/accounts/balance/check/{currency}"
14-
path = path.replace("{currency}", _safe_path_param(currency))
14+
path = path.replace("{currency}", str(currency))
1515
return self._request("GET", path)
1616

1717
def get_balance(self, params: Optional[Dict[str, Any]] = None) -> Any:

lomi/services/charges.py

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,36 +2,41 @@
22

33
from typing import Any, Dict, Optional
44

5-
from ..client_base import ClientBase, _safe_path_param
5+
from ..client_base import ClientBase
66

77

88
class ChargesService(ClientBase):
99
"""Public merchant API — generated from OpenAPI allowlist."""
1010

1111
def cancel_card_charge(self, id: str) -> Any:
12-
"""Annuler un encaissement carte"""
12+
"""Cancel card charge"""
1313
path = "/charge/card/{id}/cancel"
14-
path = path.replace("{id}", _safe_path_param(id))
14+
path = path.replace("{id}", str(id))
1515
return self._request("POST", path)
1616

1717
def create_card_charge(self, body: Optional[Dict[str, Any]] = None) -> Any:
18-
"""Créer un encaissement carte (client_secret)"""
18+
"""Create card charge (client_secret)"""
1919
path = "/charge/card"
2020
return self._request("POST", path, data=body)
2121

22-
def create_mtn_charge(self) -> Any:
23-
"""Lancer un encaissement direct MTN MoMo"""
22+
def create_mtn_charge(self, body: Optional[Dict[str, Any]] = None) -> Any:
23+
"""Create MTN MoMo charge"""
2424
path = "/charge/mtn"
25-
return self._request("POST", path)
25+
return self._request("POST", path, data=body)
26+
27+
def create_switch_charge(self, body: Optional[Dict[str, Any]] = None) -> Any:
28+
"""Create Switch charge (server-side card authorization)"""
29+
path = "/charge/switch"
30+
return self._request("POST", path, data=body)
2631

27-
def create_wave_charge(self) -> Any:
28-
"""Lancer un encaissement direct Wave"""
32+
def create_wave_charge(self, body: Optional[Dict[str, Any]] = None) -> Any:
33+
"""Create direct Wave charge"""
2934
path = "/charge/wave"
30-
return self._request("POST", path)
35+
return self._request("POST", path, data=body)
3136

3237
def get_card_charge(self, id: str) -> Any:
33-
"""Obtenir un encaissement carte"""
38+
"""Retrieve card charge"""
3439
path = "/charge/card/{id}"
35-
path = path.replace("{id}", _safe_path_param(id))
40+
path = path.replace("{id}", str(id))
3641
return self._request("GET", path)
3742

lomi/services/checkout_sessions.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from typing import Any, Dict, Optional
44

5-
from ..client_base import ClientBase, _safe_path_param
5+
from ..client_base import ClientBase
66

77

88
class CheckoutSessionsService(ClientBase):
@@ -16,7 +16,7 @@ def create(self, body: Optional[Dict[str, Any]] = None) -> Any:
1616
def get(self, id: str) -> Any:
1717
"""Obtenir une session de paiement par ID"""
1818
path = "/checkout-sessions/{id}"
19-
path = path.replace("{id}", _safe_path_param(id))
19+
path = path.replace("{id}", str(id))
2020
return self._request("GET", path)
2121

2222
def list(self, params: Optional[Dict[str, Any]] = None) -> Any:

lomi/services/customer_subscriptions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
from typing import Any, Dict, Optional
44

5-
from ..client_base import ClientBase, _safe_path_param
5+
from ..client_base import ClientBase
66

77

88
class CustomerSubscriptionsService(ClientBase):
@@ -11,13 +11,13 @@ class CustomerSubscriptionsService(ClientBase):
1111
def delete(self, subscription_id: str) -> Any:
1212
"""Cancel customer subscription"""
1313
path = "/customer-subscriptions/{subscription_id}"
14-
path = path.replace("{subscription_id}", _safe_path_param(subscription_id))
14+
path = path.replace("{subscription_id}", str(subscription_id))
1515
return self._request("DELETE", path)
1616

1717
def get(self, subscription_id: str) -> Any:
1818
"""Get customer subscription"""
1919
path = "/customer-subscriptions/{subscription_id}"
20-
path = path.replace("{subscription_id}", _safe_path_param(subscription_id))
20+
path = path.replace("{subscription_id}", str(subscription_id))
2121
return self._request("GET", path)
2222

2323
def list(self, params: Optional[Dict[str, Any]] = None) -> Any:
@@ -28,6 +28,6 @@ def list(self, params: Optional[Dict[str, Any]] = None) -> Any:
2828
def update(self, subscription_id: str) -> Any:
2929
"""Update customer subscription"""
3030
path = "/customer-subscriptions/{subscription_id}"
31-
path = path.replace("{subscription_id}", _safe_path_param(subscription_id))
31+
path = path.replace("{subscription_id}", str(subscription_id))
3232
return self._request("PATCH", path)
3333

0 commit comments

Comments
 (0)