typecast-python 0.3.11__py3-none-any.whl → 0.3.13__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.
- typecast/_user_agent.py +53 -3
- typecast/async_client.py +22 -4
- typecast/client.py +15 -4
- {typecast_python-0.3.11.dist-info → typecast_python-0.3.13.dist-info}/METADATA +5 -5
- {typecast_python-0.3.11.dist-info → typecast_python-0.3.13.dist-info}/RECORD +7 -7
- {typecast_python-0.3.11.dist-info → typecast_python-0.3.13.dist-info}/WHEEL +1 -1
- {typecast_python-0.3.11.dist-info → typecast_python-0.3.13.dist-info}/licenses/LICENSE +0 -0
typecast/_user_agent.py
CHANGED
|
@@ -1,10 +1,35 @@
|
|
|
1
1
|
import platform
|
|
2
|
+
import re
|
|
2
3
|
import sys
|
|
3
4
|
from importlib import metadata
|
|
5
|
+
from typing import Optional
|
|
4
6
|
|
|
5
7
|
from . import conf
|
|
6
8
|
|
|
7
9
|
|
|
10
|
+
_GENERATED_BY_PATTERN = re.compile(r"[a-z0-9][a-z0-9._-]{0,31}\Z")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def attribution_suffix(
|
|
14
|
+
source: Optional[str] = None,
|
|
15
|
+
generated_by: Optional[str] = None,
|
|
16
|
+
) -> str:
|
|
17
|
+
if source is None and generated_by is None:
|
|
18
|
+
return ""
|
|
19
|
+
if (
|
|
20
|
+
not isinstance(source, str)
|
|
21
|
+
or not isinstance(generated_by, str)
|
|
22
|
+
or source not in {"llms", "skill", "api-page", "api-docs"}
|
|
23
|
+
or not generated_by
|
|
24
|
+
):
|
|
25
|
+
raise ValueError(
|
|
26
|
+
"source (llms, skill, api-page, or api-docs) and generated_by must be provided together"
|
|
27
|
+
)
|
|
28
|
+
if not _GENERATED_BY_PATTERN.fullmatch(generated_by):
|
|
29
|
+
raise ValueError("generated_by must be a lowercase token of at most 32 characters")
|
|
30
|
+
return f" typecast-integration/1 (source={source}; generated_by={generated_by})"
|
|
31
|
+
|
|
32
|
+
|
|
8
33
|
def _package_version(package_name: str) -> str:
|
|
9
34
|
try:
|
|
10
35
|
return metadata.version(package_name)
|
|
@@ -36,6 +61,8 @@ def build_user_agent(
|
|
|
36
61
|
http_library: str,
|
|
37
62
|
host: str,
|
|
38
63
|
transport: str = "rest",
|
|
64
|
+
source: Optional[str] = None,
|
|
65
|
+
generated_by: Optional[str] = None,
|
|
39
66
|
) -> str:
|
|
40
67
|
sdk_version = _package_version("typecast-python")
|
|
41
68
|
base = "default" if conf.is_default_host(host) else "custom"
|
|
@@ -46,31 +73,54 @@ def build_user_agent(
|
|
|
46
73
|
f"{http_library} "
|
|
47
74
|
f"(mode={mode}; base={base}; transport={transport}; "
|
|
48
75
|
f"os={_os_name()}; arch={_arch_name()}; sdk_env=python; platform=server)"
|
|
76
|
+
f"{attribution_suffix(source, generated_by)}"
|
|
49
77
|
)
|
|
50
78
|
|
|
51
79
|
|
|
52
|
-
def requests_user_agent(
|
|
80
|
+
def requests_user_agent(
|
|
81
|
+
host: str,
|
|
82
|
+
transport: str = "rest",
|
|
83
|
+
source: Optional[str] = None,
|
|
84
|
+
generated_by: Optional[str] = None,
|
|
85
|
+
) -> str:
|
|
53
86
|
return build_user_agent(
|
|
54
87
|
mode="sync",
|
|
55
88
|
http_library=f"requests/{_package_version('requests')}",
|
|
56
89
|
host=host,
|
|
57
90
|
transport=transport,
|
|
91
|
+
source=source,
|
|
92
|
+
generated_by=generated_by,
|
|
58
93
|
)
|
|
59
94
|
|
|
60
95
|
|
|
61
|
-
def aiohttp_user_agent(
|
|
96
|
+
def aiohttp_user_agent(
|
|
97
|
+
host: str,
|
|
98
|
+
transport: str = "rest",
|
|
99
|
+
source: Optional[str] = None,
|
|
100
|
+
generated_by: Optional[str] = None,
|
|
101
|
+
) -> str:
|
|
62
102
|
return build_user_agent(
|
|
63
103
|
mode="async",
|
|
64
104
|
http_library=f"aiohttp/{_package_version('aiohttp')}",
|
|
65
105
|
host=host,
|
|
66
106
|
transport=transport,
|
|
107
|
+
source=source,
|
|
108
|
+
generated_by=generated_by,
|
|
67
109
|
)
|
|
68
110
|
|
|
69
111
|
|
|
70
|
-
def httpx_user_agent(
|
|
112
|
+
def httpx_user_agent(
|
|
113
|
+
host: str,
|
|
114
|
+
mode: str,
|
|
115
|
+
transport: str = "rest",
|
|
116
|
+
source: Optional[str] = None,
|
|
117
|
+
generated_by: Optional[str] = None,
|
|
118
|
+
) -> str:
|
|
71
119
|
return build_user_agent(
|
|
72
120
|
mode=mode,
|
|
73
121
|
http_library=f"httpx/{_package_version('httpx')}",
|
|
74
122
|
host=host,
|
|
75
123
|
transport=transport,
|
|
124
|
+
source=source,
|
|
125
|
+
generated_by=generated_by,
|
|
76
126
|
)
|
typecast/async_client.py
CHANGED
|
@@ -17,7 +17,7 @@ from ._voice_clone import (
|
|
|
17
17
|
validate_clone_inputs,
|
|
18
18
|
validate_custom_voice_id,
|
|
19
19
|
)
|
|
20
|
-
from ._user_agent import aiohttp_user_agent, httpx_user_agent
|
|
20
|
+
from ._user_agent import aiohttp_user_agent, attribution_suffix, httpx_user_agent
|
|
21
21
|
|
|
22
22
|
if TYPE_CHECKING or sys.version_info < (3, 10): # pragma: no cover
|
|
23
23
|
from ._httpx_compat import AiohttpCompatSession, ClientTimeout, FormData
|
|
@@ -77,6 +77,8 @@ class AsyncTypecast:
|
|
|
77
77
|
host: Optional[str] = None,
|
|
78
78
|
api_key: Optional[str] = None,
|
|
79
79
|
session: Optional[Any] = None,
|
|
80
|
+
source: Optional[str] = None,
|
|
81
|
+
generated_by: Optional[str] = None,
|
|
80
82
|
):
|
|
81
83
|
"""Initialize the async Typecast client.
|
|
82
84
|
|
|
@@ -88,6 +90,8 @@ class AsyncTypecast:
|
|
|
88
90
|
__aenter__ will not create a new session and __aexit__ will not close it
|
|
89
91
|
(the caller owns its lifecycle). Auth headers (`X-API-KEY`, `User-Agent`)
|
|
90
92
|
are attached per-request via `_request_headers()`.
|
|
93
|
+
source: Integration source: 'llms', 'skill', 'api-page', or 'api-docs'.
|
|
94
|
+
generated_by: Lowercase token identifying the coding agent.
|
|
91
95
|
|
|
92
96
|
Raises:
|
|
93
97
|
ValueError: If no API key is provided and TYPECAST_API_KEY is not set
|
|
@@ -95,6 +99,9 @@ class AsyncTypecast:
|
|
|
95
99
|
"""
|
|
96
100
|
self.host = conf.get_host(host)
|
|
97
101
|
self.api_key = conf.get_api_key(api_key)
|
|
102
|
+
attribution_suffix(source, generated_by)
|
|
103
|
+
self.source = source
|
|
104
|
+
self.generated_by = generated_by
|
|
98
105
|
if not self.api_key and conf.is_default_host(self.host):
|
|
99
106
|
raise ValueError("API key is required for the default Typecast API host")
|
|
100
107
|
self._owns_session = session is None
|
|
@@ -106,9 +113,16 @@ class AsyncTypecast:
|
|
|
106
113
|
if self.session is None:
|
|
107
114
|
headers = {
|
|
108
115
|
"User-Agent": (
|
|
109
|
-
aiohttp_user_agent(
|
|
116
|
+
aiohttp_user_agent(
|
|
117
|
+
self.host, source=self.source, generated_by=self.generated_by
|
|
118
|
+
)
|
|
110
119
|
if aiohttp
|
|
111
|
-
else httpx_user_agent(
|
|
120
|
+
else httpx_user_agent(
|
|
121
|
+
self.host,
|
|
122
|
+
"async",
|
|
123
|
+
source=self.source,
|
|
124
|
+
generated_by=self.generated_by,
|
|
125
|
+
)
|
|
112
126
|
)
|
|
113
127
|
}
|
|
114
128
|
if self.api_key:
|
|
@@ -157,7 +171,11 @@ class AsyncTypecast:
|
|
|
157
171
|
"""
|
|
158
172
|
if self._owns_session:
|
|
159
173
|
return None
|
|
160
|
-
headers = {
|
|
174
|
+
headers = {
|
|
175
|
+
"User-Agent": aiohttp_user_agent(
|
|
176
|
+
self.host, source=self.source, generated_by=self.generated_by
|
|
177
|
+
)
|
|
178
|
+
}
|
|
161
179
|
if self.api_key:
|
|
162
180
|
headers["X-API-KEY"] = self.api_key
|
|
163
181
|
return headers
|
typecast/client.py
CHANGED
|
@@ -16,7 +16,7 @@ from ._voice_clone import (
|
|
|
16
16
|
validate_clone_inputs,
|
|
17
17
|
validate_custom_voice_id,
|
|
18
18
|
)
|
|
19
|
-
from ._user_agent import httpx_user_agent, requests_user_agent
|
|
19
|
+
from ._user_agent import attribution_suffix, httpx_user_agent, requests_user_agent
|
|
20
20
|
|
|
21
21
|
if TYPE_CHECKING or sys.version_info < (3, 10): # pragma: no cover
|
|
22
22
|
from ._httpx_compat import RequestsCompatSession
|
|
@@ -111,6 +111,8 @@ class Typecast:
|
|
|
111
111
|
host: Optional[str] = None,
|
|
112
112
|
api_key: Optional[str] = None,
|
|
113
113
|
session: Optional[Any] = None,
|
|
114
|
+
source: Optional[str] = None,
|
|
115
|
+
generated_by: Optional[str] = None,
|
|
114
116
|
):
|
|
115
117
|
"""Initialize the Typecast client.
|
|
116
118
|
|
|
@@ -122,12 +124,17 @@ class Typecast:
|
|
|
122
124
|
the client will not create a new session nor close it; auth headers
|
|
123
125
|
(`X-API-KEY`, `User-Agent`) are attached per-request via
|
|
124
126
|
`_request_headers()`.
|
|
127
|
+
source: Integration source: 'llms', 'skill', 'api-page', or 'api-docs'.
|
|
128
|
+
generated_by: Lowercase token identifying the coding agent.
|
|
125
129
|
|
|
126
130
|
Raises:
|
|
127
131
|
ValueError: If no API key is provided and TYPECAST_API_KEY is not set.
|
|
128
132
|
"""
|
|
129
133
|
self.host = conf.get_host(host)
|
|
130
134
|
self.api_key = conf.get_api_key(api_key)
|
|
135
|
+
attribution_suffix(source, generated_by)
|
|
136
|
+
self.source = source
|
|
137
|
+
self.generated_by = generated_by
|
|
131
138
|
if not self.api_key and conf.is_default_host(self.host):
|
|
132
139
|
raise ValueError("API key is required for the default Typecast API host")
|
|
133
140
|
self._owns_session = session is None
|
|
@@ -139,9 +146,9 @@ class Typecast:
|
|
|
139
146
|
headers = {
|
|
140
147
|
"Content-Type": "application/json",
|
|
141
148
|
"User-Agent": (
|
|
142
|
-
requests_user_agent(self.host)
|
|
149
|
+
requests_user_agent(self.host, source=source, generated_by=generated_by)
|
|
143
150
|
if requests
|
|
144
|
-
else httpx_user_agent(self.host, "sync")
|
|
151
|
+
else httpx_user_agent(self.host, "sync", source=source, generated_by=generated_by)
|
|
145
152
|
),
|
|
146
153
|
}
|
|
147
154
|
if self.api_key:
|
|
@@ -179,7 +186,11 @@ class Typecast:
|
|
|
179
186
|
"""
|
|
180
187
|
if self._owns_session:
|
|
181
188
|
return None
|
|
182
|
-
headers = {
|
|
189
|
+
headers = {
|
|
190
|
+
"User-Agent": requests_user_agent(
|
|
191
|
+
self.host, source=self.source, generated_by=self.generated_by
|
|
192
|
+
)
|
|
193
|
+
}
|
|
183
194
|
if self.api_key:
|
|
184
195
|
headers["X-API-KEY"] = self.api_key
|
|
185
196
|
return headers
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: typecast-python
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.13
|
|
4
4
|
Summary: Official Typecast Python SDK - Convert text to lifelike speech using AI-powered voices
|
|
5
5
|
Project-URL: Homepage, https://typecast.ai
|
|
6
6
|
Project-URL: Documentation, https://typecast.ai/docs/overview
|
|
@@ -235,12 +235,12 @@ Requires-Dist: typing-extensions>=4.0.0
|
|
|
235
235
|
Provides-Extra: dev
|
|
236
236
|
Requires-Dist: aioresponses>=0.7.6; extra == 'dev'
|
|
237
237
|
Requires-Dist: black<27.0.0,>=26.3.1; extra == 'dev'
|
|
238
|
-
Requires-Dist: flake8<
|
|
238
|
+
Requires-Dist: flake8<8.0.0,>=5.0.0; extra == 'dev'
|
|
239
239
|
Requires-Dist: httpx<1.0.0,>=0.28.1; extra == 'dev'
|
|
240
240
|
Requires-Dist: isort>=5.0.0; extra == 'dev'
|
|
241
|
-
Requires-Dist: mypy<
|
|
241
|
+
Requires-Dist: mypy<2.4.0,>=1.0.0; extra == 'dev'
|
|
242
242
|
Requires-Dist: pytest-asyncio<2.0.0,>=1.4.0; extra == 'dev'
|
|
243
|
-
Requires-Dist: pytest-cov<
|
|
243
|
+
Requires-Dist: pytest-cov<8.0.0,>=5.0.0; extra == 'dev'
|
|
244
244
|
Requires-Dist: pytest-mock>=3.14.0; extra == 'dev'
|
|
245
245
|
Requires-Dist: pytest<10.0.0,>=9.0.3; extra == 'dev'
|
|
246
246
|
Description-Content-Type: text/markdown
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
typecast/__init__.py,sha256=L6m0Z1jn1UgGjPp9AFiTwhHk9DVV_B4WrLfQDEfbcZI,1093
|
|
2
2
|
typecast/_httpx_compat.py,sha256=Xw4AvybiiXyaA2WATBUYHwST8clE8R7R0flLMpdvBC4,6170
|
|
3
|
-
typecast/_user_agent.py,sha256=
|
|
3
|
+
typecast/_user_agent.py,sha256=dCiHkvCuTQOz5qYxk4vmxEzL7qZUo9ceKmjXsQUM5wI,3417
|
|
4
4
|
typecast/_voice_clone.py,sha256=TN2tbB3b5lC5uFCBnbERhz37bNJlbv6VZ-vj70EfTs4,3464
|
|
5
|
-
typecast/async_client.py,sha256=
|
|
6
|
-
typecast/client.py,sha256=
|
|
5
|
+
typecast/async_client.py,sha256=igeZye1Npjf1bFeiTuKMFEN2BxgWmR8DLToP7m3gNxw,23418
|
|
6
|
+
typecast/client.py,sha256=08YEMhSbTqcVlW54ZC6fyJiGxR3CnODrMT4eaFsqjaw,22774
|
|
7
7
|
typecast/composer.py,sha256=pkRSVIv99uuAwPyOXw7KSW7NAkqvAUK4hCS5pmBb7bA,7313
|
|
8
8
|
typecast/conf.py,sha256=yfOHYZDvIshWWMriN5wE0GFPR8AX3zv4Rg2655OvA9Q,724
|
|
9
9
|
typecast/exceptions.py,sha256=Y0ZzYebe8zOSOSAHbXfKR0G_RJgdmZXxi15Z7ZxPLIk,1568
|
|
@@ -13,7 +13,7 @@ typecast/models/error.py,sha256=XomIjx7jvlCjItqzJuCAT4mXC9jwTjxR8lLDUk6P8KA,152
|
|
|
13
13
|
typecast/models/subscription.py,sha256=EIaAAo3cCRw8LYT_O6D9AVwxqIHrWCijzl4UTx7FZB8,894
|
|
14
14
|
typecast/models/tts.py,sha256=xiO1e936vFr7vZqUErTEhexydoaMem6BcY_x1A1zFow,16495
|
|
15
15
|
typecast/models/voices.py,sha256=3UeBLwAlaNbQQUrt7FO18zqczLoP7jmi2x68yaUtllU,2687
|
|
16
|
-
typecast_python-0.3.
|
|
17
|
-
typecast_python-0.3.
|
|
18
|
-
typecast_python-0.3.
|
|
19
|
-
typecast_python-0.3.
|
|
16
|
+
typecast_python-0.3.13.dist-info/METADATA,sha256=LmoUpiY-EyHT3sHfSK2bt2qFPlL-IBq_JL_wtbHM8-Y,25947
|
|
17
|
+
typecast_python-0.3.13.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
18
|
+
typecast_python-0.3.13.dist-info/licenses/LICENSE,sha256=HvtJ-S89uUkuYmt-OvVk4MRxmzwtbn84__qJtSrGU2Q,11348
|
|
19
|
+
typecast_python-0.3.13.dist-info/RECORD,,
|
|
File without changes
|