Skip to content

SDK regeneration - #39

Closed
fern-api[bot] wants to merge 2 commits into
mainfrom
fern-bot/2026-10-27_16-45-54_696
Closed

fern-api[bot] wants to merge 2 commits into
mainfrom
fern-bot/2026-10-27_16-45-54_696

Conversation

@fern-api

@fern-api fern-api Bot commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Automated SDK generation by Fern

fern-api Bot added 2 commits October 27, 2026 16:45
Generated by Fern
CLI Version: unknown
Generators:
  - fernapi/fern-python-sdk: 5.41.10
@vitalragaz

Copy link
Copy Markdown
Contributor

Superseded by #38, which carries this regeneration (python generator 5.41.10) plus the hand-kept files.

@vitalragaz vitalragaz closed this Oct 27, 2026
vitalragaz added a commit that referenced this pull request Oct 29, 2026
**`speechify-api` catches up with the API: simba-3.5, projects,
workspaces, audio watermark verification and webhook endpoints, with API
version 2026-09-30 as the default. Merging releases 5.0.0.**

**Why:** Fern pushed every regeneration since August to `sdk-release`
and nobody merged it, so 4.0.0 predates simba-3.5. This branch merges
`sdk-release`, then takes every generated file from Fern's own
regeneration of SpeechifyInc/speechify-api main (#39: python generator
**5.41.10**, origin `14383dab`) and keeps this branch's hand-kept files.
Future regenerations arrive as PRs like #39.

**What to look at**
- **`SpeechifyEnvironment.DEFAULT` has `base` and `websocket`.** The
WebSocket URL used to be called `production` because of the AsyncAPI
server's name. SpeechifyInc/speechify-api#4744 renames that server, so
the name is right in the same major that turns the environment into a
class.
- **Audio calls raise `ContentTooLargeError` on 413**, because the spec
declares it on the synthesis operations. With-timestamps streaming still
yields the declared `SpeechStreamEvent_*` classes, and a test pins that.
- **The client reads `SPEECHIFY_API_KEY` when it is built, not at
import.** Generator 5.41.10 resolves the token in the constructor, so a
key set after `import speechify` (for example by `load_dotenv()`) is
used. An explicit `token=` still wins. This is #34's fix, now from the
generator.
- **A missing key still does not raise at construction.** `POST
/v1/audio/watermark/verify` takes no credentials, so a keyless client
has to be able to call it. Without a key, the first authenticated call
raises `UnauthorizedError` (401 `unauthorized`). Proposed follow-up in
speechify-api: make that 401 message name `SPEECHIFY_API_KEY`.
- **Other 5.41.10 changes in generated code:** stream reconnection
options (`stream_reconnection_enabled`,
`max_stream_reconnection_attempts`) on the client and per request, a
`timeout` request option (`timeout_in_seconds` stays as a deprecated
alias), opt-in `retry_remote_protocol_errors`, empty SSE data lines
skipped, and mypy passing under pydantic 2.14 natively, so the earlier
hand patch is gone.
- **`pyproject.toml` license** is the generator's PEP 639 form
(`[project] license = "MIT"`, `license-files`). Poetry 1.5.1, which
publishes, still writes `License: MIT` and the MIT classifier; current
poetry-core writes `License-Expression: MIT`. The version stays 4.0.0,
so release-please computes 5.0.0.
- **README.** No Websockets section: it documented
`client.audio.stream_input`, which this SDK does not have. Examples use
simba-3.5, matching what SpeechifyInc/speechify-api#4741's spec
generates, and the timeout example uses `timeout`.
- **`tests/custom/test_client.py`** (hand-kept, in `.fernignore`):
offline tests of a client built with defaults, sync and async.
Environment, URL, Bearer header, one `Speechify-Version` across resource
clients, a with-timestamps stream framed as the API writes it, the 413,
no `Authorization` without a key, the 401 without a key, a key set after
import being used, and an explicit token beating the environment.

