Skip to content

Commit 6779b2c

Browse files
feat: add aiohttp transport support via optional extra
The SDK now supports aiohttp as an alternative async HTTP transport backend. When the `aiohttp` optional extra is installed (`pip install vapi_server_sdk[aiohttp]`), the `AsyncVapi` client will automatically use `httpx-aiohttp` as its underlying transport. Users who prefer the standard httpx client are unaffected — behaviour is unchanged unless the extra is explicitly installed. Key changes: - Add new `aiohttp` optional extra (`aiohttp>=3.10,<4` + `httpx-aiohttp==0.1.8`) - Introduce `DefaultAioHttpClient` and `DefaultAsyncHttpxClient` convenience classes (exported from top-level `vapi` package) - Add `_make_default_async_client()` helper that auto-detects and prefers `httpx-aiohttp` when available - Add pytest marker and conftest fixture to skip aiohttp tests when the extra is not installed 🌿 Generated with Fern
1 parent 7a070a7 commit 6779b2c

File tree

12 files changed

+1026
-45
lines changed

12 files changed

+1026
-45
lines changed

.fern/metadata.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
{
2-
"cliVersion": "4.62.4",
2+
"cliVersion": "4.65.1",
33
"generatorName": "fernapi/fern-python-sdk",
4-
"generatorVersion": "5.2.0",
4+
"generatorVersion": "5.3.3",
55
"generatorConfig": {
66
"pydantic_config": {
77
"skip_validation": true
88
},
99
"client_class_name": "Vapi"
1010
},
11-
"originGitCommit": "609e140e6338ba929ae7f23a23046ea7dc777b07",
12-
"sdkVersion": "1.9.1"
11+
"originGitCommit": "46b109d88752307f8952db91eaa642f61c3875b4",
12+
"sdkVersion": "1.10.0"
1313
}

.github/workflows/ci.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ jobs:
4040
- name: Test
4141
run: poetry run pytest -rP -n auto .
4242

43+
- name: Install aiohttp extra
44+
run: poetry install --extras aiohttp
45+
46+
- name: Test (aiohttp)
47+
run: poetry run pytest -rP -n auto -m aiohttp .
48+
4349
publish:
4450
needs: [compile, test]
4551
if: github.event_name == 'push' && contains(github.ref, 'refs/tags/')

changelog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## 1.10.0 - 2026-04-10
2+
* The SDK now supports `aiohttp` as an optional async HTTP transport backend. Install the new extra (`pip install vapi_server_sdk[aiohttp]`) to have `AsyncVapi` automatically use `httpx-aiohttp` under the hood. Two new convenience classes, `DefaultAioHttpClient` and `DefaultAsyncHttpxClient`, are also now available for users who want to configure the async HTTP client explicitly.
3+
14
## 1.9.1 - 2026-04-07
25
* SDK regeneration
36
* Unable to analyze changes with AI, incrementing PATCH version.

poetry.lock

Lines changed: 782 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ dynamic = ["version"]
44

55
[tool.poetry]
66
name = "vapi_server_sdk"
7-
version = "1.9.1"
7+
version = "1.10.0"
88
description = ""
99
readme = "README.md"
1010
authors = []
@@ -37,7 +37,9 @@ Repository = 'https://github.com/VapiAI/server-sdk-python'
3737

3838
[tool.poetry.dependencies]
3939
python = "^3.10"
40+
aiohttp = { version = ">=3.10.0,<4", optional = true}
4041
httpx = ">=0.21.2"
42+
httpx-aiohttp = { version = "0.1.8", optional = true}
4143
pydantic = ">= 1.9.2"
4244
pydantic-core = ">=2.18.2,<2.44.0"
4345
typing_extensions = ">= 4.0.0"
@@ -54,6 +56,9 @@ ruff = "==0.11.5"
5456
[tool.pytest.ini_options]
5557
testpaths = [ "tests" ]
5658
asyncio_mode = "auto"
59+
markers = [
60+
"aiohttp: tests that require httpx_aiohttp to be installed",
61+
]
5762

