paybridge-np 0.1.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.
@@ -0,0 +1,10 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ dist/
5
+ build/
6
+ .eggs/
7
+ *.egg
8
+ .venv/
9
+ .mypy_cache/
10
+ .pytest_cache/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PayBridgeNP
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,163 @@
1
+ Metadata-Version: 2.1
2
+ Name: paybridge-np
3
+ Version: 0.1.0
4
+ Summary: Official Python SDK for the PayBridgeNP payment gateway - accept eSewa, Khalti, and ConnectIPS through a single API
5
+ Project-URL: Homepage, https://paybridgenp.com
6
+ Project-URL: Documentation, https://docs.paybridgenp.com
7
+ Project-URL: Repository, https://github.com/paybridgenp/paybridgenp-python-sdk
8
+ Project-URL: Issues, https://github.com/paybridgenp/paybridgenp-python-sdk/issues
9
+ Author-email: PayBridgeNP <support@paybridgenp.com>
10
+ License: MIT
11
+ License-File: LICENSE
12
+ Keywords: connectips,esewa,khalti,nepal,nepal-payments,paybridge,payment-gateway,payments
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Classifier: Programming Language :: Python :: 3.10
19
+ Classifier: Programming Language :: Python :: 3.11
20
+ Classifier: Programming Language :: Python :: 3.12
21
+ Classifier: Programming Language :: Python :: 3.13
22
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
+ Classifier: Typing :: Typed
24
+ Requires-Python: >=3.9
25
+ Requires-Dist: httpx>=0.24.0
26
+ Description-Content-Type: text/markdown
27
+
28
+ # paybridge-np
29
+
30
+ Official Python SDK for the [PayBridgeNP](https://paybridgenp.com) payment gateway. Accept eSewa, Khalti, and ConnectIPS through a single API.
31
+
32
+ ## Installation
33
+
34
+ ```bash
35
+ pip install paybridge-np
36
+ ```
37
+
38
+ ## Quick start
39
+
40
+ ```python
41
+ from paybridge_np import PayBridge
42
+
43
+ client = PayBridge(api_key="sk_live_...") # from dashboard.paybridgenp.com
44
+
45
+ # Create a checkout session
46
+ session = client.checkout.create({
47
+ "amount": 250000, # NPR 2,500 in paisa
48
+ "currency": "NPR",
49
+ "returnUrl": "https://mystore.com/success",
50
+ "cancelUrl": "https://mystore.com/cart",
51
+ "metadata": {"orderId": "ORD-7842"},
52
+ "customer": {
53
+ "name": "Ram Shrestha",
54
+ "email": "ram@example.com",
55
+ "phone": "9841000000",
56
+ },
57
+ })
58
+
59
+ # Redirect customer to hosted checkout
60
+ # session["checkout_url"] => https://paybridgenp.com/checkout/cs_xxx
61
+ ```
62
+
63
+ ## Payments
64
+
65
+ ```python
66
+ # List payments
67
+ result = client.payments.list(limit=20)
68
+ payments = result["data"]
69
+
70
+ # Get a single payment
71
+ payment = client.payments.retrieve("pay_xxx")
72
+ ```
73
+
74
+ ## Refunds
75
+
76
+ ```python
77
+ refund = client.refunds.create({
78
+ "paymentId": "pay_xxx",
79
+ "amount": 100000, # NPR 1,000 in paisa
80
+ "reason": "customer_request",
81
+ })
82
+ ```
83
+
84
+ ## Webhooks
85
+
86
+ ```python
87
+ # Register an endpoint
88
+ endpoint = client.webhooks.create(
89
+ url="https://mystore.com/webhooks/paybridge",
90
+ events=["payment.succeeded", "payment.failed"],
91
+ )
92
+
93
+ # Verify a webhook signature (no client instance needed)
94
+ from paybridge_np.resources.webhooks import WebhooksResource
95
+
96
+ event = WebhooksResource.construct_event(
97
+ body=raw_body,
98
+ signature=request.headers["X-PayBridge-Signature"],
99
+ secret="whsec_...",
100
+ )
101
+ ```
102
+
103
+ ## Billing (Subscriptions)
104
+
105
+ ```python
106
+ # Create a plan
107
+ plan = client.plans.create({
108
+ "name": "Pro Monthly",
109
+ "amount": 99900,
110
+ "intervalUnit": "month",
111
+ })
112
+
113
+ # Create a customer
114
+ customer = client.customers.create({
115
+ "name": "Sita Gurung",
116
+ "email": "sita@example.com",
117
+ })
118
+
119
+ # Subscribe
120
+ subscription = client.subscriptions.create({
121
+ "customerId": customer["id"],
122
+ "planId": plan["id"],
123
+ })
124
+
125
+ # List invoices
126
+ invoices = client.invoices.list(customer_id=customer["id"])
127
+ ```
128
+
129
+ ## Sandbox mode
130
+
131
+ Use a sandbox API key (`sk_sandbox_...`) to test without real money. The SDK automatically routes to sandbox endpoints.
132
+
133
+ ## Error handling
134
+
135
+ ```python
136
+ from paybridge_np import PayBridgeError, AuthenticationError
137
+
138
+ try:
139
+ session = client.checkout.create({...})
140
+ except AuthenticationError:
141
+ print("Invalid API key")
142
+ except PayBridgeError as e:
143
+ print(e, e.status_code)
144
+ ```
145
+
146
+ ## Context manager
147
+
148
+ ```python
149
+ with PayBridge(api_key="sk_live_...") as client:
150
+ session = client.checkout.create({...})
151
+ # HTTP client is closed automatically
152
+ ```
153
+
154
+ ## Documentation
155
+
156
+ - [API Reference](https://docs.paybridgenp.com)
157
+ - [Dashboard](https://dashboard.paybridgenp.com)
158
+ - [Guides](https://docs.paybridgenp.com/guides/sandbox-testing)
159
+ - [Discord](https://discord.gg/aquta4JwJt)
160
+
161
+ ## License
162
+
163
+ MIT
@@ -0,0 +1,136 @@
1
+ # paybridge-np
2
+
3
+ Official Python SDK for the [PayBridgeNP](https://paybridgenp.com) payment gateway. Accept eSewa, Khalti, and ConnectIPS through a single API.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install paybridge-np
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```python
14
+ from paybridge_np import PayBridge
15
+
16
+ client = PayBridge(api_key="sk_live_...") # from dashboard.paybridgenp.com
17
+
18
+ # Create a checkout session
19
+ session = client.checkout.create({
20
+ "amount": 250000, # NPR 2,500 in paisa
21
+ "currency": "NPR",
22
+ "returnUrl": "https://mystore.com/success",
23
+ "cancelUrl": "https://mystore.com/cart",
24
+ "metadata": {"orderId": "ORD-7842"},
25
+ "customer": {
26
+ "name": "Ram Shrestha",
27
+ "email": "ram@example.com",
28
+ "phone": "9841000000",
29
+ },
30
+ })
31
+
32
+ # Redirect customer to hosted checkout
33
+ # session["checkout_url"] => https://paybridgenp.com/checkout/cs_xxx
34
+ ```
35
+
36
+ ## Payments
37
+
38
+ ```python
39
+ # List payments
40
+ result = client.payments.list(limit=20)
41
+ payments = result["data"]
42
+
43
+ # Get a single payment
44
+ payment = client.payments.retrieve("pay_xxx")
45
+ ```
46
+
47
+ ## Refunds
48
+
49
+ ```python
50
+ refund = client.refunds.create({
51
+ "paymentId": "pay_xxx",
52
+ "amount": 100000, # NPR 1,000 in paisa
53
+ "reason": "customer_request",
54
+ })
55
+ ```
56
+
57
+ ## Webhooks
58
+
59
+ ```python
60
+ # Register an endpoint
61
+ endpoint = client.webhooks.create(
62
+ url="https://mystore.com/webhooks/paybridge",
63
+ events=["payment.succeeded", "payment.failed"],
64
+ )
65
+
66
+ # Verify a webhook signature (no client instance needed)
67
+ from paybridge_np.resources.webhooks import WebhooksResource
68
+
69
+ event = WebhooksResource.construct_event(
70
+ body=raw_body,
71
+ signature=request.headers["X-PayBridge-Signature"],
72
+ secret="whsec_...",
73
+ )
74
+ ```
75
+
76
+ ## Billing (Subscriptions)
77
+
78
+ ```python
79
+ # Create a plan
80
+ plan = client.plans.create({
81
+ "name": "Pro Monthly",
82
+ "amount": 99900,
83
+ "intervalUnit": "month",
84
+ })
85
+
86
+ # Create a customer
87
+ customer = client.customers.create({
88
+ "name": "Sita Gurung",
89
+ "email": "sita@example.com",
90
+ })
91
+
92
+ # Subscribe
93
+ subscription = client.subscriptions.create({
94
+ "customerId": customer["id"],
95
+ "planId": plan["id"],
96
+ })
97
+
98
+ # List invoices
99
+ invoices = client.invoices.list(customer_id=customer["id"])
100
+ ```
101
+
102
+ ## Sandbox mode
103
+
104
+ Use a sandbox API key (`sk_sandbox_...`) to test without real money. The SDK automatically routes to sandbox endpoints.
105
+
106
+ ## Error handling
107
+
108
+ ```python
109
+ from paybridge_np import PayBridgeError, AuthenticationError
110
+
111
+ try:
112
+ session = client.checkout.create({...})
113
+ except AuthenticationError:
114
+ print("Invalid API key")
115
+ except PayBridgeError as e:
116
+ print(e, e.status_code)
117
+ ```
118
+
119
+ ## Context manager
120
+
121
+ ```python
122
+ with PayBridge(api_key="sk_live_...") as client:
123
+ session = client.checkout.create({...})
124
+ # HTTP client is closed automatically
125
+ ```
126
+
127
+ ## Documentation
128
+
129
+ - [API Reference](https://docs.paybridgenp.com)
130
+ - [Dashboard](https://dashboard.paybridgenp.com)
131
+ - [Guides](https://docs.paybridgenp.com/guides/sandbox-testing)
132
+ - [Discord](https://discord.gg/aquta4JwJt)
133
+
134
+ ## License
135
+
136
+ MIT
@@ -0,0 +1,48 @@
1
+ [build-system]
2
+ requires = ["hatchling<1.22"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "paybridge-np"
7
+ version = "0.1.0"
8
+ description = "Official Python SDK for the PayBridgeNP payment gateway - accept eSewa, Khalti, and ConnectIPS through a single API"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.9"
12
+ authors = [{ name = "PayBridgeNP", email = "support@paybridgenp.com" }]
13
+ keywords = [
14
+ "paybridge",
15
+ "nepal",
16
+ "payments",
17
+ "esewa",
18
+ "khalti",
19
+ "connectips",
20
+ "payment-gateway",
21
+ "nepal-payments",
22
+ ]
23
+ classifiers = [
24
+ "Development Status :: 4 - Beta",
25
+ "Intended Audience :: Developers",
26
+ "License :: OSI Approved :: MIT License",
27
+ "Programming Language :: Python :: 3",
28
+ "Programming Language :: Python :: 3.9",
29
+ "Programming Language :: Python :: 3.10",
30
+ "Programming Language :: Python :: 3.11",
31
+ "Programming Language :: Python :: 3.12",
32
+ "Programming Language :: Python :: 3.13",
33
+ "Topic :: Software Development :: Libraries :: Python Modules",
34
+ "Typing :: Typed",
35
+ ]
36
+ dependencies = ["httpx>=0.24.0"]
37
+
38
+ [project.urls]
39
+ Homepage = "https://paybridgenp.com"
40
+ Documentation = "https://docs.paybridgenp.com"
41
+ Repository = "https://github.com/paybridgenp/paybridgenp-python-sdk"
42
+ Issues = "https://github.com/paybridgenp/paybridgenp-python-sdk/issues"
43
+
44
+ [tool.hatch.build.targets.wheel]
45
+ packages = ["src/paybridge_np"]
46
+
47
+ [tool.pytest.ini_options]
48
+ testpaths = ["tests"]
@@ -0,0 +1,26 @@
1
+ """Official Python SDK for the PayBridgeNP payment gateway."""
2
+
3
+ from .client import PayBridge
4
+ from .errors import (
5
+ PayBridgeError,
6
+ AuthenticationError,
7
+ InvalidRequestError,
8
+ NotFoundError,
9
+ RateLimitError,
10
+ ConnectionError as PayBridgeConnectionError,
11
+ SignatureVerificationError,
12
+ )
13
+
14
+ SDK_VERSION = "0.1.0"
15
+
16
+ __all__ = [
17
+ "PayBridge",
18
+ "PayBridgeError",
19
+ "AuthenticationError",
20
+ "InvalidRequestError",
21
+ "NotFoundError",
22
+ "RateLimitError",
23
+ "PayBridgeConnectionError",
24
+ "SignatureVerificationError",
25
+ "SDK_VERSION",
26
+ ]
@@ -0,0 +1,112 @@
1
+ """Main PayBridge client."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from .http import HttpClient
6
+ from .resources.checkout import CheckoutResource
7
+ from .resources.payments import PaymentsResource
8
+ from .resources.refunds import RefundsResource
9
+ from .resources.webhooks import WebhooksResource
10
+ from .resources.plans import PlansResource
11
+ from .resources.customers import CustomersResource
12
+ from .resources.subscriptions import SubscriptionsResource
13
+ from .resources.invoices import InvoicesResource
14
+
15
+
16
+ class PayBridge:
17
+ """PayBridgeNP API client.
18
+
19
+ Usage::
20
+
21
+ from paybridge_np import PayBridge
22
+
23
+ client = PayBridge(api_key="sk_live_...")
24
+ session = client.checkout.create({
25
+ "amount": 250000,
26
+ "returnUrl": "https://mystore.com/success",
27
+ })
28
+ """
29
+
30
+ # Static webhook utility -- no instance required for signature verification.
31
+ webhooks_static = WebhooksResource()
32
+
33
+ def __init__(
34
+ self,
35
+ api_key: str,
36
+ *,
37
+ base_url: str | None = None,
38
+ timeout: float | None = None,
39
+ max_retries: int | None = None,
40
+ ) -> None:
41
+ self._http = HttpClient(
42
+ api_key=api_key,
43
+ base_url=base_url,
44
+ timeout=timeout,
45
+ max_retries=max_retries,
46
+ )
47
+ self._checkout: CheckoutResource | None = None
48
+ self._payments: PaymentsResource | None = None
49
+ self._refunds: RefundsResource | None = None
50
+ self._webhooks: WebhooksResource | None = None
51
+ self._plans: PlansResource | None = None
52
+ self._customers: CustomersResource | None = None
53
+ self._subscriptions: SubscriptionsResource | None = None
54
+ self._invoices: InvoicesResource | None = None
55
+
56
+ @property
57
+ def checkout(self) -> CheckoutResource:
58
+ if self._checkout is None:
59
+ self._checkout = CheckoutResource(self._http)
60
+ return self._checkout
61
+
62
+ @property
63
+ def payments(self) -> PaymentsResource:
64
+ if self._payments is None:
65
+ self._payments = PaymentsResource(self._http)
66
+ return self._payments
67
+
68
+ @property
69
+ def refunds(self) -> RefundsResource:
70
+ if self._refunds is None:
71
+ self._refunds = RefundsResource(self._http)
72
+ return self._refunds
73
+
74
+ @property
75
+ def webhooks(self) -> WebhooksResource:
76
+ if self._webhooks is None:
77
+ self._webhooks = WebhooksResource(self._http)
78
+ return self._webhooks
79
+
80
+ @property
81
+ def plans(self) -> PlansResource:
82
+ if self._plans is None:
83
+ self._plans = PlansResource(self._http)
84
+ return self._plans
85
+
86
+ @property
87
+ def customers(self) -> CustomersResource:
88
+ if self._customers is None:
89
+ self._customers = CustomersResource(self._http)
90
+ return self._customers
91
+
92
+ @property
93
+ def subscriptions(self) -> SubscriptionsResource:
94
+ if self._subscriptions is None:
95
+ self._subscriptions = SubscriptionsResource(self._http)
96
+ return self._subscriptions
97
+
98
+ @property
99
+ def invoices(self) -> InvoicesResource:
100
+ if self._invoices is None:
101
+ self._invoices = InvoicesResource(self._http)
102
+ return self._invoices
103
+
104
+ def close(self) -> None:
105
+ """Close the underlying HTTP client."""
106
+ self._http.close()
107
+
108
+ def __enter__(self) -> PayBridge:
109
+ return self
110
+
111
+ def __exit__(self, *args: object) -> None:
112
+ self.close()
@@ -0,0 +1,74 @@
1
+ """PayBridgeNP SDK error types."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+
8
+ class PayBridgeError(Exception):
9
+ """Base error for all PayBridgeNP API errors."""
10
+
11
+ def __init__(
12
+ self,
13
+ message: str,
14
+ status_code: int = 0,
15
+ code: str = "api_error",
16
+ raw: dict[str, Any] | None = None,
17
+ ) -> None:
18
+ super().__init__(message)
19
+ self.status_code = status_code
20
+ self.code = code
21
+ self.raw = raw
22
+
23
+ def to_dict(self) -> dict[str, Any]:
24
+ return {
25
+ "name": type(self).__name__,
26
+ "message": str(self),
27
+ "code": self.code,
28
+ "status_code": self.status_code,
29
+ "raw": self.raw,
30
+ }
31
+
32
+
33
+ class AuthenticationError(PayBridgeError):
34
+ def __init__(self, message: str, raw: dict[str, Any] | None = None) -> None:
35
+ super().__init__(message, 401, "authentication_error", raw)
36
+
37
+
38
+ class InvalidRequestError(PayBridgeError):
39
+ def __init__(self, message: str, raw: dict[str, Any] | None = None) -> None:
40
+ super().__init__(message, 400, "invalid_request_error", raw)
41
+
42
+
43
+ class NotFoundError(PayBridgeError):
44
+ def __init__(self, message: str, raw: dict[str, Any] | None = None) -> None:
45
+ super().__init__(message, 404, "not_found_error", raw)
46
+
47
+
48
+ class RateLimitError(PayBridgeError):
49
+ def __init__(self, message: str, raw: dict[str, Any] | None = None) -> None:
50
+ super().__init__(message, 429, "rate_limit_error", raw)
51
+
52
+
53
+ class ConnectionError(PayBridgeError):
54
+ def __init__(self, message: str) -> None:
55
+ super().__init__(f"Connection error: {message}", 0, "connection_error")
56
+
57
+
58
+ class SignatureVerificationError(PayBridgeError):
59
+ def __init__(self, message: str = "Webhook signature verification failed") -> None:
60
+ super().__init__(message, 0, "signature_verification_error")
61
+
62
+
63
+ def create_error(
64
+ message: str, status_code: int, raw: dict[str, Any] | None
65
+ ) -> PayBridgeError:
66
+ if status_code == 401:
67
+ return AuthenticationError(message, raw)
68
+ if status_code == 404:
69
+ return NotFoundError(message, raw)
70
+ if status_code in (400, 422):
71
+ return InvalidRequestError(message, raw)
72
+ if status_code == 429:
73
+ return RateLimitError(message, raw)
74
+ return PayBridgeError(message, status_code, "api_error", raw)
@@ -0,0 +1,89 @@
1
+ """HTTP client with retries and exponential backoff."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import random
6
+ import time
7
+ from typing import Any
8
+
9
+ import httpx
10
+
11
+ from .errors import PayBridgeError, ConnectionError, create_error
12
+
13
+ DEFAULT_BASE_URL = "https://api.paybridgenp.com"
14
+ DEFAULT_TIMEOUT = 30.0
15
+ DEFAULT_MAX_RETRIES = 2
16
+ RETRY_STATUSES = {500, 502, 503, 504}
17
+ INITIAL_BACKOFF_S = 0.5
18
+
19
+
20
+ def _backoff(attempt: int) -> float:
21
+ return INITIAL_BACKOFF_S * (2 ** (attempt - 1)) + random.random() * 0.1
22
+
23
+
24
+ class HttpClient:
25
+ def __init__(
26
+ self,
27
+ api_key: str,
28
+ base_url: str | None = None,
29
+ timeout: float | None = None,
30
+ max_retries: int | None = None,
31
+ ) -> None:
32
+ self._base_url = (base_url or DEFAULT_BASE_URL).rstrip("/")
33
+ self._api_key = api_key
34
+ self._timeout = timeout or DEFAULT_TIMEOUT
35
+ self._max_retries = max_retries if max_retries is not None else DEFAULT_MAX_RETRIES
36
+ self._client = httpx.Client(
37
+ base_url=self._base_url,
38
+ timeout=self._timeout,
39
+ headers={
40
+ "Authorization": f"Bearer {self._api_key}",
41
+ "Content-Type": "application/json",
42
+ "User-Agent": "PayBridgeNP-Python/0.1.0",
43
+ },
44
+ )
45
+
46
+ def request(self, method: str, path: str, json: Any = None) -> Any:
47
+ attempt = 0
48
+ while True:
49
+ attempt += 1
50
+ try:
51
+ resp = self._client.request(method, path, json=json)
52
+ except httpx.HTTPError as exc:
53
+ if attempt > self._max_retries:
54
+ raise ConnectionError(str(exc)) from exc
55
+ time.sleep(_backoff(attempt))
56
+ continue
57
+
58
+ if resp.is_success:
59
+ return resp.json()
60
+
61
+ if resp.status_code in RETRY_STATUSES and attempt <= self._max_retries:
62
+ retry_after = resp.headers.get("Retry-After")
63
+ delay = float(retry_after) if retry_after else _backoff(attempt)
64
+ time.sleep(delay)
65
+ continue
66
+
67
+ raw: dict[str, Any] | None = None
68
+ try:
69
+ raw = resp.json()
70
+ except Exception:
71
+ pass
72
+
73
+ message = raw.get("error", f"HTTP {resp.status_code}") if raw and isinstance(raw.get("error"), str) else f"HTTP {resp.status_code}"
74
+ raise create_error(message, resp.status_code, raw)
75
+
76
+ def get(self, path: str) -> Any:
77
+ return self.request("GET", path)
78
+
79
+ def post(self, path: str, json: Any) -> Any:
80
+ return self.request("POST", path, json=json)
81
+
82
+ def patch(self, path: str, json: Any) -> Any:
83
+ return self.request("PATCH", path, json=json)
84
+
85
+ def delete(self, path: str) -> Any:
86
+ return self.request("DELETE", path)
87
+
88
+ def close(self) -> None:
89
+ self._client.close()
File without changes