jambonz-python-sdk 0.2.0__py3-none-any.whl

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.
Files changed (119) hide show
  1. jambonz_python_sdk-0.2.0.dist-info/METADATA +179 -0
  2. jambonz_python_sdk-0.2.0.dist-info/RECORD +119 -0
  3. jambonz_python_sdk-0.2.0.dist-info/WHEEL +4 -0
  4. jambonz_sdk/__init__.py +52 -0
  5. jambonz_sdk/_signature.py +73 -0
  6. jambonz_sdk/client/__init__.py +15 -0
  7. jambonz_sdk/client/api.py +241 -0
  8. jambonz_sdk/schema/callbacks/amd.schema.json +50 -0
  9. jambonz_sdk/schema/callbacks/base.schema.json +29 -0
  10. jambonz_sdk/schema/callbacks/call-status.schema.json +22 -0
  11. jambonz_sdk/schema/callbacks/conference-status.schema.json +24 -0
  12. jambonz_sdk/schema/callbacks/conference-wait.schema.json +11 -0
  13. jambonz_sdk/schema/callbacks/conference.schema.json +11 -0
  14. jambonz_sdk/schema/callbacks/dequeue.schema.json +19 -0
  15. jambonz_sdk/schema/callbacks/dial-dtmf.schema.json +18 -0
  16. jambonz_sdk/schema/callbacks/dial-hold.schema.json +22 -0
  17. jambonz_sdk/schema/callbacks/dial-refer.schema.json +28 -0
  18. jambonz_sdk/schema/callbacks/dial.schema.json +31 -0
  19. jambonz_sdk/schema/callbacks/enqueue-wait.schema.json +17 -0
  20. jambonz_sdk/schema/callbacks/enqueue.schema.json +27 -0
  21. jambonz_sdk/schema/callbacks/gather-partial.schema.json +54 -0
  22. jambonz_sdk/schema/callbacks/gather.schema.json +60 -0
  23. jambonz_sdk/schema/callbacks/listen.schema.json +21 -0
  24. jambonz_sdk/schema/callbacks/llm.schema.json +30 -0
  25. jambonz_sdk/schema/callbacks/message.schema.json +35 -0
  26. jambonz_sdk/schema/callbacks/pipeline-turn.schema.json +109 -0
  27. jambonz_sdk/schema/callbacks/play.schema.json +36 -0
  28. jambonz_sdk/schema/callbacks/session-new.schema.json +143 -0
  29. jambonz_sdk/schema/callbacks/session-reconnect.schema.json +9 -0
  30. jambonz_sdk/schema/callbacks/session-redirect.schema.json +38 -0
  31. jambonz_sdk/schema/callbacks/sip-refer-event.schema.json +20 -0
  32. jambonz_sdk/schema/callbacks/sip-refer.schema.json +22 -0
  33. jambonz_sdk/schema/callbacks/sip-request.schema.json +27 -0
  34. jambonz_sdk/schema/callbacks/transcribe-translation.schema.json +24 -0
  35. jambonz_sdk/schema/callbacks/transcribe.schema.json +46 -0
  36. jambonz_sdk/schema/callbacks/tts-streaming-event.schema.json +77 -0
  37. jambonz_sdk/schema/callbacks/verb-status.schema.json +57 -0
  38. jambonz_sdk/schema/components/actionHook.schema.json +36 -0
  39. jambonz_sdk/schema/components/actionHookDelayAction.schema.json +37 -0
  40. jambonz_sdk/schema/components/amd.schema.json +68 -0
  41. jambonz_sdk/schema/components/auth.schema.json +18 -0
  42. jambonz_sdk/schema/components/bidirectionalAudio.schema.json +22 -0
  43. jambonz_sdk/schema/components/fillerNoise.schema.json +25 -0
  44. jambonz_sdk/schema/components/llm-base.schema.json +94 -0
  45. jambonz_sdk/schema/components/recognizer-assemblyAiOptions.schema.json +66 -0
  46. jambonz_sdk/schema/components/recognizer-awsOptions.schema.json +52 -0
  47. jambonz_sdk/schema/components/recognizer-azureOptions.schema.json +32 -0
  48. jambonz_sdk/schema/components/recognizer-cobaltOptions.schema.json +34 -0
  49. jambonz_sdk/schema/components/recognizer-customOptions.schema.json +27 -0
  50. jambonz_sdk/schema/components/recognizer-deepgramOptions.schema.json +147 -0
  51. jambonz_sdk/schema/components/recognizer-elevenlabsOptions.schema.json +39 -0
  52. jambonz_sdk/schema/components/recognizer-gladiaOptions.schema.json +8 -0
  53. jambonz_sdk/schema/components/recognizer-googleOptions.schema.json +35 -0
  54. jambonz_sdk/schema/components/recognizer-houndifyOptions.schema.json +53 -0
  55. jambonz_sdk/schema/components/recognizer-ibmOptions.schema.json +54 -0
  56. jambonz_sdk/schema/components/recognizer-nuanceOptions.schema.json +150 -0
  57. jambonz_sdk/schema/components/recognizer-nvidiaOptions.schema.json +39 -0
  58. jambonz_sdk/schema/components/recognizer-openaiOptions.schema.json +59 -0
  59. jambonz_sdk/schema/components/recognizer-sonioxOptions.schema.json +46 -0
  60. jambonz_sdk/schema/components/recognizer-speechmaticsOptions.schema.json +100 -0
  61. jambonz_sdk/schema/components/recognizer-verbioOptions.schema.json +46 -0
  62. jambonz_sdk/schema/components/recognizer.schema.json +216 -0
  63. jambonz_sdk/schema/components/synthesizer.schema.json +82 -0
  64. jambonz_sdk/schema/components/target.schema.json +105 -0
  65. jambonz_sdk/schema/components/vad.schema.json +48 -0
  66. jambonz_sdk/schema/jambonz-app.schema.json +113 -0
  67. jambonz_sdk/schema/verbs/alert.schema.json +34 -0
  68. jambonz_sdk/schema/verbs/answer.schema.json +22 -0
  69. jambonz_sdk/schema/verbs/conference.schema.json +107 -0
  70. jambonz_sdk/schema/verbs/config.schema.json +221 -0
  71. jambonz_sdk/schema/verbs/deepgram_s2s.schema.json +81 -0
  72. jambonz_sdk/schema/verbs/dequeue.schema.json +51 -0
  73. jambonz_sdk/schema/verbs/dial.schema.json +200 -0
  74. jambonz_sdk/schema/verbs/dialogflow.schema.json +148 -0
  75. jambonz_sdk/schema/verbs/dtmf.schema.json +49 -0
  76. jambonz_sdk/schema/verbs/dub.schema.json +103 -0
  77. jambonz_sdk/schema/verbs/elevenlabs_s2s.schema.json +81 -0
  78. jambonz_sdk/schema/verbs/enqueue.schema.json +53 -0
  79. jambonz_sdk/schema/verbs/gather.schema.json +190 -0
  80. jambonz_sdk/schema/verbs/google_s2s.schema.json +42 -0
  81. jambonz_sdk/schema/verbs/hangup.schema.json +36 -0
  82. jambonz_sdk/schema/verbs/leave.schema.json +22 -0
  83. jambonz_sdk/schema/verbs/listen.schema.json +127 -0
  84. jambonz_sdk/schema/verbs/llm.schema.json +44 -0
  85. jambonz_sdk/schema/verbs/message.schema.json +82 -0
  86. jambonz_sdk/schema/verbs/openai_s2s.schema.json +42 -0
  87. jambonz_sdk/schema/verbs/pause.schema.json +36 -0
  88. jambonz_sdk/schema/verbs/pipeline.schema.json +240 -0
  89. jambonz_sdk/schema/verbs/play.schema.json +96 -0
  90. jambonz_sdk/schema/verbs/redirect.schema.json +34 -0
  91. jambonz_sdk/schema/verbs/rest_dial.schema.json +113 -0
  92. jambonz_sdk/schema/verbs/s2s.schema.json +39 -0
  93. jambonz_sdk/schema/verbs/say.schema.json +107 -0
  94. jambonz_sdk/schema/verbs/sip-decline.schema.json +58 -0
  95. jambonz_sdk/schema/verbs/sip-refer.schema.json +58 -0
  96. jambonz_sdk/schema/verbs/sip-request.schema.json +54 -0
  97. jambonz_sdk/schema/verbs/stream.schema.json +103 -0
  98. jambonz_sdk/schema/verbs/tag.schema.json +41 -0
  99. jambonz_sdk/schema/verbs/transcribe.schema.json +57 -0
  100. jambonz_sdk/schema/verbs/ultravox_s2s.schema.json +41 -0
  101. jambonz_sdk/types/__init__.py +139 -0
  102. jambonz_sdk/types/components.py +250 -0
  103. jambonz_sdk/types/rest.py +59 -0
  104. jambonz_sdk/types/session.py +55 -0
  105. jambonz_sdk/types/verbs.py +572 -0
  106. jambonz_sdk/validator.py +107 -0
  107. jambonz_sdk/verb_builder.py +316 -0
  108. jambonz_sdk/verb_builder.pyi +1133 -0
  109. jambonz_sdk/verb_registry.py +102 -0
  110. jambonz_sdk/webhook/__init__.py +10 -0
  111. jambonz_sdk/webhook/middleware.py +63 -0
  112. jambonz_sdk/webhook/response.py +43 -0
  113. jambonz_sdk/websocket/__init__.py +15 -0
  114. jambonz_sdk/websocket/audio_client.py +11 -0
  115. jambonz_sdk/websocket/audio_stream.py +151 -0
  116. jambonz_sdk/websocket/client.py +165 -0
  117. jambonz_sdk/websocket/endpoint.py +193 -0
  118. jambonz_sdk/websocket/router.py +87 -0
  119. jambonz_sdk/websocket/session.py +259 -0
