teloryxa 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.
- teloryxa-0.1.0/PKG-INFO +86 -0
- teloryxa-0.1.0/README.md +64 -0
- teloryxa-0.1.0/pyproject.toml +40 -0
- teloryxa-0.1.0/setup.cfg +4 -0
- teloryxa-0.1.0/teloryxa/__init__.py +23 -0
- teloryxa-0.1.0/teloryxa/rest/__init__.py +167 -0
- teloryxa-0.1.0/teloryxa.egg-info/PKG-INFO +86 -0
- teloryxa-0.1.0/teloryxa.egg-info/SOURCES.txt +9 -0
- teloryxa-0.1.0/teloryxa.egg-info/dependency_links.txt +1 -0
- teloryxa-0.1.0/teloryxa.egg-info/requires.txt +4 -0
- teloryxa-0.1.0/teloryxa.egg-info/top_level.txt +1 -0
teloryxa-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: teloryxa
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Teloryxa API SDK - SignalWire/Twilio compatible voice API client
|
|
5
|
+
Author-email: Teloryxa Team <dev@teloryxa.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/fooxygg/wirexa-api
|
|
8
|
+
Project-URL: Repository, https://github.com/fooxygg/wirexa-api
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: requests>=2.25.0
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
22
|
+
|
|
23
|
+
# Teloryxa API SDK
|
|
24
|
+
|
|
25
|
+
A production-ready Python SDK for Teloryxa API - a self-hosted telephony platform compatible with SignalWire and Twilio REST API.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install teloryxa
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from teloryxa import Client
|
|
37
|
+
|
|
38
|
+
# Connect to your Teloryxa API instance
|
|
39
|
+
client = Client(
|
|
40
|
+
project_id="your-project-id",
|
|
41
|
+
api_token="your-api-token",
|
|
42
|
+
signalwire_space_url="your-space.example.com:5000"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Make a call
|
|
46
|
+
call = client.calls.create(
|
|
47
|
+
to="+573001234567",
|
|
48
|
+
from_="+18005550100",
|
|
49
|
+
url="https://your-backend.com/xml",
|
|
50
|
+
method="POST",
|
|
51
|
+
timeout=28,
|
|
52
|
+
record=True,
|
|
53
|
+
status_callback="https://your-backend.com/status",
|
|
54
|
+
status_callback_event=["initiated", "ringing", "completed"],
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
print(f"Call SID: {call.sid}")
|
|
58
|
+
print(f"Call Status: {call.status}")
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Migration from SignalWire
|
|
62
|
+
|
|
63
|
+
If you're migrating from SignalWire SDK:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
# Before
|
|
67
|
+
from signalwire.rest import Client as SignalWireClient
|
|
68
|
+
|
|
69
|
+
# After
|
|
70
|
+
from teloryxa import Client as SignalWireClient
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The rest of your code stays the same!
|
|
74
|
+
|
|
75
|
+
## Features
|
|
76
|
+
|
|
77
|
+
- Full SignalWire/Twilio API compatibility
|
|
78
|
+
- Call creation, retrieval, and listing
|
|
79
|
+
- Machine Detection (AMD)
|
|
80
|
+
- Recording
|
|
81
|
+
- Status callbacks
|
|
82
|
+
- Async AMD support
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
|
|
86
|
+
MIT
|
teloryxa-0.1.0/README.md
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# Teloryxa API SDK
|
|
2
|
+
|
|
3
|
+
A production-ready Python SDK for Teloryxa API - a self-hosted telephony platform compatible with SignalWire and Twilio REST API.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install teloryxa
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick Start
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from teloryxa import Client
|
|
15
|
+
|
|
16
|
+
# Connect to your Teloryxa API instance
|
|
17
|
+
client = Client(
|
|
18
|
+
project_id="your-project-id",
|
|
19
|
+
api_token="your-api-token",
|
|
20
|
+
signalwire_space_url="your-space.example.com:5000"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# Make a call
|
|
24
|
+
call = client.calls.create(
|
|
25
|
+
to="+573001234567",
|
|
26
|
+
from_="+18005550100",
|
|
27
|
+
url="https://your-backend.com/xml",
|
|
28
|
+
method="POST",
|
|
29
|
+
timeout=28,
|
|
30
|
+
record=True,
|
|
31
|
+
status_callback="https://your-backend.com/status",
|
|
32
|
+
status_callback_event=["initiated", "ringing", "completed"],
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
print(f"Call SID: {call.sid}")
|
|
36
|
+
print(f"Call Status: {call.status}")
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Migration from SignalWire
|
|
40
|
+
|
|
41
|
+
If you're migrating from SignalWire SDK:
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
# Before
|
|
45
|
+
from signalwire.rest import Client as SignalWireClient
|
|
46
|
+
|
|
47
|
+
# After
|
|
48
|
+
from teloryxa import Client as SignalWireClient
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The rest of your code stays the same!
|
|
52
|
+
|
|
53
|
+
## Features
|
|
54
|
+
|
|
55
|
+
- Full SignalWire/Twilio API compatibility
|
|
56
|
+
- Call creation, retrieval, and listing
|
|
57
|
+
- Machine Detection (AMD)
|
|
58
|
+
- Recording
|
|
59
|
+
- Status callbacks
|
|
60
|
+
- Async AMD support
|
|
61
|
+
|
|
62
|
+
## License
|
|
63
|
+
|
|
64
|
+
MIT
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "teloryxa"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Teloryxa API SDK - SignalWire/Twilio compatible voice API client"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "Teloryxa Team", email = "dev@teloryxa.com"}
|
|
13
|
+
]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.8",
|
|
20
|
+
"Programming Language :: Python :: 3.9",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"requests>=2.25.0",
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
[project.urls]
|
|
30
|
+
Homepage = "https://github.com/fooxygg/wirexa-api"
|
|
31
|
+
Repository = "https://github.com/fooxygg/wirexa-api"
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
dev = [
|
|
35
|
+
"pytest>=7.0.0",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[tool.setuptools.packages.find]
|
|
39
|
+
where = ["."]
|
|
40
|
+
include = ["teloryxa*"]
|
teloryxa-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Teloryxa API SDK - SDK compatible con la API de voz Teloryxa.
|
|
3
|
+
|
|
4
|
+
CREDENCIALES (las obtienes del dashboard):
|
|
5
|
+
space_url = "teloryxa.com"
|
|
6
|
+
project_id = "your-project-id"
|
|
7
|
+
api_token = "your-api-token"
|
|
8
|
+
|
|
9
|
+
USO:
|
|
10
|
+
|
|
11
|
+
ANTES (SignalWire original):
|
|
12
|
+
from signalwire.rest import Client
|
|
13
|
+
client = Client(project_id, api_token, signalwire_space_url=space_url)
|
|
14
|
+
|
|
15
|
+
DESPUÉS (Teloryxa API):
|
|
16
|
+
from teloryxa import Client
|
|
17
|
+
client = Client(project_id, api_token, signalwire_space_url=space_url)
|
|
18
|
+
|
|
19
|
+
El resto del código NO cambia.
|
|
20
|
+
"""
|
|
21
|
+
from teloryxa.rest import Client
|
|
22
|
+
|
|
23
|
+
__all__ = ["Client"]
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import logging
|
|
4
|
+
import requests
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
logger = logging.getLogger("teloryxa.http_client")
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class _CallsResource:
|
|
11
|
+
"""Imita el objeto client.calls del SDK."""
|
|
12
|
+
|
|
13
|
+
def __init__(self, base_url: str, auth: tuple):
|
|
14
|
+
self._base = base_url
|
|
15
|
+
self._auth = auth
|
|
16
|
+
|
|
17
|
+
def create(
|
|
18
|
+
self,
|
|
19
|
+
to: str,
|
|
20
|
+
from_: str,
|
|
21
|
+
url: str,
|
|
22
|
+
method: str = "POST",
|
|
23
|
+
timeout: int = 28,
|
|
24
|
+
record: bool = False,
|
|
25
|
+
status_callback: Optional[str] = None,
|
|
26
|
+
status_callback_method: str = "POST",
|
|
27
|
+
status_callback_event: Optional[list] = None,
|
|
28
|
+
recording_status_callback: Optional[str] = None,
|
|
29
|
+
recording_status_callback_method: str = "POST",
|
|
30
|
+
machine_detection: Optional[str] = None,
|
|
31
|
+
machine_detection_timeout: int = 30,
|
|
32
|
+
async_amd: bool = False,
|
|
33
|
+
async_amd_status_callback: Optional[str] = None,
|
|
34
|
+
) -> "_CallInstance":
|
|
35
|
+
data = {
|
|
36
|
+
"To": to,
|
|
37
|
+
"From": from_,
|
|
38
|
+
"Url": url,
|
|
39
|
+
"Method": method,
|
|
40
|
+
"Timeout": str(timeout),
|
|
41
|
+
"Record": "true" if record else "false",
|
|
42
|
+
"StatusCallbackMethod": status_callback_method,
|
|
43
|
+
"RecordingStatusCallbackMethod": recording_status_callback_method,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if status_callback:
|
|
47
|
+
data["StatusCallback"] = status_callback
|
|
48
|
+
|
|
49
|
+
if status_callback_event:
|
|
50
|
+
data["StatusCallbackEvent"] = " ".join(status_callback_event)
|
|
51
|
+
|
|
52
|
+
if recording_status_callback:
|
|
53
|
+
data["RecordingStatusCallback"] = recording_status_callback
|
|
54
|
+
|
|
55
|
+
if machine_detection:
|
|
56
|
+
data["MachineDetection"] = machine_detection
|
|
57
|
+
data["MachineDetectionTimeout"] = str(machine_detection_timeout)
|
|
58
|
+
|
|
59
|
+
if async_amd:
|
|
60
|
+
data["AsyncAmd"] = "true"
|
|
61
|
+
if async_amd_status_callback:
|
|
62
|
+
data["AsyncAmdStatusCallback"] = async_amd_status_callback
|
|
63
|
+
|
|
64
|
+
endpoint = f"{self._base}/Calls.json"
|
|
65
|
+
|
|
66
|
+
logger.info("Request: POST %s", endpoint)
|
|
67
|
+
logger.info("Params: %s", data)
|
|
68
|
+
|
|
69
|
+
r = requests.post(endpoint, auth=self._auth, data=data, timeout=30)
|
|
70
|
+
|
|
71
|
+
logger.info("Response: HTTP %s", r.status_code)
|
|
72
|
+
logger.info("Response Body: %s", r.text[:500])
|
|
73
|
+
|
|
74
|
+
r.raise_for_status()
|
|
75
|
+
instance = _CallInstance(r.json())
|
|
76
|
+
|
|
77
|
+
logger.info("[calls.create] Call %s status: %s", instance.sid, instance.status)
|
|
78
|
+
|
|
79
|
+
return instance
|
|
80
|
+
|
|
81
|
+
def list(self, status: Optional[str] = None, limit: int = 50) -> list:
|
|
82
|
+
params = {"PageSize": limit}
|
|
83
|
+
if status:
|
|
84
|
+
params["Status"] = status
|
|
85
|
+
r = requests.get(f"{self._base}/Calls.json", auth=self._auth, params=params, timeout=10)
|
|
86
|
+
r.raise_for_status()
|
|
87
|
+
return [_CallInstance(c) for c in r.json().get("calls", [])]
|
|
88
|
+
|
|
89
|
+
def __call__(self, call_sid: str) -> "_CallContext":
|
|
90
|
+
return _CallContext(self._base, self._auth, call_sid)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
class _CallContext:
|
|
94
|
+
"""Imita client.calls('CAxxxxx')"""
|
|
95
|
+
|
|
96
|
+
def __init__(self, base_url: str, auth: tuple, call_sid: str):
|
|
97
|
+
self._base = base_url
|
|
98
|
+
self._auth = auth
|
|
99
|
+
self._sid = call_sid
|
|
100
|
+
|
|
101
|
+
def fetch(self) -> "_CallInstance":
|
|
102
|
+
r = requests.get(f"{self._base}/Calls/{self._sid}.json", auth=self._auth, timeout=10)
|
|
103
|
+
r.raise_for_status()
|
|
104
|
+
return _CallInstance(r.json())
|
|
105
|
+
|
|
106
|
+
def update(self, status: Optional[str] = None, url: Optional[str] = None) -> "_CallInstance":
|
|
107
|
+
data = {}
|
|
108
|
+
if status:
|
|
109
|
+
data["Status"] = status
|
|
110
|
+
if url:
|
|
111
|
+
data["Url"] = url
|
|
112
|
+
r = requests.post(f"{self._base}/Calls/{self._sid}.json", auth=self._auth, data=data, timeout=10)
|
|
113
|
+
r.raise_for_status()
|
|
114
|
+
return _CallInstance(r.json())
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class _CallInstance:
|
|
118
|
+
"""Objeto retornado por calls.create() / fetch()."""
|
|
119
|
+
|
|
120
|
+
def __init__(self, data: dict):
|
|
121
|
+
self._data = data
|
|
122
|
+
self.sid = data.get("sid", "")
|
|
123
|
+
self.status = data.get("status", "")
|
|
124
|
+
self.to = data.get("to", "")
|
|
125
|
+
self.from_ = data.get("from", "")
|
|
126
|
+
self.direction = data.get("direction", "")
|
|
127
|
+
self.duration = data.get("duration")
|
|
128
|
+
self.answered_by = data.get("answered_by")
|
|
129
|
+
self.date_created = data.get("date_created")
|
|
130
|
+
|
|
131
|
+
def __repr__(self):
|
|
132
|
+
return f"<Call sid={self.sid!r} status={self.status!r}>"
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
class Client:
|
|
136
|
+
"""Cliente principal para Teloryxa API.
|
|
137
|
+
|
|
138
|
+
Uso:
|
|
139
|
+
client = Client(
|
|
140
|
+
project_id,
|
|
141
|
+
api_token,
|
|
142
|
+
signalwire_space_url="teloryxa.com"
|
|
143
|
+
)
|
|
144
|
+
call = client.calls.create(to=..., from_=..., url=...)
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
def __init__(
|
|
148
|
+
self,
|
|
149
|
+
project_id: str,
|
|
150
|
+
api_token: str,
|
|
151
|
+
signalwire_space_url: str = "teloryxa.com",
|
|
152
|
+
):
|
|
153
|
+
self.project_id = project_id
|
|
154
|
+
self.api_token = api_token
|
|
155
|
+
self.space_url = signalwire_space_url
|
|
156
|
+
|
|
157
|
+
protocol = "https" if "." in signalwire_space_url and ":" not in signalwire_space_url else "http"
|
|
158
|
+
self._base_url = (
|
|
159
|
+
f"{protocol}://{signalwire_space_url}"
|
|
160
|
+
f"/api/laml/2010-04-01/Accounts/{project_id}"
|
|
161
|
+
)
|
|
162
|
+
|
|
163
|
+
self._auth = (project_id, api_token)
|
|
164
|
+
self.calls = _CallsResource(self._base_url, self._auth)
|
|
165
|
+
|
|
166
|
+
def __repr__(self):
|
|
167
|
+
return f"<TeloryxaClient project={self.project_id!r} space={self.space_url!r}>"
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: teloryxa
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Teloryxa API SDK - SignalWire/Twilio compatible voice API client
|
|
5
|
+
Author-email: Teloryxa Team <dev@teloryxa.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/fooxygg/wirexa-api
|
|
8
|
+
Project-URL: Repository, https://github.com/fooxygg/wirexa-api
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
Requires-Dist: requests>=2.25.0
|
|
20
|
+
Provides-Extra: dev
|
|
21
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
22
|
+
|
|
23
|
+
# Teloryxa API SDK
|
|
24
|
+
|
|
25
|
+
A production-ready Python SDK for Teloryxa API - a self-hosted telephony platform compatible with SignalWire and Twilio REST API.
|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
pip install teloryxa
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from teloryxa import Client
|
|
37
|
+
|
|
38
|
+
# Connect to your Teloryxa API instance
|
|
39
|
+
client = Client(
|
|
40
|
+
project_id="your-project-id",
|
|
41
|
+
api_token="your-api-token",
|
|
42
|
+
signalwire_space_url="your-space.example.com:5000"
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
# Make a call
|
|
46
|
+
call = client.calls.create(
|
|
47
|
+
to="+573001234567",
|
|
48
|
+
from_="+18005550100",
|
|
49
|
+
url="https://your-backend.com/xml",
|
|
50
|
+
method="POST",
|
|
51
|
+
timeout=28,
|
|
52
|
+
record=True,
|
|
53
|
+
status_callback="https://your-backend.com/status",
|
|
54
|
+
status_callback_event=["initiated", "ringing", "completed"],
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
print(f"Call SID: {call.sid}")
|
|
58
|
+
print(f"Call Status: {call.status}")
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
## Migration from SignalWire
|
|
62
|
+
|
|
63
|
+
If you're migrating from SignalWire SDK:
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
# Before
|
|
67
|
+
from signalwire.rest import Client as SignalWireClient
|
|
68
|
+
|
|
69
|
+
# After
|
|
70
|
+
from teloryxa import Client as SignalWireClient
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The rest of your code stays the same!
|
|
74
|
+
|
|
75
|
+
## Features
|
|
76
|
+
|
|
77
|
+
- Full SignalWire/Twilio API compatibility
|
|
78
|
+
- Call creation, retrieval, and listing
|
|
79
|
+
- Machine Detection (AMD)
|
|
80
|
+
- Recording
|
|
81
|
+
- Status callbacks
|
|
82
|
+
- Async AMD support
|
|
83
|
+
|
|
84
|
+
## License
|
|
85
|
+
|
|
86
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
teloryxa
|