zarx 0.2.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.
- zarx-0.2.0/.gitignore +33 -0
- zarx-0.2.0/LICENSE +202 -0
- zarx-0.2.0/NOTICE +4 -0
- zarx-0.2.0/PKG-INFO +246 -0
- zarx-0.2.0/README.md +221 -0
- zarx-0.2.0/pyproject.toml +42 -0
- zarx-0.2.0/src/zarx/__init__.py +64 -0
- zarx-0.2.0/src/zarx/__main__.py +3 -0
- zarx-0.2.0/src/zarx/_client.py +66 -0
- zarx-0.2.0/src/zarx/_config.py +67 -0
- zarx-0.2.0/src/zarx/_forecast_result.py +100 -0
- zarx-0.2.0/src/zarx/_realtime.py +149 -0
- zarx-0.2.0/src/zarx/_responses.py +36 -0
- zarx-0.2.0/src/zarx/_series.py +121 -0
- zarx-0.2.0/src/zarx/_speech_stream.py +53 -0
- zarx-0.2.0/src/zarx/_version.py +1 -0
- zarx-0.2.0/src/zarx/audio.py +246 -0
- zarx-0.2.0/src/zarx/cli/__init__.py +1 -0
- zarx-0.2.0/src/zarx/cli/audio_cmd.py +53 -0
- zarx-0.2.0/src/zarx/cli/chat_cmd.py +60 -0
- zarx-0.2.0/src/zarx/cli/console.py +18 -0
- zarx-0.2.0/src/zarx/cli/forecast_cmd.py +64 -0
- zarx-0.2.0/src/zarx/cli/main.py +71 -0
- zarx-0.2.0/src/zarx/cli/models_cmd.py +24 -0
- zarx-0.2.0/src/zarx/errors.py +36 -0
- zarx-0.2.0/src/zarx/forecasting.py +135 -0
- zarx-0.2.0/src/zarx/models.py +52 -0
- zarx-0.2.0/src/zarx/py.typed +0 -0
- zarx-0.2.0/src/zarx/reasoning.py +14 -0
- zarx-0.2.0/src/zarx/voices.py +58 -0
- zarx-0.2.0/tests/__init__.py +0 -0
- zarx-0.2.0/tests/conftest.py +100 -0
- zarx-0.2.0/tests/test_audio.py +183 -0
- zarx-0.2.0/tests/test_cli.py +161 -0
- zarx-0.2.0/tests/test_config.py +124 -0
- zarx-0.2.0/tests/test_forecast.py +184 -0
- zarx-0.2.0/tests/test_live.py +251 -0
- zarx-0.2.0/tests/test_models.py +29 -0
- zarx-0.2.0/tests/test_realtime.py +104 -0
- zarx-0.2.0/tests/test_requests.py +68 -0
- zarx-0.2.0/tests/test_voices.py +54 -0
zarx-0.2.0/.gitignore
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
.venv/
|
|
5
|
+
*.egg-info/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.mypy_cache/
|
|
11
|
+
|
|
12
|
+
# Node
|
|
13
|
+
node_modules/
|
|
14
|
+
*.tgz
|
|
15
|
+
typescript/dist/
|
|
16
|
+
.npm/
|
|
17
|
+
|
|
18
|
+
# Local secrets and env files: never committed
|
|
19
|
+
.env
|
|
20
|
+
.env.*
|
|
21
|
+
*.env
|
|
22
|
+
stage.env
|
|
23
|
+
|
|
24
|
+
# Editors and OS
|
|
25
|
+
.DS_Store
|
|
26
|
+
.idea/
|
|
27
|
+
.vscode/
|
|
28
|
+
|
|
29
|
+
# Audio produced by examples
|
|
30
|
+
*.mp3
|
|
31
|
+
*.wav
|
|
32
|
+
*.pcm
|
|
33
|
+
!examples/assets/*.wav
|
zarx-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
zarx-0.2.0/NOTICE
ADDED
zarx-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: zarx
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Python SDK for Zarx, the OpenAI-compatible inference API run by NPAW in Europe.
|
|
5
|
+
Project-URL: Homepage, https://zarx.ai
|
|
6
|
+
Author-email: NPAW <contact@zarx.ai>
|
|
7
|
+
License: Apache-2.0
|
|
8
|
+
License-File: LICENSE
|
|
9
|
+
License-File: NOTICE
|
|
10
|
+
Keywords: europe,inference,llm,openai,zarx
|
|
11
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
15
|
+
Classifier: Typing :: Typed
|
|
16
|
+
Requires-Python: >=3.9
|
|
17
|
+
Requires-Dist: openai<4,>=1.99
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: build>=1.2; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
21
|
+
Requires-Dist: websockets>=12; extra == 'dev'
|
|
22
|
+
Provides-Extra: realtime
|
|
23
|
+
Requires-Dist: websockets>=12; extra == 'realtime'
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
|
|
26
|
+
# zarx (Python)
|
|
27
|
+
|
|
28
|
+
Python SDK and command line for [Zarx](https://zarx.ai), the OpenAI-compatible inference API that NPAW runs on its own GPUs in Spain (EU).
|
|
29
|
+
|
|
30
|
+
`zarx` is a thin layer over the official `openai` package: `zarx.Zarx` *is* an `openai.OpenAI` client, so everything you know from the OpenAI SDK works as is. What the layer adds:
|
|
31
|
+
|
|
32
|
+
- the right endpoint and key: production by default, beta with `environment="beta"` or `ZARX_ENVIRONMENT=beta`, and `ZARX_API_KEY` only (an `OPENAI_API_KEY` is never sent to Zarx, an `OPENAI_BASE_URL` never redirects it);
|
|
33
|
+
- Responses API calls default to `store=False`, so responses are not stored for later retrieval unless you ask for it (what else is retained depends on your key's retention policy, see `docs/data.md`);
|
|
34
|
+
- generous read timeouts for the reasoning tiers (300 s read, 10 s connect) and 2 retries;
|
|
35
|
+
- model name helpers (tiers and dated ids), a helper to read the reasoning text, and a `zarx` command;
|
|
36
|
+
- one call per capability beyond chat: `zarx.audio.transcribe`, `transcribe_realtime`, `speak`, `translate`, and `zarx.forecast` / `forecast_csv` for time series.
|
|
37
|
+
|
|
38
|
+
Requires Python 3.9 or newer (0.1.0 verified on 3.9 to 3.13 on 2026-10-31; 0.2.0 run on 3.13 on 2026-11-01).
|
|
39
|
+
|
|
40
|
+
## Install
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
pip install zarx
|
|
44
|
+
pip install "zarx[realtime]" # adds websockets, for transcribe_realtime
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
or from a checkout of this repository: `pip install ./python` (`pip install './python[realtime]'` for realtime transcription).
|
|
48
|
+
|
|
49
|
+
## Quickstart
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
export ZARX_API_KEY=... # your Zarx key
|
|
53
|
+
# export ZARX_ENVIRONMENT=beta # only for beta, with a beta key
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
```python
|
|
57
|
+
from zarx import Zarx, Z_FAST
|
|
58
|
+
|
|
59
|
+
client = Zarx()
|
|
60
|
+
completion = client.chat.completions.create(
|
|
61
|
+
model=Z_FAST,
|
|
62
|
+
messages=[{"role": "user", "content": "Say hello in one sentence."}],
|
|
63
|
+
max_tokens=64,
|
|
64
|
+
)
|
|
65
|
+
print(completion.choices[0].message.content)
|
|
66
|
+
print(completion.model) # the dated id that answered, e.g. z-fast-2026-10
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Async: `from zarx import AsyncZarx`, same arguments.
|
|
70
|
+
|
|
71
|
+
### Plain OpenAI SDK
|
|
72
|
+
|
|
73
|
+
You do not need this package to use Zarx. The official SDK works with two settings:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
import os
|
|
77
|
+
from openai import OpenAI
|
|
78
|
+
|
|
79
|
+
client = OpenAI(api_key=os.environ["ZARX_API_KEY"], base_url="https://api.zarx.ai/v1")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
If you go this way, pass `store=False` yourself on every Responses API call.
|
|
83
|
+
|
|
84
|
+
## Models
|
|
85
|
+
|
|
86
|
+
| Tier | Use it for | Context |
|
|
87
|
+
|---|---|---|
|
|
88
|
+
| `z-ultra` | hardest reasoning, long documents | 600,000 tokens |
|
|
89
|
+
| `z-pro` | strong general model with reasoning, very long documents | 1,048,576 tokens (1M) |
|
|
90
|
+
| `z-fast` | low latency, high volume | 16,384 tokens |
|
|
91
|
+
|
|
92
|
+
`client.models.list()` is the authority on these values; production and beta both list 1,048,576 tokens for `z-pro` (checked 2026-11-01). `z-ultra` and `z-pro` also read images; `z-fast` is text only. See `docs/models.md`.
|
|
93
|
+
|
|
94
|
+
A tier always points at its current release. To pin one release, use its dated id:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
from zarx import pin, tier_of, Z_FAST
|
|
98
|
+
|
|
99
|
+
pin(Z_FAST, "2026-10") # "z-fast-2026-10"
|
|
100
|
+
tier_of("z-fast-2026-10") # "z-fast"
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Reasoning tokens count toward `max_tokens`: give `z-pro` at least 128 (`zarx.models.Z_PRO_MIN_MAX_TOKENS`), or the answer can come back empty with `finish_reason` `length`. The reasoning tiers accept `reasoning_effort` (`none`, `low`, `medium`, `high`) and return their reasoning next to the answer. `z-ultra` still reasons with `none` (stage, 2026-10-31), so leave it room in `max_tokens`:
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
from zarx import reasoning_text
|
|
107
|
+
|
|
108
|
+
message = completion.choices[0].message
|
|
109
|
+
print(reasoning_text(message)) # None when the tier returned no reasoning
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Responses API and data
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
response = client.responses.create(model="z-pro", input="Two lines on GDPR.", max_output_tokens=256)
|
|
116
|
+
print(response.output_text)
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
This client sends `store=False` unless you pass `store=True`. The server default is `store=True`, and how long stored content is kept depends on your key's retention policy. See `docs/data.md` in the repository.
|
|
120
|
+
|
|
121
|
+
## Errors
|
|
122
|
+
|
|
123
|
+
Zarx answers in the OpenAI error format, so the OpenAI exception classes apply and are re-exported:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
import zarx
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
client.chat.completions.create(model="z-unknown", messages=[{"role": "user", "content": "hi"}])
|
|
130
|
+
except zarx.NotFoundError as exc:
|
|
131
|
+
print(exc.code) # model_not_found
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
A missing key raises `zarx.ZarxConfigError` before any request is made.
|
|
135
|
+
|
|
136
|
+
### Retries and rate limits
|
|
137
|
+
|
|
138
|
+
Like the OpenAI client, `Zarx` retries twice on connection errors, 408, 409, 429 and 5xx. On a 429 it waits what the `retry-after` header says (up to 59 seconds), so one call can block silently for up to about 2 minutes. Zarx keeps nothing after the response, so a retry runs the request again (there is no server-side deduplication; `Idempotency-Key` is ignored). When latency or a duplicate matters, turn retries off and handle the error yourself:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
client = Zarx(max_retries=0)
|
|
142
|
+
try:
|
|
143
|
+
client.chat.completions.create(model="z-fast", messages=[{"role": "user", "content": "hi"}])
|
|
144
|
+
except zarx.RateLimitError as exc:
|
|
145
|
+
print(exc.response.headers.get("retry-after")) # seconds until the next minute window
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Chat Completions responses carry `x-ratelimit-*` headers (requests and tokens: limit, remaining, reset) when your account has rate limits set, and every response carries an `x-request-id`. The per-minute window is the clock minute. See `docs/errors.md`.
|
|
149
|
+
|
|
150
|
+
## Production or beta
|
|
151
|
+
|
|
152
|
+
| Environment | Base URL | What it is |
|
|
153
|
+
|---|---|---|
|
|
154
|
+
| `production` (default) | `https://api.zarx.ai/v1` | the stable API |
|
|
155
|
+
| `beta` | `https://api-stage.zarx.ai/v1` | the stage environment: new models and features land here first and may change |
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
from zarx import Zarx
|
|
159
|
+
|
|
160
|
+
client = Zarx() # production
|
|
161
|
+
beta = Zarx(environment="beta") # beta; "prod" and "stage" also work
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
The first that is set wins: `base_url=`, `environment=`, `ZARX_BASE_URL`, `ZARX_ENVIRONMENT`, then production. What the code says beats what the shell says. Keys are per environment: a production key gets 401 on beta and the other way round, so set the key that matches. `zarx.ENVIRONMENTS`, `zarx.PRODUCTION_BASE_URL` and `zarx.BETA_BASE_URL` are exported; `STAGE_BASE_URL` stays as an alias of `BETA_BASE_URL`. Realtime transcription follows the client's environment.
|
|
165
|
+
|
|
166
|
+
## Command line
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
zarx models # models your key can use
|
|
170
|
+
zarx chat "Hello" # streams the answer from z-fast
|
|
171
|
+
zarx chat -m z-pro --show-reasoning "Why is the sky blue?"
|
|
172
|
+
zarx speak "Good morning" -o hello.wav # text to speech (WAV; -f mp3 for MP3, -v for the voice)
|
|
173
|
+
zarx transcribe hello.wav # speech to text
|
|
174
|
+
zarx translate "Good morning" --to es # text translation (a code or a name: es, Spanish)
|
|
175
|
+
zarx forecast 3 4 6 5 7 9 -p 3 # next 3 periods of a series (hourly steps ending now)
|
|
176
|
+
zarx forecast --csv visits.csv -p 24 --band # from a CSV, with a low/high band; --json for the raw answer
|
|
177
|
+
zarx --beta models # same against beta (or ZARX_ENVIRONMENT=beta)
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Exit codes: 0 success, 1 API or network error, 2 configuration or input error (for example, no key, or fewer than 3 values to forecast).
|
|
181
|
+
|
|
182
|
+
If the console cannot print a character of the answer (for example a Windows console in cp1252 and an answer with Japanese text), `zarx` prints `?` in its place instead of failing. Set `PYTHONIOENCODING=utf-8` to see every character.
|
|
183
|
+
|
|
184
|
+
## Audio
|
|
185
|
+
|
|
186
|
+
One call each, with the client built from the environment unless you pass `client=`:
|
|
187
|
+
|
|
188
|
+
```python
|
|
189
|
+
from zarx import audio
|
|
190
|
+
|
|
191
|
+
text = audio.transcribe("meeting.wav") # speech to text
|
|
192
|
+
wav = audio.speak("Good morning", voice="marin") # text to speech, WAV bytes
|
|
193
|
+
spanish = audio.translate("Good morning", "Spanish") # text translation
|
|
194
|
+
text = audio.transcribe_realtime("meeting-16k.wav", on_delta=print) # text as it is recognised
|
|
195
|
+
spanish_wav = audio.speech_to_speech("meeting.wav", "es") # voice to voice, WAV bytes
|
|
196
|
+
for piece in audio.speak_stream("Good morning"): # speech in pieces (beta), PCM 24 kHz
|
|
197
|
+
player.write(piece)
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
Voices: `zarx.voices.voices()` lists them and `zarx.voices.voice_catalog()` adds the design attributes (beta and production since 2026-11-02; a deployment without the route raises `zarx.voices.VoicesNotAvailableError`).
|
|
201
|
+
|
|
202
|
+
`zarx.audio` (`transcribe`, `speak`, `translate`) and the `zarx speak`, `zarx transcribe` and `zarx translate` commands were run against stage on 2026-10-30, 2026-10-31 and 2026-11-01 with a zero-retention key: all three audio models are cleared for zero retention and answer 200. The audio model names may still change before general availability. Production lists the audio models since 2026-11-02; the measurements below are from stage (beta):
|
|
203
|
+
|
|
204
|
+
- `transcribe` (`z-transcribe`, `/v1/audio/transcriptions`): WAV (8, 16, 24 or 44.1 kHz, mono or stereo), MP3 or FLAC. 13 languages detected from the audio, plus Catalan, Galician and Basque on files when you name them: `transcribe(path, language="ca")` (`gl`, `eu`; the plain ISO 639-1 code) is served by a second engine of Zarx behind the same model, same name and price (beta since 2026-11-02; production when its next release is promoted). Without `language`, Catalan comes out as Spanish with no warning, so name the language when you know it. For the other languages `language` is a hint that does not change the result; `prompt` never does. `response_format="text"` answers plain text (`text/plain`) on production and beta; the helper returns the text. `verbose_json`, `srt` and `vtt` get 400 (on beta `verbose_json` is answered when `language` is `ca`, `gl` or `eu`). `/v1/audio/translations` does not translate.
|
|
205
|
+
- `transcribe_realtime` (`z-transcribe`, WebSocket at `/v1/audio/transcriptions/realtime`, Zarx's own events, not the OpenAI Realtime API): takes a WAV file or bytes in PCM16 mono 16 kHz (other WAV formats are refused before connecting), raw PCM bytes, or an iterable of PCM chunks (a microphone). `on_delta(text)` gets every piece of recognised text, `on_segment(text)` every finished sentence; the return value is the final transcript. Needs the `realtime` extra (`websockets`). A 3 s sample answered in 1.4 s on stage on 2026-11-01. Catalan, Galician and Basque are served on files only: the live route refuses `source_language` `ca`, `gl` or `eu` with `unsupported_language` (the helper never sends it), and Catalan audio sent live comes out as Spanish.
|
|
206
|
+
- `speak` (`z-speech`, `/v1/audio/speech`): `response_format` `wav` (default, 24 kHz mono 16-bit), `mp3`, `opus`, `flac`, `aac` or `pcm`; `ogg` gets 422. `voice` defaults to `"alloy"`, one of 13 presets (`alloy`, `ash`, `ballad`, `cedar`, `coral`, `echo`, `fable`, `marin`, `nova`, `onyx`, `sage`, `shimmer`, `verse`); `auto` also works, and `design:<attributes>` builds a voice from comma-separated attributes, at most one per group (gender, age, pitch, style, accent), for example `design:female,british accent` or `design:male,elderly,low pitch`; the lists are in `zarx.audio.VOICE_DESIGN_ATTRIBUTES`; free text or an unknown name gets 400 `invalid_voice` with a partner key and 422 with an account-wide key, and two attributes of one group (two accents) get 500. The same preset is not guaranteed to sound identical across calls. `speed` works; free-text `instructions` gets 422.
|
|
207
|
+
- `speak_stream` (`z-speech` with `stream_format="sse"`): yields the audio in pieces as it is generated (PCM by default, about ten pieces for a sentence) and sets `.usage` (`{"input_characters": N}`) at the end. Streams on beta and production (2026-11-02); a deployment that does not stream sends the whole audio as one piece.
|
|
208
|
+
- `translate` (`z-translate`, through chat completions): the target is a language name in English (`"Spanish"`) or a code (`"es"`, `"pt-BR"`); good for English, Spanish, French and German, and `GET /v1/models` lists the 36 languages it serves in `capabilities.languages.supported` on beta. Catalan, Galician and Basque are not served by `z-translate`: on beta since 2026-11-02 the request answers 400 `unsupported_language` (`openai.BadRequestError`; before that it answered Spanish in 8 of 10 sentences; production when its next release is promoted). The helper does not switch models by itself: for those three languages pass `model="z-ultra"`, `zarx.audio.translate(text, "ca", model="z-ultra")` (45 of 46 correct in our test).
|
|
209
|
+
- `speech_to_speech` (`z-voice`, `/v1/audio/speech-to-speech`): an audio file in, the same speech in `target_language` (an ISO 639-1 code, default `"en"`) out, as WAV bytes whatever format is asked. About 3 s for a short sentence on beta and production (2026-11-02). `target_language` `"ca"`, `"gl"` or `"eu"` works with nothing to do on your side: the translation step runs on `z-ultra` behind the same call (beta since 2026-11-02, a Spanish clip into Catalan in 4.2 s; production when its next release is promoted).
|
|
210
|
+
- Use the model name you sent, not the `model` field of audio responses, to identify the model.
|
|
211
|
+
|
|
212
|
+
See `docs/models.md` for the routes and events.
|
|
213
|
+
|
|
214
|
+
## Forecasting
|
|
215
|
+
|
|
216
|
+
```python
|
|
217
|
+
import zarx
|
|
218
|
+
|
|
219
|
+
result = zarx.forecast([3, 4, 6, 5, 7, 9], 3) # next 3 periods, hourly steps ending now
|
|
220
|
+
result = zarx.forecast(pairs, 12, include_band=True) # [(timestamp, value), ...] with a low/high band
|
|
221
|
+
result = zarx.forecast_csv("visits.csv", 24, data_points=256) # header row, timestamp first, value last
|
|
222
|
+
|
|
223
|
+
print(result.values) # the point forecasts
|
|
224
|
+
for point in result: # .timestamp, .value, .low, .high, .percentiles
|
|
225
|
+
print(point.timestamp, point.value)
|
|
226
|
+
print(result.billable_points) # what the call is billed for (usage.datapoints, or context plus forecast points)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
`series` is a list of numbers (one timestamp every `step`, default `"1h"`, ending now or starting at `start`), of `(timestamp, value)` pairs, of dicts `{"timestamp", "value", ...covariates}`, or a mapping of timestamp to value; at least 3 points. Pass real timestamps when you have them, the model uses the calendar. `periods` must be at least 1. Anything else you pass as a keyword goes into the request body as is (for example `forecast_extra_params={"quantile_low": 0.2, "quantile_high": 0.8}`). `result.raw` is the response exactly as the API returned it.
|
|
230
|
+
|
|
231
|
+
Verified on beta on 2026-11-01 and 2026-11-02 with `z-forecast` (64 hourly points, a 512-row CSV, a 12-point daily series); production lists the model since 2026-11-02. The horizon is at most 1,000 periods per call. See `docs/models.md`.
|
|
232
|
+
|
|
233
|
+
## Development
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
uv venv .venv && uv pip install -e '.[dev]'
|
|
237
|
+
.venv/bin/pytest # offline tests
|
|
238
|
+
ZARX_API_KEY=... ZARX_ENVIRONMENT=beta .venv/bin/pytest -m live # with a beta key
|
|
239
|
+
uv build # wheel and sdist in dist/
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
The `dev` extra includes `websockets`, which the `realtime` extra adds for users of `transcribe_realtime`.
|
|
243
|
+
|
|
244
|
+
## License
|
|
245
|
+
|
|
246
|
+
Apache License 2.0. See LICENSE and NOTICE.
|