@@ -0,0 +1,179 @@
1
+ Metadata-Version: 2.4
2
+ Name: jambonz-python-sdk
3
+ Version: 0.2.0
4
+ Summary: Python SDK for jambonz CPaaS platform
5
+ Project-URL: Homepage, https://github.com/jambonz/jambonz-python-sdk
6
+ Project-URL: Repository, https://github.com/jambonz/jambonz-python-sdk
7
+ Project-URL: Issues, https://github.com/jambonz/jambonz-python-sdk/issues
8
+ Project-URL: Documentation, https://jambonz.org
9
+ License-Expression: MIT
10
+ Keywords: cpaas,jambonz,sip,telephony,voip,websocket
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Framework :: AsyncIO
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
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 :: Telephony
21
+ Requires-Python: >=3.10
22
+ Requires-Dist: aiohttp>=3.9
23
+ Requires-Dist: jsonschema>=4.20
24
+ Requires-Dist: referencing>=0.31
25
+ Requires-Dist: typing-extensions>=4.0; python_version < '3.11'
26
+ Provides-Extra: dev
27
+ Requires-Dist: aioresponses>=0.7; extra == 'dev'
28
+ Requires-Dist: mypy>=1.10; extra == 'dev'
29
+ Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
30
+ Requires-Dist: pytest-cov>=5.0; extra == 'dev'
31
+ Requires-Dist: pytest>=8.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.4; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # jambonz Python SDK
36
+
37
+ Python SDK for the [jambonz](https://jambonz.org) CPaaS platform.
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ pip install jambonz-python-sdk
43
+ ```
44
+
45
+ ## Quick Start
46
+
47
+ ### Webhook (HTTP)
48
+
49
+ ```python
50
+ from aiohttp import web
51
+ from jambonz_sdk.webhook import WebhookResponse
52
+
53
+ async def handle_incoming(request: web.Request) -> web.Response:
54
+ jambonz = WebhookResponse()
55
+ jambonz.say(text="Hello!").gather(
56
+ input=["speech"],
57
+ actionHook="/handle-input",
58
+ timeout=10,
59
+ say={"text": "Please say something."},
60
+ ).hangup()
61
+ return web.json_response(jambonz.to_json())
62
+
63
+ app = web.Application()
64
+ app.router.add_post("/incoming", handle_incoming)
65
+ web.run_app(app, port=3000)
66
+ ```
67
+
68
+ ### WebSocket
69
+
70
+ ```python
71
+ import asyncio
72
+ from jambonz_sdk.websocket import create_endpoint
73
+
74
+ async def main():
75
+ make_service, runner = await create_endpoint(port=3000)
76
+ svc = make_service(path="/")
77
+
78
+ async def handle_session(session):
79
+ session.say(text="Hello!").hangup()
80
+ await session.send()
81
+
82
+ svc.on("session:new", handle_session)
83
+ await asyncio.Future()
84
+
85
+ asyncio.run(main())
86
+ ```
87
+
88
+ ### REST Client
89
+
90
+ ```python
91
+ from jambonz_sdk.client import JambonzClient
92
+
93
+ async with JambonzClient(
94
+ base_url="https://api.jambonz.us",
95
+ account_sid="your-account-sid",
96
+ api_key="your-api-key",
97
+ ) as client:
98
+ call_sid = await client.calls.create({
99
+ "from": "+15085551212",
100
+ "to": {"type": "phone", "number": "+15085551213"},
101
+ "call_hook": "/incoming",
102
+ })
103
+ ```
104
+
105
+ ## How It Works
106
+
107
+ ### Spec-driven verb generation
108
+
109
+ The SDK does **not** hardcode verb method signatures. Instead, verb methods (`.say()`, `.gather()`, `.dial()`, `.pipeline()`, etc.) are **auto-generated at import time** from [JSON Schema](https://github.com/jambonz/schema) files — the same schemas used by the Node.js SDK and the jambonz server.
110
+
111
+ **What this means:**
112
+
113
+ - When the schema adds a new property to a verb, the SDK picks it up automatically — no code change needed
114
+ - Every method has **real typed parameters** (not `**kwargs: Any`) so IDEs show autocomplete and type hints
115
+ - Verb synonyms (`stream` ↔ `listen`, `openai_s2s` → `llm` with `vendor: "openai"`) are handled by the registry
116
+
117
+ ### Updating the schema
118
+
119
+ ```bash
120
+ # Download the pinned version from @jambonz/schema:
121
+ python scripts/sync_schema.py
122
+
123
+ # Or copy from a local clone:
124
+ python scripts/sync_schema.py --local /path/to/schema
125
+ ```
126
+
127
+ If a **new verb** was added (not just new properties), add one line to `verb_registry.py`:
128
+
129
+ ```python
130
+ VerbDef("new_verb", "new_verb", doc="Description.")
131
+ ```
132
+
133
+ ## Features
134
+
135
+ - **All 31 jambonz verbs**: say, play, gather, dial, conference, enqueue/dequeue, hangup, pause, redirect, config, tag, dtmf, dub, message, alert, answer, leave, listen/stream, transcribe, openai_s2s, google_s2s, deepgram_s2s, elevenlabs_s2s, ultravox_s2s, s2s, llm, dialogflow, pipeline, sip_decline, sip_request, sip_refer
136
+ - **Fluent chainable API**: `.say(...).gather(...).hangup()`
137
+ - **Webhook transport**: `WebhookResponse` for HTTP apps (works with aiohttp, FastAPI, Flask, etc.)
138
+ - **WebSocket transport**: `create_endpoint` with `Session`, event handling, `send()`/`reply()`
139
+ - **REST client**: `JambonzClient` with calls, conferences, queues, mid-call control
140
+ - **Audio streaming**: Bidirectional audio via `AudioStream`
141
+ - **Mid-call control**: inject commands (mute, whisper, record, DTMF, tag)
142
+ - **TTS token streaming**: `send_tts_tokens()` / `flush_tts_tokens()`
143
+ - **Pipeline updates**: `update_pipeline()` for mid-conversation LLM changes
144
+ - **Signature verification**: HMAC-SHA256 webhook signature validation
145
+ - **Env vars**: Portal discovery via OPTIONS + runtime reading
146
+
147
+ ## Examples
148
+
149
+ See the [`examples/`](examples/) directory:
150
+
151
+ | Example | Webhook | WebSocket | Description |
152
+ |---------|---------|-----------|-------------|
153
+ | hello-world | [webhook](examples/hello-world/webhook_app.py) | [websocket](examples/hello-world/websocket_app.py) | Minimal greeting |
154
+ | echo | [webhook](examples/echo/webhook_app.py) | [websocket](examples/echo/websocket_app.py) | Speech echo with gather |
155
+ | ivr-menu | [webhook](examples/ivr-menu/webhook_app.py) | — | IVR menu with speech + DTMF |
156
+ | voice-agent | [webhook](examples/voice-agent/webhook_app.py) | [websocket](examples/voice-agent/websocket_app.py) | LLM pipeline with tool calls |
157
+ | dial | [webhook](examples/dial/webhook_app.py) | — | Outbound dial with fallback |
158
+ | listen-record | [webhook](examples/listen-record/webhook_app.py) | [websocket](examples/listen-record/websocket_app.py) | Audio recording |
159
+
160
+ ## Development
161
+
162
+ ```bash
163
+ # Create venv and install
164
+ python3 -m venv .venv
165
+ source .venv/bin/activate
166
+ pip install -e ".[dev]"
167
+
168
+ # Run tests
169
+ pytest tests/unit/ # Fast unit tests (253)
170
+ pytest tests/integration/ # Real server tests (26)
171
+ pytest # All 279 tests
172
+
173
+ # Sync schema from upstream
174
+ python scripts/sync_schema.py
175
+ ```
176
+
177
+ ## License
178
+
179
+ MIT
@@ -0,0 +1,119 @@
1
+ jambonz_sdk/__init__.py,sha256=FhooW-LiVUck04Iz_lEY0_LCxfsZo1TPpafaZuKoVQ8,1391
2
+ jambonz_sdk/_signature.py,sha256=3sy95S310ALrTX2_2w3xH5KLBPKYacy08dpYOxu39i8,2007
3
+ jambonz_sdk/validator.py,sha256=A5nXjeF8BguHwpzmHpkjch4Pw__I4DOVp9qmwfgk7F0,3770
4
+ jambonz_sdk/verb_builder.py,sha256=xI1MWPBB0S0PshCJTeRqmSR7FYKdH5QQVCc1IltuCG8,10899
5
+ jambonz_sdk/verb_builder.pyi,sha256=4fgGI-FbFkrE4yyKkCHn7U0KSBJ0HM5kF86UyobGyps,30730
6
+ jambonz_sdk/verb_registry.py,sha256=QNfFpUW_7mcS3pf_35oSHEAfwF7FVBCcpD3QObxki_s,4953
7
+ jambonz_sdk/client/__init__.py,sha256=0EpEk8feWsFOw54cqpe7aMF7ZrHm4BGnTA9Qtg0Id6w,273
8
+ jambonz_sdk/client/api.py,sha256=aN-nQ6BqEiuLKe_jbIu0JjVMSZe2ZPlFYvsJg8vehZI,7442
9
+ jambonz_sdk/schema/jambonz-app.schema.json,sha256=CaOPh8VIlNzwJmBe33Hrki46Efz5_wrEpSYwoCClDQE,4332
10
+ jambonz_sdk/schema/callbacks/amd.schema.json,sha256=2XvGFxiTuQ2kYY0LernYqmTjVEftfx3sek4Sjq5vSnA,1953
11
+ jambonz_sdk/schema/callbacks/base.schema.json,sha256=G0l-doDap-xZypHXZC3ectVK36Z6SHs_iXj5mKxYWYw,1958
12
+ jambonz_sdk/schema/callbacks/call-status.schema.json,sha256=PtPWkRygCdYsP60096stOXrwEbiqvPV9YGvEzpx2XeM,1127
13
+ jambonz_sdk/schema/callbacks/conference-status.schema.json,sha256=YZ-kpaSZMjk1qYZ-CS13NxBNJuJ88i1xElm9s8Dz6KM,1194
14
+ jambonz_sdk/schema/callbacks/conference-wait.schema.json,sha256=IMEBBxFxQUgHf42i9hp2j0an-j24U4D_EJ1eQ1DNJwk,477
15
+ jambonz_sdk/schema/callbacks/conference.schema.json,sha256=mOdI63zITfGRDT-j_bvwKSTgi8AQ2zdf3Fc7YXEzaiY,416
16
+ jambonz_sdk/schema/callbacks/dequeue.schema.json,sha256=s65QvBPCZZ9KeOVlJWJUjZLGIgVnNA4f6p_UwgYwOx4,695
17
+ jambonz_sdk/schema/callbacks/dial-dtmf.schema.json,sha256=mfglBf1cGLz8hFdM7N-O74lxIab08akLku_d680iysM,570
18
+ jambonz_sdk/schema/callbacks/dial-hold.schema.json,sha256=KNUZpiTNLm_XuZI-p7fy1oym9_BcsZ_DrBB1V-Ikgow,828
19
+ jambonz_sdk/schema/callbacks/dial-refer.schema.json,sha256=m__lzLCBzOWLnzyX1Lxuvz3YuAQ2ARxFKCtAfDprOCg,1538
20
+ jambonz_sdk/schema/callbacks/dial.schema.json,sha256=y_3xmAiAMrpG2cadOGqdWdCyw_aWggpF7HLeWBBpObE,1110
21
+ jambonz_sdk/schema/callbacks/enqueue-wait.schema.json,sha256=Gl_BdbW3VpKKF2iRmzT8dgdZUUmqMxCrf2Mp8d2aOZg,1207
22
+ jambonz_sdk/schema/callbacks/enqueue.schema.json,sha256=uGDOHoLZNnfuFb0Dx27YD7GK5ky4iWvlPSps_u5_Sv4,1129
23
+ jambonz_sdk/schema/callbacks/gather-partial.schema.json,sha256=TNmfDqBmWFLJYPTJBS8wf1eoVQ_6bLB4A6jbdUeJDAY,3377
24
+ jambonz_sdk/schema/callbacks/gather.schema.json,sha256=EKApuYTHV_sBcrpGnpR4y5GvYotrJm5M4BIvIUsMZs4,2601
25
+ jambonz_sdk/schema/callbacks/listen.schema.json,sha256=D8_J7MDBhNwEn3nwRHWXkZIsHb0ap2vY2ehfOAI4Vio,686
26
+ jambonz_sdk/schema/callbacks/llm.schema.json,sha256=anXe9QD0X_8pSo_NAj_TJEfKpPNdAfFJQTUOI-Y3ZL4,976
27
+ jambonz_sdk/schema/callbacks/message.schema.json,sha256=t2nO4Gb1bXi9JtA4NwVeFudOFzbyEbnOrGDCFhRxM44,1245
28
+ jambonz_sdk/schema/callbacks/pipeline-turn.schema.json,sha256=1OBaA255zj3Ug0tqtfoWCVNsNcRSinKPDcSNEiBNQ04,4514
29
+ jambonz_sdk/schema/callbacks/play.schema.json,sha256=XpyFUlE1ywhfNmHu-q_KrvQl4jwJqxHQBCIPT9eCrGs,1253
30
+ jambonz_sdk/schema/callbacks/session-new.schema.json,sha256=ENqyXSu6lKb6uOE_xup3xctjjKjKV-lvWRpw1yfnj50,5429
31
+ jambonz_sdk/schema/callbacks/session-reconnect.schema.json,sha256=dMyK4dkahnXVCPg5hAQtsZxb3E8gXKRJ8dkROYMPC-4,538
32
+ jambonz_sdk/schema/callbacks/session-redirect.schema.json,sha256=Xvz7i7R8YjX_J0Zkv_Ovy9KHJ0kcrETRTMgDJRpvcvs,1398
33
+ jambonz_sdk/schema/callbacks/sip-refer-event.schema.json,sha256=rs4AkEVm_zi1SyyCIv94l3uDLwSlZnD_pp-ejmj56z0,751
34
+ jambonz_sdk/schema/callbacks/sip-refer.schema.json,sha256=oGa7Xg8f8aP0gaRfpM0MrlNIuU203ehP9dlWQ5xLkn0,887
35
+ jambonz_sdk/schema/callbacks/sip-request.schema.json,sha256=e0PWYRUwJR-TWYFU7WeI0E7DgfHDRZJTH-gbb_CLAhw,858
36
+ jambonz_sdk/schema/callbacks/transcribe-translation.schema.json,sha256=eRn6eqDuADy0NrcbKX6YmlSS6dVJpR8J0_mj4Ef4hQE,891
37
+ jambonz_sdk/schema/callbacks/transcribe.schema.json,sha256=8-8t7MIpEtpM0ZkdNIZeh820N8jFVAaCFgv-fs41Mmk,2130
38
+ jambonz_sdk/schema/callbacks/tts-streaming-event.schema.json,sha256=yAY-RIoXWm2NhDxuX8JB3OPEktxlBoRAjVjdFN4WmTM,2570
39
+ jambonz_sdk/schema/callbacks/verb-status.schema.json,sha256=PwetY3q0WK8u6rKc3G3ozbDG4Cb6_P0w3HbitjSTg_w,2039
40
+ jambonz_sdk/schema/components/actionHook.schema.json,sha256=cteHhGPzvNfGNJVKWkwdkxbFT6Ph2xDC84_6TwFN1kM,1796
41
+ jambonz_sdk/schema/components/actionHookDelayAction.schema.json,sha256=w3gSk0aUDWWJ8XDMxDl55BYWOmtUV8nP3XRV2Ud9m2o,1722
42
+ jambonz_sdk/schema/components/amd.schema.json,sha256=-WjQJMPqIKbw-za9_BkcwCfYPoQ2nB7LZ1JlSeNDfvc,2863
43
+ jambonz_sdk/schema/components/auth.schema.json,sha256=oqTJ4oKUINFF2kHRARmITSI5C49dTICSVqdizIrv7ek,578
44
+ jambonz_sdk/schema/components/bidirectionalAudio.schema.json,sha256=o9-p_I6ZwcK5ckUpTE7U68yN1tiW3nJSSMvKxu4bf7o,861
45
+ jambonz_sdk/schema/components/fillerNoise.schema.json,sha256=KuNzxDDKgKnlVBiqrJjSyM83wpCEC3Pu8swDYjrR9jE,1054
46
+ jambonz_sdk/schema/components/llm-base.schema.json,sha256=yC5LSVNTbjM_7FF-Jit65J5zF3pa_5ILkwim-zJXlZY,3436
47
+ jambonz_sdk/schema/components/recognizer-assemblyAiOptions.schema.json,sha256=JfjDNUoUOSzX5WD4cKXAAJVrQ-Pv1g29dMzdAwamO7k,2119
48
+ jambonz_sdk/schema/components/recognizer-awsOptions.schema.json,sha256=Z7adtaaVgHjjz3lx6gXghwxZXHQwu36HDADu9tMhS-I,1660
49
+ jambonz_sdk/schema/components/recognizer-azureOptions.schema.json,sha256=r8WNOEuPyan9kVCaRLJ8ycxOwzgQ3s4Kcsb8fd96kJk,1144
50
+ jambonz_sdk/schema/components/recognizer-cobaltOptions.schema.json,sha256=rLbrKh3Cr_LRy8fAPUOpEg7i2dHxtZStqwoumsdeo8I,1031
51
+ jambonz_sdk/schema/components/recognizer-customOptions.schema.json,sha256=1mLPULdn9zGouockiymNoaZwcBtrtG8BBL08rHHdtJY,864
52
+ jambonz_sdk/schema/components/recognizer-deepgramOptions.schema.json,sha256=JygJcdKOXpBDp6nPCq4H8H8pdlSGtC9gzUhuVuClMy8,4385
53
+ jambonz_sdk/schema/components/recognizer-elevenlabsOptions.schema.json,sha256=JriyGgBWSKaStxAJB4LIcFYnWZE-6Diy3XPncWZgmRY,1333
54
+ jambonz_sdk/schema/components/recognizer-gladiaOptions.schema.json,sha256=6Sk_xWl1tB5qTAptKSYPjZJyGG0jK-A0QlmswSSo9YQ,382
55
+ jambonz_sdk/schema/components/recognizer-googleOptions.schema.json,sha256=qIygKgsRnZjW9oZ5i1vA2nSrfEwGk9Wvrl4bJ3mrprk,1158
56
+ jambonz_sdk/schema/components/recognizer-houndifyOptions.schema.json,sha256=EOTFZZTvRZlgr42mHWtn8_c9st0Vw_azYbXwMQbM8YM,3598
57
+ jambonz_sdk/schema/components/recognizer-ibmOptions.schema.json,sha256=0lLxVUYA9735PMi7ZRgjVO4EvoERh54vd9AyK-GtEt0,1555
58
+ jambonz_sdk/schema/components/recognizer-nuanceOptions.schema.json,sha256=PSbtOPUy-FryOY5O0HA03ZSAUAF1mVoS-8RXF2NDaqY,5077
59
+ jambonz_sdk/schema/components/recognizer-nvidiaOptions.schema.json,sha256=AAvwTy5iSrMEw-qoCFmxQPQ_tX4ewk88R4ncphDbDgE,1182
60
+ jambonz_sdk/schema/components/recognizer-openaiOptions.schema.json,sha256=L9H8_0hm5AElpiO6doigMbMSqp8ZDL_rq1xu51J5Syw,2237
61
+ jambonz_sdk/schema/components/recognizer-sonioxOptions.schema.json,sha256=HkMiX5Ul4b4W0Lz4APle5UgKKwefPZ5rehcCUg96pqU,1686
62
+ jambonz_sdk/schema/components/recognizer-speechmaticsOptions.schema.json,sha256=0q6ycpeTSFjc-cd0bBZyJCB2sw82633TXU7EmITIECA,3642
63
+ jambonz_sdk/schema/components/recognizer-verbioOptions.schema.json,sha256=gq64hfKwf56iF-MmpSaeZZjcfP5A1gGdIgLHauCa0xg,1438
64
+ jambonz_sdk/schema/components/recognizer.schema.json,sha256=M0RZFvNHsedZ7TVjKGen49hwutZv5lzIG5_1HK8up9c,9073
65
+ jambonz_sdk/schema/components/synthesizer.schema.json,sha256=-MiCdHn1N7ZXUokhGJU0dc3cc0zRhlOsAuOIltKmJPk,3302
66
+ jambonz_sdk/schema/components/target.schema.json,sha256=zBEvVYZIzMWexip2W_yvWn44dcc3pnWlLDDCQPN_Mmk,3473
67
+ jambonz_sdk/schema/components/vad.schema.json,sha256=IFgTWDImRoa2EctcvKSYB5iyDlXpUXNhAu8ldGPyn00,1869
68
+ jambonz_sdk/schema/verbs/alert.schema.json,sha256=bwV5K_8aT4RkJyd8kk5zqrAONEKtsDr0ieLqaC3tIGU,911
69
+ jambonz_sdk/schema/verbs/answer.schema.json,sha256=m7M3bsuwr0zwcatjgQeD4YSluWJeliAvT7ZNleB6a2E,690
70
+ jambonz_sdk/schema/verbs/conference.schema.json,sha256=hwtyuHNN5hAspCN7rL4CueNU8VySVSnBhFI6vpnhBV0,3798
71
+ jambonz_sdk/schema/verbs/config.schema.json,sha256=V1nSs2p_9Z_e1bhFHNPuBV6XXP8WeWyXpdml6cYtyt0,7109
72
+ jambonz_sdk/schema/verbs/deepgram_s2s.schema.json,sha256=xqcCwNZGeNrSCauRIiZ22re1IavS2y311p69DwACqkk,2284
73
+ jambonz_sdk/schema/verbs/dequeue.schema.json,sha256=-h1RdRKQsMqa9WeX0mbe7fSJd3GQ7uZ9p0A7AErg6Zs,1407
74
+ jambonz_sdk/schema/verbs/dial.schema.json,sha256=-khc5zsn-oP-p5qEr2fIKYzRITqs48IrO45MIYWzF9Y,7266
75
+ jambonz_sdk/schema/verbs/dialogflow.schema.json,sha256=aLoZ_wru_ZR2-rBN7MvkjbWSMyFKKgEPJZNsT-nDRNU,4416
76
+ jambonz_sdk/schema/verbs/dtmf.schema.json,sha256=2gwOII-xdbfwDnKE09Ds-D1bhQPIiHchCy6714ke91U,1147
77
+ jambonz_sdk/schema/verbs/dub.schema.json,sha256=ECEg6hOq_WigemwwDpl1WXsqf_JgqBrSbnPQZJO-Azc,2521
78
+ jambonz_sdk/schema/verbs/elevenlabs_s2s.schema.json,sha256=8gZT2yiqngY2nEqOKH1I0dqxjHnqwpl90SVc-0ndkuA,2508
79
+ jambonz_sdk/schema/verbs/enqueue.schema.json,sha256=xTLo7LNm8o8w-jNuBQJw83RNHV5AJN6wkDbT5INvS5c,1767
80
+ jambonz_sdk/schema/verbs/gather.schema.json,sha256=ee9KndAfUzGovbgZYc8j9Jhwn_Bj-oFsXq7WlPWNFsg,6181
81
+ jambonz_sdk/schema/verbs/google_s2s.schema.json,sha256=XPuLP0Py0mwCnggfbKQq_sFyvqIjdidPchFG-kY3xUw,1035
82
+ jambonz_sdk/schema/verbs/hangup.schema.json,sha256=QGoorQDijZpF9B9npjXQazfDxCnD50PshI4awEaNKV8,888
83
+ jambonz_sdk/schema/verbs/leave.schema.json,sha256=Iwy8Qe7qZGFNnW9bTmBTR7mySEXd3Kc-JshEB9XI7M0,574
84
+ jambonz_sdk/schema/verbs/listen.schema.json,sha256=azmsc5sQxTdTLTCYPbouXh_E6y1e2QcWLPPfx0WAgqM,4061
85
+ jambonz_sdk/schema/verbs/llm.schema.json,sha256=9jCYQxeLVaWVarKal3Zu2ajy3yOQ6LzqEv0H5jO_X6k,1234
86
+ jambonz_sdk/schema/verbs/message.schema.json,sha256=FNygt6xo_ff0EyOzqrOD0NVG7Df7ZyjvwLfRAyW8Ua0,2233
87
+ jambonz_sdk/schema/verbs/openai_s2s.schema.json,sha256=nWYihUfihZQg6azl-PKb9caLNfKNPPb22MyLK2h2Hns,1035
88
+ jambonz_sdk/schema/verbs/pause.schema.json,sha256=m-lgem141QCFcR9x1HEntDrV_IRwWsdVkP3z84Bjj3M,837
89
+ jambonz_sdk/schema/verbs/pipeline.schema.json,sha256=ilniLadTkJLjW8eW0aXCHd5V8RJwXY8bCNIq4HQLe6A,8867
90
+ jambonz_sdk/schema/verbs/play.schema.json,sha256=uf4k54-iuH1p7ctQsiKd5BKVTiy2aHNa3OCJnr-TpU0,2442
91
+ jambonz_sdk/schema/verbs/redirect.schema.json,sha256=8HxGjFA0mbJKcl8ZsyiD9b0edOzxkp1dVsA962z7lWI,1085
92
+ jambonz_sdk/schema/verbs/rest_dial.schema.json,sha256=K913G1pLVAxx4msjf2We7V3RGVEvyNWbeTRSmpJ3mEM,2841
93
+ jambonz_sdk/schema/verbs/s2s.schema.json,sha256=YPMjwPfq_VfQOtQscBIKFaK0OHiDw1LH8j5GxSJnGpw,912
94
+ jambonz_sdk/schema/verbs/say.schema.json,sha256=0Mhaw3DgvIylFJn8v6weO07wKzsgBHNueEXouEyBTtk,3521
95
+ jambonz_sdk/schema/verbs/sip-decline.schema.json,sha256=10iWST4JIwGrT1yP758YnEaijPyt-A7i-1Rg6yYJUd0,1404
96
+ jambonz_sdk/schema/verbs/sip-refer.schema.json,sha256=ogvdMtq8oP452SzR0lw0x-jmPkRtaUmiHa-4FY-GMlw,1720
97
+ jambonz_sdk/schema/verbs/sip-request.schema.json,sha256=czrONgdLCErVpV5wHw_i4YZyqyIgD1GeiVrgswKsBvw,1430
98
+ jambonz_sdk/schema/verbs/stream.schema.json,sha256=Xs3H3GSfdgul-spNREGKOyEiIofvFW6mIhRKjGsrGTg,2930
99
+ jambonz_sdk/schema/verbs/tag.schema.json,sha256=VKzVKh-YOwJxnLFrj9nFBzV0JFc7MyYzmOnjnzJ3KwA,1153
100
+ jambonz_sdk/schema/verbs/transcribe.schema.json,sha256=5cM1CYcdo-rFCE5wRDIqFtpEOf4v4BZs-yLjZc37tSE,1851
101
+ jambonz_sdk/schema/verbs/ultravox_s2s.schema.json,sha256=5QpPMgfQq3RTzWve3U6fKeZPst5oUGYO1n7OfiKWPl0,1017
102
+ jambonz_sdk/types/__init__.py,sha256=o0dkleGg8jqvORhD_mXumuos-NPisyu_CwTa-XG7kUQ,2428
103
+ jambonz_sdk/types/components.py,sha256=QHykPAfdDrlgmedmJykPUU5QZwi8ZiFbQkdgnumBmQk,5745
104
+ jambonz_sdk/types/rest.py,sha256=CFX0J-deBMoG8oXtoJzFIRBBKbjTULaUOnsV-mx09i8,1206
105
+ jambonz_sdk/types/session.py,sha256=kl2lv9z0aCfq9nD5nFzqRjVjVDeAERA_c9U4HUzqEQA,1305
106
+ jambonz_sdk/types/verbs.py,sha256=cOirvlP8gYnNK_JGjJ2FAdcMweZB3N9_4U3tv2vjqU8,12129
107
+ jambonz_sdk/webhook/__init__.py,sha256=JU-KEgTFn1uj8CPFKhFF_fUuwfElDR3hcv6nyK8tt9E,307
108
+ jambonz_sdk/webhook/middleware.py,sha256=8FuqDRJe6bOFLinU-_hTJCD_tOPxIMp2iHs4tY1SAqo,1931
109
+ jambonz_sdk/webhook/response.py,sha256=yL1JE-VjCfU2RPERA4-dl73iYqS9qQYMw2rAZyG80zE,1325
110
+ jambonz_sdk/websocket/__init__.py,sha256=13Xlg8FUF8BuVEqp7TtfNS9mfJR7ooQWtST-1g7ypNo,425
111
+ jambonz_sdk/websocket/audio_client.py,sha256=fjJH7XK0jCX8WR0mnn00oQPs9uqvp9jYq1azAyva3pQ,369
112
+ jambonz_sdk/websocket/audio_stream.py,sha256=JmkxP2oEpq0sA0jsuCp2I7g2Ai4PouC0H27mucnRXi4,5471
113
+ jambonz_sdk/websocket/client.py,sha256=HMlcZoOVzYH0pQY54pPgv7J063nKT-95ZJ2Y3u3hvsA,6324
114
+ jambonz_sdk/websocket/endpoint.py,sha256=yDwfIdVP-JKovUdHOzA_mFO_hsd3jh-sNtDaOnQqMIA,6394
115
+ jambonz_sdk/websocket/router.py,sha256=n04A-rJ3rQrLm3bcKLBB67Niu6PRPa-zDomyY4Uboj4,2879
116
+ jambonz_sdk/websocket/session.py,sha256=0Ooztm_Pqs2uYTbDZvswrRKi1ZFixaoDAVd7ML5pMg8,9248
117
+ jambonz_python_sdk-0.2.0.dist-info/METADATA,sha256=lUR1pYfQ0cMrYUJSglGRQyDYYRDdNHy7zNqF3YvfNc4,6367
118
+ jambonz_python_sdk-0.2.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
119
+ jambonz_python_sdk-0.2.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,52 @@
1
+ """jambonz Python SDK.
2
+
3
+ A Python SDK for the jambonz CPaaS platform, providing:
4
+
5
+ - **Webhook**: HTTP transport for building jambonz voice apps
6
+ - **WebSocket**: Persistent connection transport for real-time voice AI
7
+ - **Client**: REST API client for call control and management
8
+
9
+ Quick start (webhook)::
10
+
11
+ from jambonz_sdk.webhook import WebhookResponse
12
+
13
+ jambonz = WebhookResponse()
14
+ jambonz.say(text="Hello!").hangup()
15
+ response_body = jambonz.to_json()
16
+
17
+ Quick start (websocket)::
18
+
19
+ from jambonz_sdk.websocket import create_endpoint
20
+
21
+ make_service, server = await create_endpoint(port=3000)
22
+ svc = make_service(path="/")
23
+
24
+ def handle_session(session):
25
+ session.say(text="Hello!").hangup()
26
+ await session.send()
27
+
28
+ svc.on("session:new", handle_session)
29
+
30
+ Quick start (REST client)::
31
+
32
+ from jambonz_sdk.client import JambonzClient
33
+
34
+ async with JambonzClient(base_url=url, account_sid=sid, api_key=key) as client:
35
+ call_sid = await client.calls.create({...})
36
+ """
37
+
38
+ __version__ = "0.1.0"
39
+
40
+ # Re-export main classes for convenience
41
+ from jambonz_sdk.client import JambonzClient
42
+ from jambonz_sdk.validator import JambonzValidator
43
+ from jambonz_sdk.verb_builder import VerbBuilder
44
+ from jambonz_sdk.webhook import WebhookResponse
45
+
46
+ __all__ = [
47
+ "JambonzClient",
48
+ "JambonzValidator",
49
+ "VerbBuilder",
50
+ "WebhookResponse",
51
+ "__version__",
52
+ ]
@@ -0,0 +1,73 @@
1
+ """HMAC-SHA256 webhook signature verification.
2
+
3
+ jambonz signs webhook requests with the header:
4
+ Jambonz-Signature: t=<timestamp>,v1=<signature>
5
+
6
+ The signature is computed as:
7
+ HMAC-SHA256(secret, timestamp + "." + raw_body)
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ import hashlib
13
+ import hmac
14
+ import time
15
+
16
+ DEFAULT_TOLERANCE = 300 # 5 minutes
17
+
18
+
19
+ def verify_signature(
20
+ payload: bytes,
21
+ signature_header: str,
22
+ secret: str,
23
+ tolerance: int = DEFAULT_TOLERANCE,
24
+ ) -> bool:
25
+ """Verify a jambonz webhook signature.
26
+
27
+ Args:
28
+ payload: Raw request body bytes.
29
+ signature_header: Value of the ``Jambonz-Signature`` header.
30
+ secret: The webhook signing secret.
31
+ tolerance: Maximum age in seconds for the timestamp (default 300).
32
+
33
+ Returns:
34
+ True if the signature is valid.
35
+
36
+ Raises:
37
+ ValueError: If the signature header is malformed, the signature
38
+ doesn't match, or the timestamp is outside the tolerance window.
39
+ """
40
+ parts: dict[str, str] = {}
41
+ for item in signature_header.split(","):
42
+ key, _, value = item.strip().partition("=")
43
+ parts[key] = value
44
+
45
+ timestamp_str = parts.get("t")
46
+ sig = parts.get("v1")
47
+
48
+ if not timestamp_str or not sig:
49
+ raise ValueError("Invalid Jambonz-Signature header format")
50
+
51
+ try:
52
+ timestamp = int(timestamp_str)
53
+ except (ValueError, TypeError) as exc:
54
+ raise ValueError("Invalid timestamp in Jambonz-Signature header") from exc
55
+
56
+ if tolerance > 0:
57
+ age = int(time.time()) - timestamp
58
+ if age > tolerance:
59
+ raise ValueError(
60
+ f"Signature timestamp too old: {age}s > {tolerance}s tolerance"
61
+ )
62
+
63
+ signed_payload = f"{timestamp}.".encode() + payload
64
+ expected = hmac.new(
65
+ secret.encode(),
66
+ signed_payload,
67
+ hashlib.sha256,
68
+ ).hexdigest()
69
+
70
+ if not hmac.compare_digest(expected, sig):
71
+ raise ValueError("Signature verification failed")
72
+
73
+ return True
@@ -0,0 +1,15 @@
1
+ """REST API client for jambonz platform."""
2
+
3
+ from jambonz_sdk.client.api import (
4
+ CallsResource,
5
+ ConferencesResource,
6
+ JambonzClient,
7
+ QueuesResource,
8
+ )
9
+
10
+ __all__ = [
11
+ "CallsResource",
12
+ "ConferencesResource",
13
+ "JambonzClient",
14
+ "QueuesResource",
15
+ ]