smspva-sdk 0.1.0a1__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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 SMSPVA
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,3 @@
1
+ include METHODS.md
2
+ include LICENSE
3
+ prune tests
@@ -0,0 +1,76 @@
1
+ # SDK method index
2
+
3
+ All six packages cover these same 56 methods. Both Python clients use the Python names. PHP and Java use the JavaScript camelCase method names, with their own resource access syntax. Go capitalizes the first letter (for example, `GetBalance`); C# also appends `Async` (`GetBalanceAsync`). See each package README for request types and working usage. Parameters retain their API spelling.
4
+
5
+ ## activation
6
+
7
+ | Python (sync and async) | JavaScript / TypeScript | HTTP |
8
+ | --- | --- | --- |
9
+ | `client.activation.get_balance` | `client.activation.getBalance` | `GET /activation/balance` |
10
+ | `client.activation.get_user_info` | `client.activation.getUserInfo` | `GET /activation/userinfo` |
11
+ | `client.activation.get_operators` | `client.activation.getOperators` | `GET /activation/operators/{country}` |
12
+ | `client.activation.get_conversions` | `client.activation.getConversions` | `GET /activation/conversions/{service}` |
13
+ | `client.activation.get_message_type_settings` | `client.activation.getMessageTypeSettings` | `GET /activation/countryservicesettings` |
14
+ | `client.activation.get_all_number_counts` | `client.activation.getAllNumberCounts` | `GET /activation/countnumbers` |
15
+ | `client.activation.get_country_number_counts` | `client.activation.getCountryNumberCounts` | `GET /activation/countnumbers/{country}` |
16
+ | `client.activation.get_service_price` | `client.activation.getServicePrice` | `GET /activation/serviceprice/{country}/{service}` |
17
+ | `client.activation.get_country_operator_prices` | `client.activation.getCountryOperatorPrices` | `GET /activation/serviceprice/{country}` |
18
+ | `client.activation.get_service_prices` | `client.activation.getServicePrices` | `GET /activation/serviceprices/{service}` |
19
+ | `client.activation.get_all_service_prices` | `client.activation.getAllServicePrices` | `GET /activation/servicesprices` |
20
+ | `client.activation.get_number` | `client.activation.getNumber` | `GET /activation/number/{country}/{service}` |
21
+ | `client.activation.get_number_by_operator` | `client.activation.getNumberByOperator` | `GET /activation/number/{country}/{service}/{operator}` |
22
+ | `client.activation.receive_sms` | `client.activation.receiveSms` | `GET /activation/sms/{orderid}` |
23
+ | `client.activation.get_orders` | `client.activation.getOrders` | `GET /activation/orders` |
24
+ | `client.activation.get_number_status` | `client.activation.getNumberStatus` | `GET /activation/numberstatus/{number}/{service}` |
25
+ | `client.activation.clear_sms` | `client.activation.clearSms` | `PUT /activation/clearsms/{orderid}` |
26
+ | `client.activation.stop_sms` | `client.activation.stopSms` | `PUT /activation/stopsms/{orderid}` |
27
+ | `client.activation.cancel_order` | `client.activation.cancelOrder` | `PUT /activation/cancelorder/{orderid}` |
28
+ | `client.activation.block_number` | `client.activation.blockNumber` | `PUT /activation/blocknumber/{orderid}` |
29
+
30
+ ## rental
31
+
32
+ | Python (sync and async) | JavaScript / TypeScript | HTTP |
33
+ | --- | --- | --- |
34
+ | `client.rental.get_countries` | `client.rental.getCountries` | `GET /api/rent.php?method=getcountries` |
35
+ | `client.rental.get_default_services` | `client.rental.getDefaultServices` | `GET /api/rent.php?method=get_default_services` |
36
+ | `client.rental.get_countries_by_service` | `client.rental.getCountriesByService` | `GET /api/rent.php?method=get_country_by_service` |
37
+ | `client.rental.get_data` | `client.rental.getData` | `GET /api/rent.php?method=getdata` |
38
+ | `client.rental.get_data_with_providers` | `client.rental.getDataWithProviders` | `GET /api/rent.php?method=getdataWithProviders` |
39
+ | `client.rental.get_count` | `client.rental.getCount` | `GET /api/rent.php?method=getcount` |
40
+ | `client.rental.get_count_with_providers` | `client.rental.getCountWithProviders` | `GET /api/rent.php?method=getCountWithProviders` |
41
+ | `client.rental.get_multi_service_count` | `client.rental.getMultiServiceCount` | `GET /api/rent.php?method=get_count_multi` |
42
+ | `client.rental.get_canada_paypal_days` | `client.rental.getCanadaPaypalDays` | `GET /api/rent.php?method=get_days_canada_paypal` |
43
+ | `client.rental.get_minimum_paypal_days` | `client.rental.getMinimumPaypalDays` | `GET /api/rent.php?method=get_min_paypal_days` |
44
+ | `client.rental.create` | `client.rental.create` | `GET /api/rent.php?method=create` |
45
+ | `client.rental.create_multi` | `client.rental.createMulti` | `GET /api/rent.php?method=create_multi` |
46
+ | `client.rental.add_service_to_order` | `client.rental.addServiceToOrder` | `GET /api/rent.php?method=add_service_to_order` |
47
+ | `client.rental.get_orders` | `client.rental.getOrders` | `GET /api/rent.php?method=orders` |
48
+ | `client.rental.activate` | `client.rental.activate` | `GET /api/rent.php?method=activate` |
49
+ | `client.rental.get_sms` | `client.rental.getSms` | `GET /api/rent.php?method=sms` |
50
+ | `client.rental.prolong` | `client.rental.prolong` | `GET /api/rent.php?method=prolong` |
51
+ | `client.rental.prolong_by_days` | `client.rental.prolongByDays` | `GET /api/rent.php?method=prolong_max` |
52
+ | `client.rental.delete_order` | `client.rental.deleteOrder` | `GET /api/rent.php?method=delete` |
53
+ | `client.rental.get_history` | `client.rental.getHistory` | `GET /api/rent.php?method=get_rent_history` |
54
+ | `client.rental.get_restore_cost` | `client.rental.getRestoreCost` | `GET /api/rent.php?method=restore_user_precalc` |
55
+ | `client.rental.restore` | `client.rental.restore` | `GET /api/rent.php?method=restore_user` |
56
+
57
+ ## email
58
+
59
+ | Python (sync and async) | JavaScript / TypeScript | HTTP |
60
+ | --- | --- | --- |
61
+ | `client.email.get_providers` | `client.email.getProviders` | `GET /api/rent_email.php?method=get_providers` |
62
+ | `client.email.get_data` | `client.email.getData` | `GET /api/rent_email.php?method=get_data` |
63
+ | `client.email.get_count` | `client.email.getCount` | `GET /api/rent_email.php?method=get_count` |
64
+ | `client.email.create_order` | `client.email.createOrder` | `GET /api/rent_email.php?method=create_order` |
65
+ | `client.email.get_orders` | `client.email.getOrders` | `GET /api/rent_email.php?method=get_orders` |
66
+ | `client.email.get_mails` | `client.email.getMails` | `GET /api/rent_email.php?method=get_mails` |
67
+ | `client.email.get_mail_body` | `client.email.getMailBody` | `GET /api/rent_email.php?method=get_mail_body` |
68
+ | `client.email.buy_alias` | `client.email.buyAlias` | `GET /api/rent_email.php?method=buy_alias` |
69
+ | `client.email.get_mails_by_alias` | `client.email.getMailsByAlias` | `GET /api/rent_email.php?method=get_mails_by_alias` |
70
+ | `client.email.prolong_order` | `client.email.prolongOrder` | `GET /api/rent_email.php?method=prolong_order` |
71
+ | `client.email.cancel_order` | `client.email.cancelOrder` | `GET /api/rent_email.php?method=cancel_order` |
72
+ | `client.email.get_archived_orders` | `client.email.getArchivedOrders` | `GET /api/rent_email.php?method=get_archived_orders` |
73
+ | `client.email.calc_restore_order` | `client.email.calcRestoreOrder` | `GET /api/rent_email.php?method=calc_restore_order` |
74
+ | `client.email.restore_order` | `client.email.restoreOrder` | `GET /api/rent_email.php?method=restore_order` |
75
+
76
+ Activation also provides `wait_for_sms` / `waitForSms`. It polls an existing order until a caller-supplied expiry, without purchasing or cancelling an order.
@@ -0,0 +1,135 @@
1
+ Metadata-Version: 2.4
2
+ Name: smspva-sdk
3
+ Version: 0.1.0a1
4
+ Summary: Typed sync and async clients for SMSPVA Activation V2, Rental and Private Email
5
+ License-Expression: MIT
6
+ Project-URL: Homepage, https://github.com/SMSPVA/smspva-python
7
+ Project-URL: Documentation, https://docs.smspva.com
8
+ Project-URL: Repository, https://github.com/SMSPVA/smspva-python
9
+ Project-URL: Issues, https://github.com/SMSPVA/smspva-python/issues
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Typing :: Typed
12
+ Classifier: Programming Language :: Python :: 3
13
+ Requires-Python: >=3.10
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Requires-Dist: httpx<1,>=0.28
17
+ Requires-Dist: typing_extensions>=4.12
18
+ Dynamic: license-file
19
+
20
+ # SMSPVA Python SDK
21
+
22
+ [![CI](https://github.com/SMSPVA/smspva-python/actions/workflows/ci.yml/badge.svg)](https://github.com/SMSPVA/smspva-python/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) ![Status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)
23
+
24
+ Python 3.10+, synchronous `SMSPVA` and asynchronous `AsyncSMSPVA`, with the same 56 typed methods. Covers Activation V2 (20), Rental (22) and Private Email (14). Alternative API is excluded. This is an alpha release. PyPI publication is pending.
25
+
26
+ Install from source:
27
+
28
+ ```sh
29
+ git clone https://github.com/SMSPVA/smspva-python.git
30
+ cd smspva-python
31
+ python -m pip install .
32
+ ```
33
+
34
+ ```python
35
+ import os
36
+ from smspva import SMSPVA
37
+
38
+ with SMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
39
+ print(client.activation.get_balance())
40
+ print(client.rental.get_countries())
41
+ print(client.email.get_providers())
42
+ ```
43
+
44
+ ```python
45
+ import asyncio
46
+ import os
47
+ from smspva import AsyncSMSPVA
48
+
49
+ async def main():
50
+ async with AsyncSMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
51
+ result = await client.activation.get_balance()
52
+ print(result)
53
+
54
+ asyncio.run(main())
55
+ ```
56
+
57
+ Use the client as a context manager, or call `close()` / `await aclose()` yourself. Async uses HTTPX `AsyncClient`, not worker threads.
58
+
59
+ ## Requests and results
60
+
61
+ - Activation V2 sends the key in the `apikey` header. Rental and Email use the `apikey` query parameter. Public methods send no key or cookies. Optional-key rental methods use the client key unless you pass `use_api_key=False`.
62
+ - Returned dictionaries preserve wire field names and values, including string prices, timestamps, and IDs. Types follow the source schemas; a field not marked required remains optional.
63
+ - `is_pending(result)` recognises Activation SMS HTTP 202 / `SMS_NOT_YET_RECEIVED`. `is_no_stock(result)` recognises Email creation `status=2`. Both return the original response instead of raising a generic error.
64
+ - All documented optional parameters are available, including `partnerkey`, `partner_key`, `provider`, `extend`, pagination and search. Query and path values are encoded. Email `pcode=None` or `pcode=""` is omitted entirely.
65
+ - `rental.get_multi_service_count` requires explicit `dtype` and `dcount` because the docs warn that backend defaults are unreliable. The wire method remains `get_count_multi`.
66
+
67
+ ```python
68
+ # Public reference data, without an API key.
69
+ with SMSPVA() as client:
70
+ services = client.email.get_data(pcode="CODE_FROM_GET_PROVIDERS")
71
+ ```
72
+
73
+ Paid example (run only when you intend to create a rental):
74
+
75
+ ```python
76
+ from smspva import is_no_stock
77
+
78
+ with SMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
79
+ result = client.email.create_order(
80
+ scode="CODE_FROM_GET_DATA", dtype="week", dcount=1
81
+ )
82
+ if is_no_stock(result):
83
+ print("No mailbox available; refresh counts before trying again.")
84
+ else:
85
+ print(result)
86
+ ```
87
+
88
+ ## Waiting for SMS
89
+
90
+ Save an expiry once when the number is created. `wait_for_sms` polls only Receive SMS, never creates another order, and stops on terminal errors, expiry or a transport failure. A new SMS retrieval can trigger payment.
91
+
92
+ ```python
93
+ import time
94
+
95
+ # number_result is the successful response from your own get_number request.
96
+ expires_at = time.time() + number_result["data"]["orderExpireIn"]
97
+ result = client.activation.wait_for_sms(
98
+ orderid=number_result["data"]["orderId"], expires_at=expires_at
99
+ )
100
+ ```
101
+
102
+ Use `await client.activation.wait_for_sms(...)` with `AsyncSMSPVA`. The helper waits at least five seconds between pending responses; this is a helper policy, not a claim about an API-wide rate limit. Request deadlines are bounded by the saved expiry. HTTPX timeouts apply to individual network operations; the async polling helper also enforces an overall remaining deadline.
103
+
104
+ ## Errors and timeouts
105
+
106
+ `ApiError` retains `family`, `operation`, `http_status`, `code` and the original `response`. `ProtocolError` means the body was not a usable JSON envelope. `TransportError` and `RequestTimeoutError` mean the request outcome may be unknown (`outcome_unknown` for state-changing/paid methods). No requests are retried automatically; inspect current orders before repeating a paid operation.
107
+
108
+ Exception messages omit request URLs and keys. Query credentials may still appear if you enable HTTPX request logging; redact those logs. Do not put account keys in browser code.
109
+
110
+ The default timeout is 30 seconds per HTTPX network operation. Override at client construction or per call with `timeout=...`. Advanced transports, proxies and test doubles can be supplied through `transport=httpx.HTTPTransport(...)` or `httpx.AsyncHTTPTransport(...)`; environment proxies/cookies are not inherited. Redirects are never followed.
111
+
112
+ The generated method index is in `METHODS.md`. Response TypedDicts and input aliases are available in `smspva.types`; the package includes `py.typed`.
113
+
114
+ ## License
115
+
116
+ MIT. See [LICENSE](LICENSE).
117
+
118
+ ## Development
119
+
120
+ ```sh
121
+ python -m pip install -e . build mypy
122
+ python -m unittest discover -s tests -v
123
+ python -m mypy
124
+ python -m build
125
+ ```
126
+
127
+ Tests use synthetic fixtures and local transports; they do not buy numbers or call the production API.
128
+
129
+ ## Documentation
130
+
131
+ [API documentation](https://docs.smspva.com)
132
+
133
+ The new documentation is being prepared in English, Spanish and Chinese. Localized links will be added when it is deployed.
134
+
135
+ The SDK covers Activation V2, Rental and Private Email. Alternative API is not supported.
@@ -0,0 +1,116 @@
1
+ # SMSPVA Python SDK
2
+
3
+ [![CI](https://github.com/SMSPVA/smspva-python/actions/workflows/ci.yml/badge.svg)](https://github.com/SMSPVA/smspva-python/actions/workflows/ci.yml) [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) ![Status: alpha](https://img.shields.io/badge/status-alpha-orange.svg)
4
+
5
+ Python 3.10+, synchronous `SMSPVA` and asynchronous `AsyncSMSPVA`, with the same 56 typed methods. Covers Activation V2 (20), Rental (22) and Private Email (14). Alternative API is excluded. This is an alpha release. PyPI publication is pending.
6
+
7
+ Install from source:
8
+
9
+ ```sh
10
+ git clone https://github.com/SMSPVA/smspva-python.git
11
+ cd smspva-python
12
+ python -m pip install .
13
+ ```
14
+
15
+ ```python
16
+ import os
17
+ from smspva import SMSPVA
18
+
19
+ with SMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
20
+ print(client.activation.get_balance())
21
+ print(client.rental.get_countries())
22
+ print(client.email.get_providers())
23
+ ```
24
+
25
+ ```python
26
+ import asyncio
27
+ import os
28
+ from smspva import AsyncSMSPVA
29
+
30
+ async def main():
31
+ async with AsyncSMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
32
+ result = await client.activation.get_balance()
33
+ print(result)
34
+
35
+ asyncio.run(main())
36
+ ```
37
+
38
+ Use the client as a context manager, or call `close()` / `await aclose()` yourself. Async uses HTTPX `AsyncClient`, not worker threads.
39
+
40
+ ## Requests and results
41
+
42
+ - Activation V2 sends the key in the `apikey` header. Rental and Email use the `apikey` query parameter. Public methods send no key or cookies. Optional-key rental methods use the client key unless you pass `use_api_key=False`.
43
+ - Returned dictionaries preserve wire field names and values, including string prices, timestamps, and IDs. Types follow the source schemas; a field not marked required remains optional.
44
+ - `is_pending(result)` recognises Activation SMS HTTP 202 / `SMS_NOT_YET_RECEIVED`. `is_no_stock(result)` recognises Email creation `status=2`. Both return the original response instead of raising a generic error.
45
+ - All documented optional parameters are available, including `partnerkey`, `partner_key`, `provider`, `extend`, pagination and search. Query and path values are encoded. Email `pcode=None` or `pcode=""` is omitted entirely.
46
+ - `rental.get_multi_service_count` requires explicit `dtype` and `dcount` because the docs warn that backend defaults are unreliable. The wire method remains `get_count_multi`.
47
+
48
+ ```python
49
+ # Public reference data, without an API key.
50
+ with SMSPVA() as client:
51
+ services = client.email.get_data(pcode="CODE_FROM_GET_PROVIDERS")
52
+ ```
53
+
54
+ Paid example (run only when you intend to create a rental):
55
+
56
+ ```python
57
+ from smspva import is_no_stock
58
+
59
+ with SMSPVA(os.environ["SMSPVA_API_KEY"]) as client:
60
+ result = client.email.create_order(
61
+ scode="CODE_FROM_GET_DATA", dtype="week", dcount=1
62
+ )
63
+ if is_no_stock(result):
64
+ print("No mailbox available; refresh counts before trying again.")
65
+ else:
66
+ print(result)
67
+ ```
68
+
69
+ ## Waiting for SMS
70
+
71
+ Save an expiry once when the number is created. `wait_for_sms` polls only Receive SMS, never creates another order, and stops on terminal errors, expiry or a transport failure. A new SMS retrieval can trigger payment.
72
+
73
+ ```python
74
+ import time
75
+
76
+ # number_result is the successful response from your own get_number request.
77
+ expires_at = time.time() + number_result["data"]["orderExpireIn"]
78
+ result = client.activation.wait_for_sms(
79
+ orderid=number_result["data"]["orderId"], expires_at=expires_at
80
+ )
81
+ ```
82
+
83
+ Use `await client.activation.wait_for_sms(...)` with `AsyncSMSPVA`. The helper waits at least five seconds between pending responses; this is a helper policy, not a claim about an API-wide rate limit. Request deadlines are bounded by the saved expiry. HTTPX timeouts apply to individual network operations; the async polling helper also enforces an overall remaining deadline.
84
+
85
+ ## Errors and timeouts
86
+
87
+ `ApiError` retains `family`, `operation`, `http_status`, `code` and the original `response`. `ProtocolError` means the body was not a usable JSON envelope. `TransportError` and `RequestTimeoutError` mean the request outcome may be unknown (`outcome_unknown` for state-changing/paid methods). No requests are retried automatically; inspect current orders before repeating a paid operation.
88
+
89
+ Exception messages omit request URLs and keys. Query credentials may still appear if you enable HTTPX request logging; redact those logs. Do not put account keys in browser code.
90
+
91
+ The default timeout is 30 seconds per HTTPX network operation. Override at client construction or per call with `timeout=...`. Advanced transports, proxies and test doubles can be supplied through `transport=httpx.HTTPTransport(...)` or `httpx.AsyncHTTPTransport(...)`; environment proxies/cookies are not inherited. Redirects are never followed.
92
+
93
+ The generated method index is in `METHODS.md`. Response TypedDicts and input aliases are available in `smspva.types`; the package includes `py.typed`.
94
+
95
+ ## License
96
+
97
+ MIT. See [LICENSE](LICENSE).
98
+
99
+ ## Development
100
+
101
+ ```sh
102
+ python -m pip install -e . build mypy
103
+ python -m unittest discover -s tests -v
104
+ python -m mypy
105
+ python -m build
106
+ ```
107
+
108
+ Tests use synthetic fixtures and local transports; they do not buy numbers or call the production API.
109
+
110
+ ## Documentation
111
+
112
+ [API documentation](https://docs.smspva.com)
113
+
114
+ The new documentation is being prepared in English, Spanish and Chinese. Localized links will be added when it is deployed.
115
+
116
+ The SDK covers Activation V2, Rental and Private Email. Alternative API is not supported.
@@ -0,0 +1,34 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "smspva-sdk"
7
+ version = "0.1.0a1"
8
+ description = "Typed sync and async clients for SMSPVA Activation V2, Rental and Private Email"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ requires-python = ">=3.10"
13
+ dependencies = ["httpx>=0.28,<1", "typing_extensions>=4.12"]
14
+ classifiers = ["Development Status :: 3 - Alpha", "Typing :: Typed", "Programming Language :: Python :: 3"]
15
+
16
+ [tool.setuptools.packages.find]
17
+ where = ["src"]
18
+
19
+ [tool.setuptools.package-data]
20
+ smspva = ["py.typed", "_contracts.json"]
21
+
22
+ [tool.mypy]
23
+ python_version = "3.10"
24
+ strict = true
25
+ files = ["src/smspva"]
26
+
27
+ [tool.setuptools]
28
+ include-package-data = true
29
+
30
+ [project.urls]
31
+ Homepage = "https://github.com/SMSPVA/smspva-python"
32
+ Documentation = "https://docs.smspva.com"
33
+ Repository = "https://github.com/SMSPVA/smspva-python"
34
+ Issues = "https://github.com/SMSPVA/smspva-python/issues"
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,6 @@
1
+ from ._client import SMSPVA, AsyncSMSPVA
2
+ from ._polling import is_pending, is_no_stock
3
+ from .errors import SMSPVAError, ApiError, ProtocolError, TransportError, RequestTimeoutError, PollingTimeoutError, ValidationError
4
+
5
+ __version__ = "0.1.0a1"
6
+ __all__ = ["SMSPVA", "AsyncSMSPVA", "is_pending", "is_no_stock", "SMSPVAError", "ApiError", "ProtocolError", "TransportError", "RequestTimeoutError", "PollingTimeoutError", "ValidationError"]
@@ -0,0 +1,43 @@
1
+ from __future__ import annotations
2
+
3
+ from types import TracebackType
4
+ import httpx
5
+
6
+ from ._transport import Transport, AsyncTransport
7
+ from ._resources import Activation, Rental, Email, AsyncActivation, AsyncRental, AsyncEmail
8
+
9
+
10
+ class SMSPVA:
11
+ def __init__(self, api_key: str | None = None, *, timeout: float = 30, activation_base_url: str | None = None,
12
+ rental_base_url: str | None = None, email_base_url: str | None = None, transport: httpx.BaseTransport | None = None):
13
+ self._transport = Transport(api_key, timeout, {"activation": activation_base_url, "rental": rental_base_url, "email": email_base_url}, transport)
14
+ self.activation = Activation(self._transport)
15
+ self.rental = Rental(self._transport)
16
+ self.email = Email(self._transport)
17
+
18
+ def close(self) -> None:
19
+ self._transport.close()
20
+
21
+ def __enter__(self) -> SMSPVA:
22
+ return self
23
+
24
+ def __exit__(self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None) -> None:
25
+ self.close()
26
+
27
+
28
+ class AsyncSMSPVA:
29
+ def __init__(self, api_key: str | None = None, *, timeout: float = 30, activation_base_url: str | None = None,
30
+ rental_base_url: str | None = None, email_base_url: str | None = None, transport: httpx.AsyncBaseTransport | None = None):
31
+ self._transport = AsyncTransport(api_key, timeout, {"activation": activation_base_url, "rental": rental_base_url, "email": email_base_url}, transport)
32
+ self.activation = AsyncActivation(self._transport)
33
+ self.rental = AsyncRental(self._transport)
34
+ self.email = AsyncEmail(self._transport)
35
+
36
+ async def aclose(self) -> None:
37
+ await self._transport.close()
38
+
39
+ async def __aenter__(self) -> AsyncSMSPVA:
40
+ return self
41
+
42
+ async def __aexit__(self, exc_type: type[BaseException] | None, exc: BaseException | None, tb: TracebackType | None) -> None:
43
+ await self.aclose()