ombala 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,3 @@
1
+ __pycache__
2
+ .pypirc
3
+ dist
ombala-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,112 @@
1
+ Metadata-Version: 2.4
2
+ Name: ombala
3
+ Version: 0.1.0
4
+ Summary: SDK em Python para a API de envios de SMS em Angola
5
+ Project-URL: Homepage, https://www.useombala.ao/
6
+ Project-URL: Repository, https://github.com/omarscode/ombala
7
+ Project-URL: Documentation, https://github.com/omarscode/ombala#README
8
+ Project-URL: Tracker, https://github.com/omarscode/ombala/issues
9
+ Author-email: Omar Rodrigues <omarscode007@gmail.com>
10
+ License: MIT
11
+ Keywords: angola,api,ombala,sdk,sms
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Communications :: Telephony
22
+ Classifier: Topic :: Software Development :: Libraries
23
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
24
+ Requires-Python: >=3.9
25
+ Requires-Dist: httpx>=0.27.0
26
+ Requires-Dist: pydantic>=2.0.0
27
+ Provides-Extra: dev
28
+ Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
29
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
30
+ Requires-Dist: respx>=0.21.0; extra == 'dev'
31
+ Requires-Dist: ruff>=0.5.0; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # Ombala SDK Python
35
+
36
+ SDK Python para a [API Ombala](https://api.useombala.ao) — envio de SMS em Angola.
37
+
38
+ ## Instalação
39
+
40
+ ```bash
41
+ pip install ombala
42
+ ```
43
+
44
+ ## Uso
45
+
46
+ ```python
47
+ from ombala import Ombala
48
+
49
+ client = Ombala("Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503")
50
+
51
+ # Enviar SMS
52
+ client.messages.send(
53
+ message="Olá, tudo bem?",
54
+ from_="MINHALOJA",
55
+ to="921939411",
56
+ )
57
+
58
+ # Listar mensagens
59
+ client.messages.list(page=1)
60
+
61
+ # Ver saldo
62
+ client.credits.balance()
63
+ ```
64
+
65
+ ### Modo assíncrono
66
+
67
+ ```python
68
+ import asyncio
69
+ from ombala import AsyncOmbala
70
+
71
+ async def main():
72
+ async with AsyncOmbala("Token ...") as client:
73
+ resp = await client.messages.send(
74
+ message="Olá, tudo bem?",
75
+ from_="MINHALOJA",
76
+ to="921939411",
77
+ )
78
+ print(resp)
79
+
80
+ asyncio.run(main())
81
+ ```
82
+
83
+ ## API
84
+
85
+ ### Mensagens
86
+
87
+ | Método | Descrição |
88
+ |---|---|
89
+ | `messages.send(message, from_, to, schedule?)` | Enviar SMS |
90
+ | `messages.list(page?)` | Listar mensagens |
91
+ | `messages.get(message_id, id?)` | Obter mensagem por ID |
92
+ | `messages.delete(message_id)` | Apagar registo de envio |
93
+ | `messages.list_recipients(page?)` | Listar destinatários |
94
+ | `messages.list_by_date_range(start, end, page?)` | Listar mensagens por intervalo de datas |
95
+ | `messages.list_by_recipient(phone_number?, page?)` | Listar mensagens de um número |
96
+
97
+ ### Remetentes
98
+
99
+ | Método | Descrição |
100
+ |---|---|
101
+ | `senders.create(name)` | Criar remetente |
102
+ | `senders.list()` | Listar remetentes |
103
+ | `senders.list_approved()` | Listar remetentes aprovados |
104
+ | `senders.list_pending()` | Listar remetentes pendentes |
105
+ | `senders.delete(sender_id)` | Apagar remetente |
106
+
107
+ ### Créditos
108
+
109
+ | Método | Descrição |
110
+ |---|---|
111
+ | `credits.balance()` | Mostrar saldo |
112
+ | `credits.recharges()` | Histórico de carregamentos |
ombala-0.1.0/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # Ombala SDK Python
2
+
3
+ SDK Python para a [API Ombala](https://api.useombala.ao) — envio de SMS em Angola.
4
+
5
+ ## Instalação
6
+
7
+ ```bash
8
+ pip install ombala
9
+ ```
10
+
11
+ ## Uso
12
+
13
+ ```python
14
+ from ombala import Ombala
15
+
16
+ client = Ombala("Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503")
17
+
18
+ # Enviar SMS
19
+ client.messages.send(
20
+ message="Olá, tudo bem?",
21
+ from_="MINHALOJA",
22
+ to="921939411",
23
+ )
24
+
25
+ # Listar mensagens
26
+ client.messages.list(page=1)
27
+
28
+ # Ver saldo
29
+ client.credits.balance()
30
+ ```
31
+
32
+ ### Modo assíncrono
33
+
34
+ ```python
35
+ import asyncio
36
+ from ombala import AsyncOmbala
37
+
38
+ async def main():
39
+ async with AsyncOmbala("Token ...") as client:
40
+ resp = await client.messages.send(
41
+ message="Olá, tudo bem?",
42
+ from_="MINHALOJA",
43
+ to="921939411",
44
+ )
45
+ print(resp)
46
+
47
+ asyncio.run(main())
48
+ ```
49
+
50
+ ## API
51
+
52
+ ### Mensagens
53
+
54
+ | Método | Descrição |
55
+ |---|---|
56
+ | `messages.send(message, from_, to, schedule?)` | Enviar SMS |
57
+ | `messages.list(page?)` | Listar mensagens |
58
+ | `messages.get(message_id, id?)` | Obter mensagem por ID |
59
+ | `messages.delete(message_id)` | Apagar registo de envio |
60
+ | `messages.list_recipients(page?)` | Listar destinatários |
61
+ | `messages.list_by_date_range(start, end, page?)` | Listar mensagens por intervalo de datas |
62
+ | `messages.list_by_recipient(phone_number?, page?)` | Listar mensagens de um número |
63
+
64
+ ### Remetentes
65
+
66
+ | Método | Descrição |
67
+ |---|---|
68
+ | `senders.create(name)` | Criar remetente |
69
+ | `senders.list()` | Listar remetentes |
70
+ | `senders.list_approved()` | Listar remetentes aprovados |
71
+ | `senders.list_pending()` | Listar remetentes pendentes |
72
+ | `senders.delete(sender_id)` | Apagar remetente |
73
+
74
+ ### Créditos
75
+
76
+ | Método | Descrição |
77
+ |---|---|
78
+ | `credits.balance()` | Mostrar saldo |
79
+ | `credits.recharges()` | Histórico de carregamentos |
@@ -0,0 +1,3 @@
1
+ from ombala.client import Ombala, AsyncOmbala
2
+
3
+ __all__ = ["Ombala", "AsyncOmbala"]
@@ -0,0 +1,79 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import Any
4
+
5
+ import httpx
6
+
7
+ from ombala.exceptions import (
8
+ AuthenticationError,
9
+ OmbalaError,
10
+ RateLimitError,
11
+ ServerError,
12
+ ValidationError,
13
+ )
14
+ from ombala.resources.credits import CreditsResource
15
+ from ombala.resources.messages import MessagesResource
16
+ from ombala.resources.senders import SendersResource
17
+
18
+ BASE_URL = "https://api.useombala.ao"
19
+
20
+
21
+ def error(status_code: int, response_data: dict[str, Any] | None) -> OmbalaError:
22
+ message = str(response_data) if response_data else f"HTTP {status_code}"
23
+ if status_code == 401:
24
+ return AuthenticationError(message, status_code, response_data)
25
+ if status_code == 429:
26
+ return RateLimitError(message, status_code, response_data)
27
+ if 400 <= status_code < 500:
28
+ return ValidationError(message, status_code, response_data)
29
+ if 500 <= status_code < 600:
30
+ return ServerError(message, status_code, response_data)
31
+ return OmbalaError(message, status_code, response_data)
32
+
33
+
34
+ class Ombala:
35
+ def __init__(self, token: str, base_url: str = BASE_URL, timeout: int = 30) -> None:
36
+ self._client = httpx.Client(
37
+ base_url=base_url,
38
+ headers={
39
+ "Authorization": f"Token {token}",
40
+ "Content-Type": "application/json",
41
+ },
42
+ timeout=timeout,
43
+ )
44
+ self.messages = MessagesResource(self)
45
+ self.senders = SendersResource(self)
46
+ self.credits = CreditsResource(self)
47
+
48
+ def _request(self, method: str, path: str, **kwargs: Any) -> httpx.Response:
49
+ try:
50
+ response = self._client.request(method, path, **kwargs)
51
+ except httpx.HTTPError as exc:
52
+ raise OmbalaError(f"Request failed: {exc}") from exc
53
+
54
+ if response.is_error:
55
+ try:
56
+ data = response.json()
57
+ except Exception:
58
+ data = None
59
+ raise error(response.status_code, data)
60
+
61
+ return response
62
+
63
+ def get(self, path: str, **kwargs: Any) -> httpx.Response:
64
+ return self._request("GET", path, **kwargs)
65
+
66
+ def post(self, path: str, **kwargs: Any) -> httpx.Response:
67
+ return self._request("POST", path, **kwargs)
68
+
69
+ def delete(self, path: str, **kwargs: Any) -> httpx.Response:
70
+ return self._request("DELETE", path, **kwargs)
71
+
72
+ def close(self) -> None:
73
+ self._client.close()
74
+
75
+ def __enter__(self) -> Ombala:
76
+ return self
77
+
78
+ def __exit__(self, *args: Any) -> None:
79
+ self.close()
@@ -0,0 +1,20 @@
1
+ from typing import Any
2
+
3
+
4
+ class OmbalaError(Exception):
5
+ def __init__(self, message: str, status_code: int | None = None,response_data: dict[str, Any] | None = None) -> None:
6
+ self.status_code = status_code
7
+ self.response_data = response_data
8
+ super().__init__(message)
9
+
10
+
11
+ class AuthenticationError(OmbalaError): ...
12
+
13
+
14
+ class ValidationError(OmbalaError): ...
15
+
16
+
17
+ class RateLimitError(OmbalaError): ...
18
+
19
+
20
+ class ServerError(OmbalaError): ...
@@ -0,0 +1,48 @@
1
+ from datetime import datetime
2
+ from typing import Any
3
+
4
+ from pydantic import BaseModel, Field
5
+
6
+
7
+ class SendSMSRequest(BaseModel):
8
+ message: str
9
+ from_: str = Field(alias="from", serialization_alias="from")
10
+ to: str
11
+ schedule: str | None = None
12
+
13
+
14
+ class Message(BaseModel):
15
+ id: str
16
+ message: str
17
+ from_: str | None = Field(None, alias="from")
18
+ to: str | None = None
19
+ status: str | None = None
20
+ created_at: datetime | None = Field(None, alias="createdAt")
21
+
22
+
23
+ class SenderCreate(BaseModel):
24
+ name: str
25
+
26
+
27
+ class Sender(BaseModel):
28
+ id: str
29
+ name: str
30
+ status: str | None = None
31
+
32
+
33
+ class CreditBalance(BaseModel):
34
+ balance: float | None = None
35
+ currency: str | None = None
36
+
37
+
38
+ class Recharge(BaseModel):
39
+ id: str | None = None
40
+ amount: float | None = None
41
+ date: str | None = None
42
+
43
+
44
+ class PaginatedResponse(BaseModel):
45
+ data: list[Any]
46
+ page: int | None = None
47
+ total: int | None = None
48
+ total_pages: int | None = None
File without changes
@@ -0,0 +1,19 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ if TYPE_CHECKING:
6
+ from ombala.client import Ombala, AsyncOmbala
7
+
8
+
9
+ class CreditsResource:
10
+ def __init__(self, client: Ombala | AsyncOmbala) -> None:
11
+ self._client = client
12
+
13
+ def balance(self) -> dict[str, Any]:
14
+ resp = self._client.get("/v1/credits")
15
+ return resp.json()
16
+
17
+ def recharges(self) -> dict[str, Any]:
18
+ resp = self._client.get("/v1/recharges")
19
+ return resp.json()
@@ -0,0 +1,73 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from ombala.models import SendSMSRequest
6
+
7
+ if TYPE_CHECKING:
8
+ from ombala.client import Ombala, AsyncOmbala
9
+
10
+
11
+ class MessagesResource:
12
+ def __init__(self, client: Ombala | AsyncOmbala) -> None:
13
+ self._client = client
14
+
15
+ def send(self, message: str, from_: str,to: str, schedule: str | None = None) -> dict[str, Any]:
16
+ body = SendSMSRequest(message=message, from_=from_, to=to, schedule=schedule)
17
+ resp = self._client.post(
18
+ "/v1/messages",
19
+ content=body.model_dump_json(by_alias=True),
20
+ )
21
+ return resp.json()
22
+
23
+ def list(self, page: int | None = None) -> dict[str, Any]:
24
+ params: dict[str, Any] = {}
25
+ if page is not None:
26
+ params["page"] = page
27
+ resp = self._client.get("/v1/messages", params=params)
28
+ return resp.json()
29
+
30
+ def get(self, message_id: str, id: str | None = None) -> dict[str, Any]:
31
+ params: dict[str, Any] = {"message_id": message_id}
32
+ if id is not None:
33
+ params["id"] = id
34
+ resp = self._client.get("/v1/messages/one", params=params)
35
+ return resp.json()
36
+
37
+ def delete(self, message_id: str) -> None:
38
+ self._client.delete(f"/v1/messages/{message_id}")
39
+
40
+ def list_recipients(
41
+ self,
42
+ page: int | None = None,
43
+ ) -> dict[str, Any]:
44
+ params: dict[str, Any] = {}
45
+ if page is not None:
46
+ params["page"] = page
47
+ resp = self._client.get("/v1/messages/recipients", params=params)
48
+ return resp.json()
49
+
50
+ def list_by_date_range(
51
+ self,
52
+ start: str,
53
+ end: str,
54
+ page: int | None = None,
55
+ ) -> dict[str, Any]:
56
+ params: dict[str, Any] = {"start": start, "end": end}
57
+ if page is not None:
58
+ params["page"] = page
59
+ resp = self._client.get("/v1/messages/date", params=params)
60
+ return resp.json()
61
+
62
+ def list_by_recipient(
63
+ self,
64
+ phone_number: str | None = None,
65
+ page: int | None = None,
66
+ ) -> dict[str, Any]:
67
+ params: dict[str, Any] = {}
68
+ if phone_number is not None:
69
+ params["phone_number"] = phone_number
70
+ if page is not None:
71
+ params["page"] = page
72
+ resp = self._client.get("/v1/messages/recipient", params=params)
73
+ return resp.json()
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ if TYPE_CHECKING:
6
+ from ombala.client import Ombala, AsyncOmbala
7
+
8
+
9
+ class SendersResource:
10
+ def __init__(self, client: Ombala | AsyncOmbala) -> None:
11
+ self._client = client
12
+
13
+ def create(self, name: str) -> dict[str, Any]:
14
+ resp = self._client.post("/v1/senders/", json={"name": name})
15
+ return resp.json()
16
+
17
+ def list(self) -> dict[str, Any]:
18
+ resp = self._client.get("/v1/senders")
19
+ return resp.json()
20
+
21
+ def list_approved(self) -> dict[str, Any]:
22
+ resp = self._client.get("/v1/senders/approved")
23
+ return resp.json()
24
+
25
+ def list_pending(self) -> dict[str, Any]:
26
+ resp = self._client.get("/v1/senders/pending")
27
+ return resp.json()
28
+
29
+ def delete(self, sender_id: str) -> None:
30
+ self._client.delete(f"/v1/senders/{sender_id}")
@@ -0,0 +1,591 @@
1
+ {
2
+ "openapi": "3.0.0",
3
+ "info": {
4
+ "title": "Ombala API",
5
+ "version": "1.0.0"
6
+ },
7
+ "servers": [
8
+ {
9
+ "url": "https://api.useombala.ao"
10
+ }
11
+ ],
12
+ "tags": [
13
+ {
14
+ "name": "Mensagens"
15
+ },
16
+ {
17
+ "name": "Remetentes"
18
+ },
19
+ {
20
+ "name": "Créditos"
21
+ }
22
+ ],
23
+ "paths": {
24
+ "/v1/messages": {
25
+ "post": {
26
+ "tags": [
27
+ "Mensagens"
28
+ ],
29
+ "summary": "Enviar Mensagem",
30
+ "description": "Permite enviar uma SMS para um ou mais números de telefone.",
31
+ "requestBody": {
32
+ "content": {
33
+ "application/json": {
34
+ "schema": {
35
+ "type": "object",
36
+ "required": [
37
+ "message",
38
+ "from",
39
+ "to"
40
+ ],
41
+ "properties": {
42
+ "message": {
43
+ "type": "string",
44
+ "description": "Texto da mensagem",
45
+ "required": true
46
+ },
47
+ "from": {
48
+ "type": "string",
49
+ "description": "Remetente da mensagem, deve estar previamente criado e aprovado.",
50
+ "required": true
51
+ },
52
+ "to": {
53
+ "type": "string",
54
+ "description": "Lista de número(s) destinatário(s) da mensagem",
55
+ "required": true
56
+ },
57
+ "schedule": {
58
+ "type": "string",
59
+ "description": "Data e hora para o envio da SMS, no formato yyyyMMddHHmmss, ideal para agendar o envio de uma SMS, não é um parâmetro obrigatório.",
60
+ "format": "date-time",
61
+ "required": false
62
+ }
63
+ },
64
+ "example": {
65
+ "message": "Mensagem de teste.",
66
+ "from": "MINHALOJA",
67
+ "to": "921939411",
68
+ "schedule": "20231015182000"
69
+ }
70
+ }
71
+ }
72
+ }
73
+ },
74
+ "parameters": [
75
+ {
76
+ "name": "Authorization",
77
+ "in": "header",
78
+ "schema": {
79
+ "type": "string",
80
+ "description": "Token de autorização disponível no Portal Ombala"
81
+ },
82
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
83
+ },
84
+ {
85
+ "name": "Content-Type",
86
+ "in": "header",
87
+ "schema": {
88
+ "type": "string",
89
+ "description": "Formato do conteúdo do pedido, formato application/json, obrigatório."
90
+ },
91
+ "example": "application/json"
92
+ }
93
+ ],
94
+ "responses": {
95
+ "201": {
96
+ "description": "Mensagem enviada com sucesso",
97
+ "content": {
98
+ "application/json": {}
99
+ }
100
+ },
101
+ "4XX": {
102
+ "description": "Houve um problema no pedido. Haverá uma descrição clara da causa do do erro.",
103
+ "content": {
104
+ "application/json": {}
105
+ }
106
+ }
107
+ }
108
+ },
109
+ "get": {
110
+ "tags": [
111
+ "Mensagens"
112
+ ],
113
+ "summary": "Listar Mensagens",
114
+ "parameters": [
115
+ {
116
+ "name": "Authorization",
117
+ "in": "header",
118
+ "schema": {
119
+ "type": "string",
120
+ "description": "Token de autorização disponível no Portal Ombala"
121
+ },
122
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
123
+ },
124
+ {
125
+ "name": "page",
126
+ "in": "query",
127
+ "schema": {
128
+ "type": "integer",
129
+ "description": "As mensagens serão retornadas em diversas páginas, pode requisitar uma página especifica por esse parâmentro, ele não é obrigatório."
130
+ },
131
+ "example": "0"
132
+ }
133
+ ],
134
+ "responses": {
135
+ "200": {
136
+ "description": "Pedido Realizado com sucesso",
137
+ "content": {
138
+ "application/json": {}
139
+ }
140
+ }
141
+ }
142
+ }
143
+ },
144
+ "/v1/messages/{message_id}": {
145
+ "delete": {
146
+ "tags": [
147
+ "Mensagens"
148
+ ],
149
+ "summary": "Delete",
150
+ "description": "Apagar o registro de envio de uma SMS",
151
+ "parameters": [
152
+ {
153
+ "name": "Authorization",
154
+ "in": "header",
155
+ "schema": {
156
+ "type": "string",
157
+ "description": "Token de autorização disponível no Portal Ombala"
158
+ },
159
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
160
+ },
161
+ {
162
+ "name": "message_id",
163
+ "in": "path",
164
+ "schema": {
165
+ "type": "string",
166
+ "description": "ID da mensagem"
167
+ },
168
+ "example": "b9eb6ea6-5117-4848-a9ed-8cbffc74a991"
169
+ }
170
+ ],
171
+ "responses": {
172
+ "204": {
173
+ "description": "Pedido Realizado com sucesso",
174
+ "content": {
175
+ "application/json": {}
176
+ }
177
+ }
178
+ }
179
+ }
180
+ },
181
+ "/v1/messages/recipients": {
182
+ "get": {
183
+ "tags": [
184
+ "Mensagens"
185
+ ],
186
+ "summary": "Listar destinatários",
187
+ "description": "Listar todos os números que já foram alvo de uma SMS através da sua conta",
188
+ "parameters": [
189
+ {
190
+ "name": "Authorization",
191
+ "in": "header",
192
+ "schema": {
193
+ "type": "string",
194
+ "description": "Token de autorização disponível no Portal Ombala"
195
+ },
196
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
197
+ },
198
+ {
199
+ "name": "page",
200
+ "in": "query",
201
+ "schema": {
202
+ "type": "integer",
203
+ "description": "As mensagens serão retornadas em diversas páginas, pode requisitar uma página especifica por esse parâmentro, ele não é obrigatório."
204
+ },
205
+ "example": "1"
206
+ }
207
+ ],
208
+ "responses": {
209
+ "200": {
210
+ "description": "Pedido Realizado com sucesso",
211
+ "content": {
212
+ "application/json": {}
213
+ }
214
+ }
215
+ }
216
+ }
217
+ },
218
+ "/v1/messages/date": {
219
+ "get": {
220
+ "tags": [
221
+ "Mensagens"
222
+ ],
223
+ "summary": "Listar Mensagens Intervalo de datas",
224
+ "description": "Listar todas as mensagens envidas dentro de um intervalo de datas",
225
+ "parameters": [
226
+ {
227
+ "name": "Authorization",
228
+ "in": "header",
229
+ "schema": {
230
+ "type": "string",
231
+ "description": "Token de autorização disponível no Portal Ombala"
232
+ },
233
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
234
+ },
235
+ {
236
+ "name": "start",
237
+ "in": "query",
238
+ "description": "Data de início da consulta, no formato YYYYMMDD",
239
+ "required": true,
240
+ "schema": {
241
+ "type": "integer"
242
+ },
243
+ "example": "20231011"
244
+ },
245
+ {
246
+ "name": "end",
247
+ "in": "query",
248
+ "description": "Data de fim da consulta, no formato YYYYMMDD",
249
+ "required": true,
250
+ "schema": {
251
+ "type": "integer"
252
+ },
253
+ "example": "20231020"
254
+ },
255
+ {
256
+ "name": "page",
257
+ "in": "query",
258
+ "schema": {
259
+ "type": "integer",
260
+ "description": "As mensagens serão retornadas em diversas páginas, pode requisitar uma página especifica por esse parâmentro, ele não é obrigatório."
261
+ },
262
+ "example": "1"
263
+ }
264
+ ],
265
+ "responses": {
266
+ "200": {
267
+ "description": "Pedido Realizado com sucesso",
268
+ "content": {
269
+ "application/json": {}
270
+ }
271
+ }
272
+ }
273
+ }
274
+ },
275
+ "/v1/messages/recipient": {
276
+ "get": {
277
+ "tags": [
278
+ "Mensagens"
279
+ ],
280
+ "summary": "Listas de mensagens de um número/destinatário",
281
+ "parameters": [
282
+ {
283
+ "name": "Authorization",
284
+ "in": "header",
285
+ "schema": {
286
+ "type": "string",
287
+ "description": "Token de autorização disponível no Portal Ombala"
288
+ },
289
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
290
+ },
291
+ {
292
+ "name": "phone_number",
293
+ "in": "query",
294
+ "schema": {
295
+ "type": "integer"
296
+ },
297
+ "example": "921939455"
298
+ },
299
+ {
300
+ "name": "page",
301
+ "in": "query",
302
+ "schema": {
303
+ "type": "integer",
304
+ "description": "Os resultados serão retornadas em diversas páginas, pode requisitar uma página especifica por esse parâmentro, ele não é obrigatório."
305
+ },
306
+ "example": "0"
307
+ }
308
+ ],
309
+ "responses": {
310
+ "200": {
311
+ "description": "Pedido Realizado com sucesso",
312
+ "content": {
313
+ "application/json": {}
314
+ }
315
+ }
316
+ }
317
+ }
318
+ },
319
+ "/v1/messages/one": {
320
+ "get": {
321
+ "tags": [
322
+ "Mensagens"
323
+ ],
324
+ "summary": "Mostrar mensagem pelo ID mensagem",
325
+ "parameters": [
326
+ {
327
+ "name": "Authorization",
328
+ "in": "header",
329
+ "schema": {
330
+ "type": "string",
331
+ "description": "Token de autorização disponível no Portal Ombala"
332
+ },
333
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
334
+ },
335
+ {
336
+ "name": "message_id",
337
+ "in": "query",
338
+ "description": "ID da Mensagem",
339
+ "schema": {
340
+ "type": "string"
341
+ },
342
+ "example": "545b6ca5-a481-4abe-b3b9-ce1e8a4b3629"
343
+ },
344
+ {
345
+ "name": "id",
346
+ "in": "query",
347
+ "description": "ID do número de destino da SMS no contexto de uma mensagem",
348
+ "schema": {
349
+ "type": "string"
350
+ },
351
+ "example": "545b6ca5-a481-4abe-b3b9-ce1e8a4b3629"
352
+ }
353
+ ],
354
+ "responses": {
355
+ "200": {
356
+ "description": "Pedido Realizado com sucesso",
357
+ "content": {
358
+ "application/json": {}
359
+ }
360
+ }
361
+ }
362
+ }
363
+ },
364
+ "/v1/senders/": {
365
+ "post": {
366
+ "tags": [
367
+ "Remetentes"
368
+ ],
369
+ "summary": "Criar Remetente",
370
+ "requestBody": {
371
+ "content": {
372
+ "application/json": {
373
+ "schema": {
374
+ "type": "object",
375
+ "properties": {
376
+ "name": {
377
+ "type": "string",
378
+ "description": "Nome do remente da SMS",
379
+ "required": true
380
+ }
381
+ },
382
+ "example": {
383
+ "name": "LOJAHEBER"
384
+ }
385
+ }
386
+ }
387
+ }
388
+ },
389
+ "parameters": [
390
+ {
391
+ "name": "Authorization",
392
+ "in": "header",
393
+ "schema": {
394
+ "type": "string",
395
+ "description": "Token de autorização disponível no Portal Ombala"
396
+ },
397
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
398
+ },
399
+ {
400
+ "name": "Content-Type",
401
+ "in": "header",
402
+ "schema": {
403
+ "type": "string",
404
+ "description": "Formato do conteúdo do pedido, formato application/json, obrigatório."
405
+ },
406
+ "example": "application/json"
407
+ }
408
+ ],
409
+ "responses": {
410
+ "201": {
411
+ "description": "Pedido Realizado com sucesso",
412
+ "content": {
413
+ "application/json": {}
414
+ }
415
+ }
416
+ }
417
+ }
418
+ },
419
+ "/v1/senders": {
420
+ "get": {
421
+ "tags": [
422
+ "Remetentes"
423
+ ],
424
+ "summary": "Listar Remetentes",
425
+ "parameters": [
426
+ {
427
+ "name": "Authorization",
428
+ "in": "header",
429
+ "schema": {
430
+ "type": "string",
431
+ "description": "Token de autorização disponível no Portal Ombala"
432
+ },
433
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
434
+ }
435
+ ],
436
+ "responses": {
437
+ "200": {
438
+ "description": "Pedido Realizado com sucesso",
439
+ "content": {
440
+ "application/json": {}
441
+ }
442
+ }
443
+ }
444
+ }
445
+ },
446
+ "/v1/senders/approved": {
447
+ "get": {
448
+ "tags": [
449
+ "Remetentes"
450
+ ],
451
+ "summary": "Listar Remetentes Aprovados",
452
+ "parameters": [
453
+ {
454
+ "name": "Authorization",
455
+ "in": "header",
456
+ "schema": {
457
+ "type": "string",
458
+ "description": "Token de autorização disponível no Portal Ombala"
459
+ },
460
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
461
+ }
462
+ ],
463
+ "responses": {
464
+ "200": {
465
+ "description": "Pedido Realizado com sucesso",
466
+ "content": {
467
+ "application/json": {}
468
+ }
469
+ }
470
+ }
471
+ }
472
+ },
473
+ "/v1/senders/pending": {
474
+ "get": {
475
+ "tags": [
476
+ "Remetentes"
477
+ ],
478
+ "summary": "Listar Remetentes Pendentes de Aprovação",
479
+ "parameters": [
480
+ {
481
+ "name": "Authorization",
482
+ "in": "header",
483
+ "schema": {
484
+ "type": "string",
485
+ "description": "Token de autorização disponível no Portal Ombala"
486
+ },
487
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
488
+ }
489
+ ],
490
+ "responses": {
491
+ "200": {
492
+ "description": "Pedido Realizado com sucesso",
493
+ "content": {
494
+ "application/json": {}
495
+ }
496
+ }
497
+ }
498
+ }
499
+ },
500
+ "/v1/senders/{sender_id}": {
501
+ "delete": {
502
+ "tags": [
503
+ "Remetentes"
504
+ ],
505
+ "summary": "Delete",
506
+ "parameters": [
507
+ {
508
+ "name": "Authorization",
509
+ "in": "header",
510
+ "schema": {
511
+ "type": "string",
512
+ "description": "Token de autorização disponível no Portal Ombala"
513
+ },
514
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
515
+ },
516
+ {
517
+ "name": "sender_id",
518
+ "in": "path",
519
+ "schema": {
520
+ "type": "string",
521
+ "description": "ID do Remetente"
522
+ }
523
+ }
524
+ ],
525
+ "responses": {
526
+ "204": {
527
+ "description": "Pedido Realizado com sucesso",
528
+ "content": {
529
+ "application/json": {}
530
+ }
531
+ }
532
+ }
533
+ }
534
+ },
535
+ "/v1/credits": {
536
+ "get": {
537
+ "tags": [
538
+ "Créditos"
539
+ ],
540
+ "summary": "Mostrar Saldo/Créditos de SMS",
541
+ "parameters": [
542
+ {
543
+ "name": "Authorization",
544
+ "in": "header",
545
+ "schema": {
546
+ "type": "string",
547
+ "description": "Token de autorização disponível no Portal Ombala"
548
+ },
549
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
550
+ }
551
+ ],
552
+ "responses": {
553
+ "200": {
554
+ "description": "Pedido Realizado com sucesso",
555
+ "content": {
556
+ "application/json": {}
557
+ }
558
+ }
559
+ }
560
+ }
561
+ },
562
+ "/v1/recharges": {
563
+ "get": {
564
+ "tags": [
565
+ "Créditos"
566
+ ],
567
+ "summary": "Mostar Histórico de Carregamentos",
568
+ "parameters": [
569
+ {
570
+ "name": "Authorization",
571
+ "in": "header",
572
+ "schema": {
573
+ "type": "string",
574
+ "description": "Token de autorização disponível no Portal Ombala"
575
+ },
576
+ "example": "Token a9eb6ea6-5777-4848-a9ed-8cbffc74a503"
577
+ }
578
+ ],
579
+ "responses": {
580
+ "200": {
581
+ "description": "Pedido Realizado com sucesso",
582
+ "content": {
583
+ "application/json": {}
584
+ }
585
+ }
586
+ }
587
+ }
588
+ }
589
+ },
590
+ "components": {}
591
+ }
@@ -0,0 +1,47 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "ombala"
7
+ version = "0.1.0"
8
+ description = "SDK em Python para a API de envios de SMS em Angola"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = { text = "MIT" }
12
+ authors = [
13
+ { name = "Omar Rodrigues", email = "omarscode007@gmail.com" }
14
+ ]
15
+ keywords = ["sms", "api", "sdk", "angola", "ombala"]
16
+ dependencies = ["httpx>=0.27.0", "pydantic>=2.0.0"]
17
+ classifiers = [
18
+ "Development Status :: 3 - Alpha",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Programming Language :: Python :: 3",
22
+ "Programming Language :: Python :: 3.9",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Topic :: Communications :: Telephony",
28
+ "Topic :: Software Development :: Libraries",
29
+ "Topic :: Software Development :: Libraries :: Python Modules",
30
+ ]
31
+
32
+ [project.urls]
33
+ Homepage = "https://www.useombala.ao/"
34
+ Repository = "https://github.com/omarscode/ombala"
35
+ Documentation = "https://github.com/omarscode/ombala#README"
36
+ Tracker = "https://github.com/omarscode/ombala/issues"
37
+
38
+ [project.optional-dependencies]
39
+ dev = [
40
+ "pytest>=8.0.0",
41
+ "pytest-asyncio>=0.24.0",
42
+ "respx>=0.21.0",
43
+ "ruff>=0.5.0",
44
+ ]
45
+
46
+ [tool.hatch.build.targets.wheel]
47
+ packages = ["ombala"]
File without changes