**Merge order and follow-ups**
- SpeechifyInc/speechify-api#4744 has merged and pins the docs snippets
to 5.0.0, so the docs point at a version that is not on PyPI until this
releases.
- #39 is closed as superseded by this PR. #34 stays open until its
author confirms this covers their case.
- **After the release, not now:** reset `sdk-release` to `main`, or
delete it.

## How verified
- CI on `d280838` (Python 3.10, Poetry 1.5.1): `compile` (mypy) and
`test` pass.
- Local, Python 3.12, lockfile pydantic 2.14.1: `pytest` 103 passed, 3
skipped (aiohttp not installed; 106 passed with the extra). `mypy .`: no
issues in 176 files.
- The two new env-var tests fail against this branch's previous 5.14.20
`client.py` and pass on 5.41.10.
- Offline smoke, no credits: `Speechify()` with the key set after import
sends `audio.speech()` to `https://api.speechify.ai/v1/audio/speech`
with the Bearer header and `Speechify-Version: 2026-09-30`.
`request_options={"timeout": 1}` reaches httpx as a 1 s timeout.
- Live, keyless, no credits: `models.list()` and `audio.speech()` raise
`UnauthorizedError` 401
`{"error":{"code":"unauthorized","message":"Unauthorized"}}`.
`audio.watermark.verify()` answers `watermarked=False`.
- The tree differs from #39 only in hand-kept files: `AGENTS.md`,
`README.md`, `reference.md`, `.fernignore`,
`tests/custom/test_client.py`, and the 4.0.0 version in `pyproject.toml`
and `.fern/metadata.json`.

<details><summary>Investigation detail</summary>

- Merge commit `48cb2c9`: every generated path checked out from
`fern-bot/2026-10-27_16-45-54_696` (`33e10e7`), hand-kept files from
this branch. Fern's `.fern/replay.lock`, `.gitattributes` and their
`.fernignore` lines are in; `tests/custom/test_client.py` stays in
`.fernignore`.
- Build check: `poetry build` (1.5.1) gives `License: MIT`, `Classifier:
License :: OSI Approved :: MIT License` and `LICENSE` in dist-info.
`python -m build` with poetry-core 2.5.0 gives `Metadata-Version: 2.4`,
`License-Expression: MIT`, `License-File: LICENSE`. `twine check` passes
both.
- An earlier revision of SpeechifyInc/speechify-api#4744 added
`x-fern-discriminator-context: protocol` to the stream union for the
TypeScript SDK. In Python that yields
`SpeechChunkEvent`/`SpeechDoneEvent` cast to the `SpeechStreamEvent_*`
union, so `isinstance` checks fail. The annotation was dropped, and the
stream test fails if it comes back.
- The audio calls now map 409 to `ConflictError`, as the spec declares.

</details>

BREAKING CHANGE: the default API version moves to 2026-09-30, `base_url`
is gone, and `SpeechifyEnvironment` is a class with `base` and
`websocket`.
- Requests now send `Speechify-Version: 2026-09-30` instead of
2026-09-13. On that version `simba-english` and `simba-multilingual`
return 400 `model_retired`, and `output_format="pcm_16000"` returns real
16 kHz audio instead of 24 kHz bytes labelled 16 kHz.
- To keep the 4.x wire behaviour, pin the version:
`Speechify(version="2026-09-13")`
- `Speechify(base_url=...)` and `AsyncSpeechify(base_url=...)` are
removed. For a custom URL, pass
`environment=SpeechifyEnvironment(base="https://...",
websocket="wss://...")`.
- `SpeechifyEnvironment` is a plain class, not an `Enum`, so
`SpeechifyEnvironment.DEFAULT.value` becomes
`SpeechifyEnvironment.DEFAULT.base`.
- A client built without a key no longer raises at construction. The
first authenticated call raises `UnauthorizedError` instead.

---------

Co-authored-by: fern-api[bot] <115122769+fern-api[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant