gosms-python 1.0.3__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,87 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+
9
+ permissions:
10
+ contents: write
11
+
12
+ jobs:
13
+ test:
14
+ runs-on: ubuntu-latest
15
+ strategy:
16
+ matrix:
17
+ python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
18
+ steps:
19
+ - uses: actions/checkout@v4
20
+
21
+ - name: Set up Python ${{ matrix.python-version }}
22
+ uses: actions/setup-python@v5
23
+ with:
24
+ python-version: ${{ matrix.python-version }}
25
+
26
+ - name: Install dependencies
27
+ run: pip install -e ".[dev,async]"
28
+
29
+ - name: Lint
30
+ run: ruff check src/ tests/
31
+
32
+ - name: Test
33
+ run: pytest --tb=short -q
34
+
35
+ release:
36
+ needs: test
37
+ if: github.event_name == 'push' && github.ref == 'refs/heads/main'
38
+ runs-on: ubuntu-latest
39
+ outputs:
40
+ released: ${{ steps.semantic.outputs.new_release_published }}
41
+ version: ${{ steps.semantic.outputs.new_release_version }}
42
+ steps:
43
+ - uses: actions/checkout@v4
44
+ with:
45
+ fetch-depth: 0
46
+
47
+ - name: Semantic Release
48
+ id: semantic
49
+ uses: cycjimmy/semantic-release-action@v4
50
+ with:
51
+ extra_plugins: |
52
+ conventional-changelog-conventionalcommits@8
53
+ semantic_version: 24
54
+ env:
55
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
56
+
57
+ publish:
58
+ needs: release
59
+ if: needs.release.outputs.released == 'true'
60
+ runs-on: ubuntu-latest
61
+ steps:
62
+ - uses: actions/checkout@v4
63
+ with:
64
+ ref: main
65
+
66
+ - name: Set up Python
67
+ uses: actions/setup-python@v5
68
+ with:
69
+ python-version: "3.13"
70
+
71
+ - name: Set version from release
72
+ run: |
73
+ VERSION=${{ needs.release.outputs.version }}
74
+ sed -i "s/version = \".*\"/version = \"$VERSION\"/" pyproject.toml
75
+ sed -i "s/__version__ = \".*\"/__version__ = \"$VERSION\"/" src/gosms/__init__.py
76
+
77
+ - name: Install build tools
78
+ run: pip install build twine
79
+
80
+ - name: Build package
81
+ run: python -m build
82
+
83
+ - name: Publish to PyPI
84
+ run: twine upload dist/*
85
+ env:
86
+ TWINE_USERNAME: __token__
87
+ TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
@@ -0,0 +1,37 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+
7
+ # Distribution / packaging
8
+ dist/
9
+ build/
10
+ *.egg-info/
11
+ *.egg
12
+ pip-wheel-metadata/
13
+
14
+ # Virtual environments
15
+ .venv/
16
+ venv/
17
+ env/
18
+
19
+ # IDE
20
+ .idea/
21
+ .vscode/
22
+ *.swp
23
+ *.swo
24
+
25
+ # Testing
26
+ .pytest_cache/
27
+ .coverage
28
+ htmlcov/
29
+ .tox/
30
+
31
+ # Linting
32
+ .ruff_cache/
33
+ .mypy_cache/
34
+
35
+ # OS
36
+ .DS_Store
37
+ Thumbs.db
@@ -0,0 +1,12 @@
1
+ {
2
+ "branches": ["main"],
3
+ "plugins": [
4
+ ["@semantic-release/commit-analyzer", {
5
+ "preset": "conventionalcommits"
6
+ }],
7
+ ["@semantic-release/release-notes-generator", {
8
+ "preset": "conventionalcommits"
9
+ }],
10
+ "@semantic-release/github"
11
+ ]
12
+ }
@@ -0,0 +1,276 @@
1
+ Metadata-Version: 2.4
2
+ Name: gosms-python
3
+ Version: 1.0.3
4
+ Summary: Official Python SDK for GoSMS.GE SMS Gateway
5
+ Project-URL: Homepage, https://gosms.ge
6
+ Project-URL: Repository, https://github.com/gosms-ge/gosmsge-python
7
+ Project-URL: Issues, https://github.com/gosms-ge/gosmsge-python/issues
8
+ Author-email: "GoSMS.GE" <info@gosms.ge>
9
+ License-Expression: MIT
10
+ Keywords: gosms,otp,sms,sms-api,sms-gateway,sms-sdk
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Programming Language :: Python :: 3.13
20
+ Classifier: Topic :: Communications
21
+ Classifier: Typing :: Typed
22
+ Requires-Python: >=3.9
23
+ Requires-Dist: requests>=2.28.0
24
+ Provides-Extra: async
25
+ Requires-Dist: httpx>=0.24.0; extra == 'async'
26
+ Provides-Extra: dev
27
+ Requires-Dist: build; extra == 'dev'
28
+ Requires-Dist: pytest-asyncio>=0.21; extra == 'dev'
29
+ Requires-Dist: pytest-httpx>=0.21; extra == 'dev'
30
+ Requires-Dist: pytest>=7.0; extra == 'dev'
31
+ Requires-Dist: responses>=0.23; extra == 'dev'
32
+ Requires-Dist: ruff>=0.1; extra == 'dev'
33
+ Provides-Extra: django
34
+ Requires-Dist: django>=3.2; extra == 'django'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # GoSMS.GE Python SDK
38
+
39
+ [![PyPI version](https://img.shields.io/pypi/v/gosms-python.svg)](https://pypi.org/project/gosms-python/)
40
+ [![Python versions](https://img.shields.io/pypi/pyversions/gosms-python.svg)](https://pypi.org/project/gosms-python/)
41
+ [![Tests](https://github.com/gosms-python/gosms-python-python/actions/workflows/release.yml/badge.svg)](https://github.com/gosms-python/gosms-python-python/actions)
42
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
43
+
44
+ Official Python SDK for the [GoSMS.GE](https://gosms.ge) SMS gateway. Send SMS messages, manage OTP verification, and check balances with both sync and async clients.
45
+
46
+ ## Installation
47
+
48
+ ```bash
49
+ pip install gosms-python
50
+ ```
51
+
52
+ For async support:
53
+
54
+ ```bash
55
+ pip install gosms-python[async]
56
+ ```
57
+
58
+ ## Quick Start
59
+
60
+ ```python
61
+ from gosms import SMS
62
+
63
+ sms = SMS("your_api_key")
64
+
65
+ # Send a message
66
+ result = sms.send("995555123456", "Hello!", "GOSMS.GE")
67
+ print(result.message_id) # 12345
68
+ print(result.balance) # 99
69
+
70
+ # Check balance
71
+ balance = sms.balance()
72
+ print(balance.balance) # 500
73
+ ```
74
+
75
+ ## All Endpoints
76
+
77
+ ### Send SMS
78
+
79
+ ```python
80
+ result = sms.send("995555123456", "Hello!", "GOSMS.GE")
81
+ result = sms.send("995555123456", "Urgent!", "GOSMS.GE", urgent=True)
82
+ ```
83
+
84
+ ### Send Bulk SMS
85
+
86
+ ```python
87
+ result = sms.send_bulk(
88
+ "GOSMS.GE",
89
+ ["995555111111", "995555222222"],
90
+ "Hello everyone!",
91
+ )
92
+ print(result.total_count) # 2
93
+ print(result.success_count) # 2
94
+
95
+ for msg in result.messages:
96
+ print(f"{msg.to}: {msg.message_id}")
97
+ ```
98
+
99
+ ### Send OTP
100
+
101
+ ```python
102
+ result = sms.send_otp("995555123456")
103
+ print(result.hash) # "abc123hash" — save this for verification
104
+ ```
105
+
106
+ ### Verify OTP
107
+
108
+ ```python
109
+ result = sms.verify_otp("995555123456", "abc123hash", "1234")
110
+ print(result.verify) # True
111
+ ```
112
+
113
+ ### Check Message Status
114
+
115
+ ```python
116
+ result = sms.status(12345)
117
+ print(result.status) # "delivered"
118
+ ```
119
+
120
+ ### Check Balance
121
+
122
+ ```python
123
+ result = sms.balance()
124
+ print(result.balance) # 500
125
+ ```
126
+
127
+ ### Create Sender Name
128
+
129
+ ```python
130
+ result = sms.create_sender("MyBrand")
131
+ print(result.success) # True
132
+ ```
133
+
134
+ ## Async Usage
135
+
136
+ ```python
137
+ import asyncio
138
+ from gosms import AsyncSMS
139
+
140
+ async def main():
141
+ async with AsyncSMS("your_api_key") as sms:
142
+ result = await sms.send("995555123456", "Hello!", "GOSMS.GE")
143
+ print(result.message_id)
144
+
145
+ balance = await sms.balance()
146
+ print(balance.balance)
147
+
148
+ asyncio.run(main())
149
+ ```
150
+
151
+ All methods from the sync client are available as async equivalents with the same signatures.
152
+
153
+ ## Django Integration
154
+
155
+ Add to your `settings.py`:
156
+
157
+ ```python
158
+ GOSMS_SETTINGS = {
159
+ "api_key": "your_api_key",
160
+ "timeout": 30, # optional
161
+ "retries": 1, # optional
162
+ }
163
+ ```
164
+
165
+ Use anywhere in your project:
166
+
167
+ ```python
168
+ from gosms.django import get_sms_client
169
+
170
+ sms = get_sms_client()
171
+ sms.send("995555123456", "Hello!", "GOSMS.GE")
172
+ ```
173
+
174
+ The client is created lazily on first call and reused as a singleton.
175
+
176
+ ## Configuration
177
+
178
+ ```python
179
+ sms = SMS(
180
+ "your_api_key",
181
+ timeout=30, # request timeout in seconds (default: 30)
182
+ retries=3, # retry attempts on failure (default: 1)
183
+ debug=True, # enable debug logging (default: False)
184
+ )
185
+ ```
186
+
187
+ ## Error Handling
188
+
189
+ ```python
190
+ from gosms import SMS, GoSmsApiError, GoSmsErrorCode
191
+
192
+ sms = SMS("your_api_key")
193
+
194
+ try:
195
+ result = sms.send("995555123456", "Hello!", "GOSMS.GE")
196
+ except GoSmsApiError as e:
197
+ print(e.error_code) # 100
198
+ print(e.message) # "Invalid API key"
199
+
200
+ if e.error_code == GoSmsErrorCode.INVALID_API_KEY:
201
+ print("Check your API key")
202
+ ```
203
+
204
+ ### Error Codes
205
+
206
+ | Code | Constant | Description |
207
+ |------|----------|-------------|
208
+ | 100 | `INVALID_API_KEY` | Invalid API key |
209
+ | 101 | `INVALID_PHONE_NUMBER` | Invalid phone number |
210
+ | 102 | `INSUFFICIENT_BALANCE` | Insufficient balance |
211
+ | 103 | `SENDER_NOT_FOUND` | Sender name not found |
212
+ | 104 | `INVALID_TEXT` | Invalid message text |
213
+ | 105 | `TOO_MANY_RECIPIENTS` | Too many recipients (max 1000) |
214
+ | 106 | `INVALID_MESSAGE_ID` | Invalid message ID |
215
+ | 107 | `SENDER_EXISTS` | Sender name already exists |
216
+ | 108 | `INVALID_SENDER_NAME` | Invalid sender name |
217
+ | 109 | `INVALID_OTP_HASH` | Invalid OTP hash |
218
+ | 110 | `INVALID_OTP_CODE` | Invalid OTP code |
219
+ | 111 | `OTP_EXPIRED` | OTP expired |
220
+ | 112 | `OTP_ALREADY_VERIFIED` | OTP already verified |
221
+ | 113 | `RATE_LIMIT_EXCEEDED` | Rate limit exceeded |
222
+
223
+ ## Response Types
224
+
225
+ All methods return typed frozen dataclasses:
226
+
227
+ | Method | Return Type | Key Fields |
228
+ |--------|-------------|------------|
229
+ | `send()` | `SmsSendResponse` | `success`, `message_id`, `balance` |
230
+ | `send_bulk()` | `SendBulkSmsResponse` | `success`, `total_count`, `messages` |
231
+ | `send_otp()` | `OtpSendResponse` | `success`, `hash`, `balance` |
232
+ | `verify_otp()` | `OtpVerifyResponse` | `success`, `verify` |
233
+ | `status()` | `CheckStatusResponse` | `success`, `status`, `message_id` |
234
+ | `balance()` | `BalanceResponse` | `success`, `balance` |
235
+ | `create_sender()` | `SenderCreateResponse` | `success` |
236
+
237
+ ## Migration from v1.x
238
+
239
+ v2.0 is a complete rewrite. Key changes:
240
+
241
+ ```python
242
+ # v1.x (old)
243
+ from gosms import sms # module-level singleton
244
+ sms.send('995...', 'text', 'SENDER')
245
+
246
+ # v2.0 (new)
247
+ from gosms import SMS # explicit instantiation
248
+ sms = SMS('your_api_key')
249
+ sms.send('995...', 'text', 'SENDER')
250
+
251
+ # v1.x Django (old)
252
+ from gosms import sms # import-time side effect
253
+
254
+ # v2.0 Django (new)
255
+ from gosms.django import get_sms_client # lazy factory
256
+ sms = get_sms_client()
257
+ ```
258
+
259
+ Other changes:
260
+ - `GoSmsApiError` now extends `Exception` (was `BaseException`)
261
+ - Added `GoSmsErrorCode` constants for typed error handling
262
+ - Added `send_bulk()` and `create_sender()` endpoints
263
+ - Added async client (`AsyncSMS`) via `pip install gosms-python[async]`
264
+ - All responses are typed frozen dataclasses
265
+ - Removed `dev_mode` / `RequestMock` in favor of standard test mocking
266
+
267
+ ## License
268
+
269
+ MIT
270
+
271
+ ## Links
272
+
273
+ - Website: https://gosms.ge
274
+ - PyPI: https://pypi.org/project/gosms-python/
275
+ - GitHub: https://github.com/gosms-python/gosms-python-python
276
+ - Support: info@gosms.ge
@@ -0,0 +1,240 @@
1
+ # GoSMS.GE Python SDK
2
+
3
+ [![PyPI version](https://img.shields.io/pypi/v/gosms-python.svg)](https://pypi.org/project/gosms-python/)
4
+ [![Python versions](https://img.shields.io/pypi/pyversions/gosms-python.svg)](https://pypi.org/project/gosms-python/)
5
+ [![Tests](https://github.com/gosms-python/gosms-python-python/actions/workflows/release.yml/badge.svg)](https://github.com/gosms-python/gosms-python-python/actions)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ Official Python SDK for the [GoSMS.GE](https://gosms.ge) SMS gateway. Send SMS messages, manage OTP verification, and check balances with both sync and async clients.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pip install gosms-python
14
+ ```
15
+
16
+ For async support:
17
+
18
+ ```bash
19
+ pip install gosms-python[async]
20
+ ```
21
+
22
+ ## Quick Start
23
+
24
+ ```python
25
+ from gosms import SMS
26
+
27
+ sms = SMS("your_api_key")
28
+
29
+ # Send a message
30
+ result = sms.send("995555123456", "Hello!", "GOSMS.GE")
31
+ print(result.message_id) # 12345
32
+ print(result.balance) # 99
33
+
34
+ # Check balance
35
+ balance = sms.balance()
36
+ print(balance.balance) # 500
37
+ ```
38
+
39
+ ## All Endpoints
40
+
41
+ ### Send SMS
42
+
43
+ ```python
44
+ result = sms.send("995555123456", "Hello!", "GOSMS.GE")
45
+ result = sms.send("995555123456", "Urgent!", "GOSMS.GE", urgent=True)
46
+ ```
47
+
48
+ ### Send Bulk SMS
49
+
50
+ ```python
51
+ result = sms.send_bulk(
52
+ "GOSMS.GE",
53
+ ["995555111111", "995555222222"],
54
+ "Hello everyone!",
55
+ )
56
+ print(result.total_count) # 2
57
+ print(result.success_count) # 2
58
+
59
+ for msg in result.messages:
60
+ print(f"{msg.to}: {msg.message_id}")
61
+ ```
62
+
63
+ ### Send OTP
64
+
65
+ ```python
66
+ result = sms.send_otp("995555123456")
67
+ print(result.hash) # "abc123hash" — save this for verification
68
+ ```
69
+
70
+ ### Verify OTP
71
+
72
+ ```python
73
+ result = sms.verify_otp("995555123456", "abc123hash", "1234")
74
+ print(result.verify) # True
75
+ ```
76
+
77
+ ### Check Message Status
78
+
79
+ ```python
80
+ result = sms.status(12345)
81
+ print(result.status) # "delivered"
82
+ ```
83
+
84
+ ### Check Balance
85
+
86
+ ```python
87
+ result = sms.balance()
88
+ print(result.balance) # 500
89
+ ```
90
+
91
+ ### Create Sender Name
92
+
93
+ ```python
94
+ result = sms.create_sender("MyBrand")
95
+ print(result.success) # True
96
+ ```
97
+
98
+ ## Async Usage
99
+
100
+ ```python
101
+ import asyncio
102
+ from gosms import AsyncSMS
103
+
104
+ async def main():
105
+ async with AsyncSMS("your_api_key") as sms:
106
+ result = await sms.send("995555123456", "Hello!", "GOSMS.GE")
107
+ print(result.message_id)
108
+
109
+ balance = await sms.balance()
110
+ print(balance.balance)
111
+
112
+ asyncio.run(main())
113
+ ```
114
+
115
+ All methods from the sync client are available as async equivalents with the same signatures.
116
+
117
+ ## Django Integration
118
+
119
+ Add to your `settings.py`:
120
+
121
+ ```python
122
+ GOSMS_SETTINGS = {
123
+ "api_key": "your_api_key",
124
+ "timeout": 30, # optional
125
+ "retries": 1, # optional
126
+ }
127
+ ```
128
+
129
+ Use anywhere in your project:
130
+
131
+ ```python
132
+ from gosms.django import get_sms_client
133
+
134
+ sms = get_sms_client()
135
+ sms.send("995555123456", "Hello!", "GOSMS.GE")
136
+ ```
137
+
138
+ The client is created lazily on first call and reused as a singleton.
139
+
140
+ ## Configuration
141
+
142
+ ```python
143
+ sms = SMS(
144
+ "your_api_key",
145
+ timeout=30, # request timeout in seconds (default: 30)
146
+ retries=3, # retry attempts on failure (default: 1)
147
+ debug=True, # enable debug logging (default: False)
148
+ )
149
+ ```
150
+
151
+ ## Error Handling
152
+
153
+ ```python
154
+ from gosms import SMS, GoSmsApiError, GoSmsErrorCode
155
+
156
+ sms = SMS("your_api_key")
157
+
158
+ try:
159
+ result = sms.send("995555123456", "Hello!", "GOSMS.GE")
160
+ except GoSmsApiError as e:
161
+ print(e.error_code) # 100
162
+ print(e.message) # "Invalid API key"
163
+
164
+ if e.error_code == GoSmsErrorCode.INVALID_API_KEY:
165
+ print("Check your API key")
166
+ ```
167
+
168
+ ### Error Codes
169
+
170
+ | Code | Constant | Description |
171
+ |------|----------|-------------|
172
+ | 100 | `INVALID_API_KEY` | Invalid API key |
173
+ | 101 | `INVALID_PHONE_NUMBER` | Invalid phone number |
174
+ | 102 | `INSUFFICIENT_BALANCE` | Insufficient balance |
175
+ | 103 | `SENDER_NOT_FOUND` | Sender name not found |
176
+ | 104 | `INVALID_TEXT` | Invalid message text |
177
+ | 105 | `TOO_MANY_RECIPIENTS` | Too many recipients (max 1000) |
178
+ | 106 | `INVALID_MESSAGE_ID` | Invalid message ID |
179
+ | 107 | `SENDER_EXISTS` | Sender name already exists |
180
+ | 108 | `INVALID_SENDER_NAME` | Invalid sender name |
181
+ | 109 | `INVALID_OTP_HASH` | Invalid OTP hash |
182
+ | 110 | `INVALID_OTP_CODE` | Invalid OTP code |
183
+ | 111 | `OTP_EXPIRED` | OTP expired |
184
+ | 112 | `OTP_ALREADY_VERIFIED` | OTP already verified |
185
+ | 113 | `RATE_LIMIT_EXCEEDED` | Rate limit exceeded |
186
+
187
+ ## Response Types
188
+
189
+ All methods return typed frozen dataclasses:
190
+
191
+ | Method | Return Type | Key Fields |
192
+ |--------|-------------|------------|
193
+ | `send()` | `SmsSendResponse` | `success`, `message_id`, `balance` |
194
+ | `send_bulk()` | `SendBulkSmsResponse` | `success`, `total_count`, `messages` |
195
+ | `send_otp()` | `OtpSendResponse` | `success`, `hash`, `balance` |
196
+ | `verify_otp()` | `OtpVerifyResponse` | `success`, `verify` |
197
+ | `status()` | `CheckStatusResponse` | `success`, `status`, `message_id` |
198
+ | `balance()` | `BalanceResponse` | `success`, `balance` |
199
+ | `create_sender()` | `SenderCreateResponse` | `success` |
200
+
201
+ ## Migration from v1.x
202
+
203
+ v2.0 is a complete rewrite. Key changes:
204
+
205
+ ```python
206
+ # v1.x (old)
207
+ from gosms import sms # module-level singleton
208
+ sms.send('995...', 'text', 'SENDER')
209
+
210
+ # v2.0 (new)
211
+ from gosms import SMS # explicit instantiation
212
+ sms = SMS('your_api_key')
213
+ sms.send('995...', 'text', 'SENDER')
214
+
215
+ # v1.x Django (old)
216
+ from gosms import sms # import-time side effect
217
+
218
+ # v2.0 Django (new)
219
+ from gosms.django import get_sms_client # lazy factory
220
+ sms = get_sms_client()
221
+ ```
222
+
223
+ Other changes:
224
+ - `GoSmsApiError` now extends `Exception` (was `BaseException`)
225
+ - Added `GoSmsErrorCode` constants for typed error handling
226
+ - Added `send_bulk()` and `create_sender()` endpoints
227
+ - Added async client (`AsyncSMS`) via `pip install gosms-python[async]`
228
+ - All responses are typed frozen dataclasses
229
+ - Removed `dev_mode` / `RequestMock` in favor of standard test mocking
230
+
231
+ ## License
232
+
233
+ MIT
234
+
235
+ ## Links
236
+
237
+ - Website: https://gosms.ge
238
+ - PyPI: https://pypi.org/project/gosms-python/
239
+ - GitHub: https://github.com/gosms-python/gosms-python-python
240
+ - Support: info@gosms.ge
@@ -0,0 +1,62 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "gosms-python"
7
+ version = "1.0.3"
8
+ description = "Official Python SDK for GoSMS.GE SMS Gateway"
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ requires-python = ">=3.9"
12
+ authors = [
13
+ { name = "GoSMS.GE", email = "info@gosms.ge" },
14
+ ]
15
+ keywords = ["sms", "sms-api", "gosms", "sms-sdk", "sms-gateway", "otp"]
16
+ classifiers = [
17
+ "Development Status :: 5 - Production/Stable",
18
+ "Intended Audience :: Developers",
19
+ "License :: OSI Approved :: MIT License",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Topic :: Communications",
27
+ "Typing :: Typed",
28
+ ]
29
+ dependencies = [
30
+ "requests>=2.28.0",
31
+ ]
32
+
33
+ [project.optional-dependencies]
34
+ async = ["httpx>=0.24.0"]
35
+ django = ["django>=3.2"]
36
+ dev = [
37
+ "pytest>=7.0",
38
+ "pytest-asyncio>=0.21",
39
+ "responses>=0.23",
40
+ "pytest-httpx>=0.21",
41
+ "ruff>=0.1",
42
+ "build",
43
+ ]
44
+
45
+ [project.urls]
46
+ Homepage = "https://gosms.ge"
47
+ Repository = "https://github.com/gosms-ge/gosmsge-python"
48
+ Issues = "https://github.com/gosms-ge/gosmsge-python/issues"
49
+
50
+ [tool.hatch.build.targets.wheel]
51
+ packages = ["src/gosms"]
52
+
53
+ [tool.pytest.ini_options]
54
+ testpaths = ["tests"]
55
+ asyncio_mode = "auto"
56
+
57
+ [tool.ruff]
58
+ target-version = "1.0.3"
59
+ line-length = 120
60
+
61
+ [tool.ruff.lint]
62
+ select = ["E", "F", "I", "UP", "B", "SIM"]