5863
[tool.mypy]
5964
plugins = ["pydantic.mypy"]
@@ -85,3 +90,6 @@ section-order = ["future", "standard-library", "third-party", "first-party"]
8590
[build-system]
8691
requires = ["poetry-core"]
8792
build-backend = "poetry.core.masonry.api"
93+
94+
[tool.poetry.extras]
95+
aiohttp=["aiohttp", "httpx-aiohttp"]

reference.md

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3646,17 +3646,17 @@ client.phone_numbers.list()
36463646
```python
36473647
from vapi import Vapi
36483648
from vapi.environment import VapiEnvironment
3649+
from vapi.phone_numbers import CreatePhoneNumbersRequest_ByoPhoneNumber
36493650

36503651
client = Vapi(
36513652
token="<token>",
36523653
environment=VapiEnvironment.DEFAULT,
36533654
)
36543655

36553656
client.phone_numbers.create(
3656-
request={
3657-
"provider": "byo-phone-number",
3658-
"credential_id": "credentialId"
3659-
},
3657+
request=CreatePhoneNumbersRequest_ByoPhoneNumber(
3658+
credential_id="credentialId",
3659+
),
36603660
)
36613661

36623662
```
@@ -3971,6 +3971,7 @@ client.phone_numbers.delete(
39713971
```python
39723972
from vapi import Vapi
39733973
from vapi.environment import VapiEnvironment
3974+
from vapi.phone_numbers import UpdatePhoneNumbersRequestBody_ByoPhoneNumber
39743975

39753976
client = Vapi(
39763977
token="<token>",
@@ -3979,9 +3980,7 @@ client = Vapi(
39793980

39803981
client.phone_numbers.update(
39813982
id="id",
3982-
request={
3983-
"provider": "byo-phone-number"
3984-
},
3983+
request=UpdatePhoneNumbersRequestBody_ByoPhoneNumber(),
39853984
)
39863985

39873986
```
@@ -4163,18 +4162,18 @@ client.tools.list()
41634162
```python
41644163
from vapi import Vapi
41654164
from vapi.environment import VapiEnvironment
4165+
from vapi.tools import CreateToolsRequest_ApiRequest
41664166

41674167
client = Vapi(
41684168
token="<token>",
41694169
environment=VapiEnvironment.DEFAULT,
41704170
)
41714171

41724172
client.tools.create(
4173-
request={
4174-
"type": "apiRequest",
4175-
"method": "POST",
4176-
"url": "url"
4177-
},
4173+
request=CreateToolsRequest_ApiRequest(
4174+
method="POST",
4175+
url="url",
4176+
),
41784177
)
41794178

41804179
```
@@ -4344,6 +4343,7 @@ client.tools.delete(
43444343
```python
43454344
from vapi import Vapi
43464345
from vapi.environment import VapiEnvironment
4346+
from vapi.tools import UpdateToolsRequestBody_ApiRequest
43474347

43484348
client = Vapi(
43494349
token="<token>",
@@ -4352,9 +4352,7 @@ client = Vapi(
43524352

43534353
client.tools.update(
43544354
id="id",
4355-
request={
4356-
"type": "apiRequest"
4357-
},
4355+
request=UpdateToolsRequestBody_ApiRequest(),
43584356
)
43594357

43604358
```
@@ -5477,24 +5475,24 @@ client.insight.insight_controller_find_all()
54775475
```python
54785476
from vapi import Vapi, JsonQueryOnCallTableWithStringTypeColumn
54795477
from vapi.environment import VapiEnvironment
5478+
from vapi.insight import InsightControllerCreateRequest_Bar
54805479

54815480
client = Vapi(
54825481
token="<token>",
54835482
environment=VapiEnvironment.DEFAULT,
54845483
)
54855484

54865485
client.insight.insight_controller_create(
5487-
request={
5488-
"type": "bar",
5489-
"queries": [
5486+
request=InsightControllerCreateRequest_Bar(
5487+
queries=[
54905488
JsonQueryOnCallTableWithStringTypeColumn(
54915489
type="vapiql-json",
54925490
table="call",
54935491
column="id",
54945492
operation="count",
54955493
)
5496-
]
5497-
},
5494+
],
5495+
),
54985496
)
54995497

55005498
```
@@ -5664,6 +5662,7 @@ client.insight.insight_controller_remove(
56645662
```python
56655663
from vapi import Vapi
56665664
from vapi.environment import VapiEnvironment
5665+
from vapi.insight import InsightControllerUpdateRequestBody_Bar
56675666

56685667
client = Vapi(
56695668
token="<token>",
@@ -5672,9 +5671,7 @@ client = Vapi(
56725671

56735672
client.insight.insight_controller_update(
56745673
id="id",
5675-
request={
5676-
"type": "bar"
5677-
},
5674+
request=InsightControllerUpdateRequestBody_Bar(),
56785675
)
56795676

56805677
```
@@ -5817,24 +5814,24 @@ For Pie and Text Insights, step will be ignored even if provided.
58175814
```python
58185815
from vapi import Vapi, JsonQueryOnCallTableWithStringTypeColumn
58195816
from vapi.environment import VapiEnvironment
5817+
from vapi.insight import InsightControllerPreviewRequest_Bar
58205818

58215819
client = Vapi(
58225820
token="<token>",
58235821
environment=VapiEnvironment.DEFAULT,
58245822
)
58255823

58265824
client.insight.insight_controller_preview(
5827-
request={
5828-
"type": "bar",
5829-
"queries": [
5825+
request=InsightControllerPreviewRequest_Bar(
5826+
queries=[
58305827
JsonQueryOnCallTableWithStringTypeColumn(
58315828
type="vapiql-json",
58325829
table="call",
58335830
column="id",
58345831
operation="count",
58355832
)
5836-
]
5837-
},
5833+
],
5834+
),
58385835
)
58395836

58405837
```
@@ -6583,16 +6580,15 @@ client.eval.eval_controller_get_runs_paginated()
65836580
```python
65846581
from vapi import Vapi
65856582
from vapi.environment import VapiEnvironment
6583+
from vapi.eval import CreateEvalRunDtoTarget_Assistant
65866584

65876585
client = Vapi(
65886586
token="<token>",
65896587
environment=VapiEnvironment.DEFAULT,
65906588
)
65916589

65926590
client.eval.eval_controller_run(
6593-
target={
6594-
"type": "assistant"
6595-
},
6591+
target=CreateEvalRunDtoTarget_Assistant(),
65966592
type="eval",
65976593
)
65986594

src/vapi/__init__.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4212,6 +4212,7 @@
42124212
structured_outputs,
42134213
tools,
42144214
)
4215+
from ._default_clients import DefaultAioHttpClient, DefaultAsyncHttpxClient
42154216
from .assistants import (
42164217
UpdateAssistantDtoBackgroundSound,
42174218
UpdateAssistantDtoBackgroundSoundZero,
@@ -6349,6 +6350,8 @@
63496350
"DeepgramVoice": ".types",
63506351
"DeepgramVoiceId": ".types",
63516352
"DeepgramVoiceModel": ".types",
6353+
"DefaultAioHttpClient": "._default_clients",
6354+
"DefaultAsyncHttpxClient": "._default_clients",
63526355
"DeletePhoneNumbersResponse": ".phone_numbers",
63536356
"DeletePhoneNumbersResponse_ByoPhoneNumber": ".phone_numbers",
63546357
"DeletePhoneNumbersResponse_Telnyx": ".phone_numbers",
@@ -10984,6 +10987,8 @@ def __dir__():
1098410987
"DeepgramVoice",
1098510988
"DeepgramVoiceId",
1098610989
"DeepgramVoiceModel",
10990+
"DefaultAioHttpClient",
10991+
"DefaultAsyncHttpxClient",
1098710992
"DeletePhoneNumbersResponse",
1098810993
"DeletePhoneNumbersResponse_ByoPhoneNumber",
1098910994
"DeletePhoneNumbersResponse_Telnyx",

src/vapi/_default_clients.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# This file was auto-generated by Fern from our API Definition.
2+
3+
import typing
4+
5+
import httpx
6+
7+
SDK_DEFAULT_TIMEOUT = 60
8+
9+
try:
10+
import httpx_aiohttp # type: ignore[import-not-found]
11+
except ImportError:
12+
13+
class DefaultAioHttpClient(httpx.AsyncClient): # type: ignore
14+
def __init__(self, **kwargs: typing.Any) -> None:
15+
raise RuntimeError(
16+
"To use the aiohttp client, install the aiohttp extra: pip install vapi_server_sdk[aiohttp]"
17+
)
18+
19+
else:
20+
21+
class DefaultAioHttpClient(httpx_aiohttp.HttpxAiohttpClient): # type: ignore
22+
def __init__(self, **kwargs: typing.Any) -> None:
23+
kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT)
24+
kwargs.setdefault("follow_redirects", True)
25+
super().__init__(**kwargs)
26+
27+
28+
class DefaultAsyncHttpxClient(httpx.AsyncClient):
29+
def __init__(self, **kwargs: typing.Any) -> None:
30+
kwargs.setdefault("timeout", SDK_DEFAULT_TIMEOUT)
31+
kwargs.setdefault("follow_redirects", True)
32+
super().__init__(**kwargs)

src/vapi/client.py

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,24 @@ def analytics(self):
234234
return self._analytics
235235

236236

237+
def _make_default_async_client(
238+
timeout: typing.Optional[float],
239+
follow_redirects: typing.Optional[bool],
240+
) -> httpx.AsyncClient:
241+
try:
242+
import httpx_aiohttp # type: ignore[import-not-found]
243+
except ImportError:
244+
pass
245+
else:
246+
if follow_redirects is not None:
247+
return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout, follow_redirects=follow_redirects)
248+
return httpx_aiohttp.HttpxAiohttpClient(timeout=timeout)
249+
250+
if follow_redirects is not None:
251+
return httpx.AsyncClient(timeout=timeout, follow_redirects=follow_redirects)
252+
return httpx.AsyncClient(timeout=timeout)
253+
254+
237255
class AsyncVapi:
238256
"""
239257
Use this class to access the different functions within the SDK. You can instantiate any number of clients with different configuration that will propagate to these functions.
@@ -303,9 +321,7 @@ def __init__(
303321
async_token=async_token,
304322
httpx_client=httpx_client
305323
if httpx_client is not None
306-
else httpx.AsyncClient(timeout=_defaulted_timeout, follow_redirects=follow_redirects)
307-
if follow_redirects is not None
308-
else httpx.AsyncClient(timeout=_defaulted_timeout),
324+
else _make_default_async_client(timeout=_defaulted_timeout, follow_redirects=follow_redirects),
309325
timeout=_defaulted_timeout,
310326
logging=logging,
311327
)

src/vapi/core/client_wrapper.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ def get_headers(self) -> typing.Dict[str, str]:
2727
import platform
2828

2929
headers: typing.Dict[str, str] = {
30-
"User-Agent": "vapi_server_sdk/1.9.1",
30+
"User-Agent": "vapi_server_sdk/1.10.0",
3131
"X-Fern-Language": "Python",
3232
"X-Fern-Runtime": f"python/{platform.python_version()}",
3333
"X-Fern-Platform": f"{platform.system().lower()}/{platform.release()}",
3434
"X-Fern-SDK-Name": "vapi_server_sdk",
35-
"X-Fern-SDK-Version": "1.9.1",
35+
"X-Fern-SDK-Version": "1.10.0",
3636
**(self.get_custom_headers() or {}),
3737
}
3838
headers["Authorization"] = f"Bearer {self._get_token()}"

0 commit comments

Comments
 (0)