Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
6bec701
chore(internal): avoid errors for isinstance checks on proxies
stainless-app[bot] May 8, 2025
abf0203
chore(internal): avoid lint errors in pagination expressions
stainless-app[bot] May 9, 2025
2016cda
fix(package): support direct resource imports
stainless-app[bot] May 9, 2025
e704323
docs(api): updates to API spec
stainless-app[bot] May 9, 2025
4902642
docs(api): updates to API spec
stainless-app[bot] May 9, 2025
bfc448f
chore(ci): upload sdks to package manager
stainless-app[bot] May 14, 2025
b421fd0
chore(ci): fix installation instructions
stainless-app[bot] May 15, 2025
302e1a8
chore(docs): grammar improvements
stainless-app[bot] May 21, 2025
b6a9aff
chore(docs): remove reference to rye shell
stainless-app[bot] Jun 2, 2025
b78bf04
chore(docs): remove unnecessary param examples
stainless-app[bot] Jun 2, 2025
1bf8218
feat(client): add follow_redirects request option
stainless-app[bot] Jun 2, 2025
6c8b5ad
chore(tests): run tests in parallel
stainless-app[bot] Jun 12, 2025
55872c2
fix(client): correctly parse binary response | stream
stainless-app[bot] Jun 12, 2025
5e99c8f
chore(tests): add tests for httpx client instantiation & proxies
stainless-app[bot] Jun 16, 2025
f6aa1eb
chore(internal): update conftest.py
stainless-app[bot] Jun 16, 2025
2dc262b
chore(ci): enable for pull requests
stainless-app[bot] Jun 17, 2025
52ec704
chore(readme): update badges
stainless-app[bot] Jun 17, 2025
f5db115
fix(tests): fix: tests which call HTTP endpoints directly with the ex…
stainless-app[bot] Jun 17, 2025
27ebc83
fix: allow utf-8 encoded filename in headers
ms-jpq Jun 23, 2025
876817a
Merge pull request #17 from stainless-sdks/hao/sdk-2788-python-fix-un…
ms-jpq Jun 23, 2025
f0cc6ef
docs(client): fix httpx.Timeout documentation reference
stainless-app[bot] Jun 24, 2025
fd7c358
chore: parse environment variables for default headers
mmikita95 Jul 7, 2025
6b7aeb4
fix: merged_headers -> default_headers to avoid conflicts
mmikita95 Jul 11, 2025
843d69d
feat(client): add support for aiohttp
stainless-app[bot] Jul 15, 2025
94bb5d6
chore(tests): skip some failing tests on the latest python versions
stainless-app[bot] Jun 23, 2025
0d20a9e
fix(ci): release-doctor — report correct token name
stainless-app[bot] Jun 26, 2025
ced5ec3
chore(ci): only run for pushes and fork pull requests
stainless-app[bot] Jun 27, 2025
7f49d8d
fix(ci): correct conditional
stainless-app[bot] Jun 29, 2025
9ee05fb
chore(ci): change upload type
stainless-app[bot] Jul 1, 2025
81c98bd
chore(internal): codegen related update
stainless-app[bot] Jul 7, 2025
383abab
chore(internal): bump pinned h11 dep
stainless-app[bot] Jul 8, 2025
fe9f5d9
chore(package): mark python 3.13 as supported
stainless-app[bot] Jul 8, 2025
a4774a8
fix(parsing): correctly handle nested discriminated unions
stainless-app[bot] Jul 9, 2025
b93bb29
chore(readme): fix version rendering on pypi
stainless-app[bot] Jul 10, 2025
ffcc579
fix(client): don't send Content-Type header on GET requests
stainless-app[bot] Jul 11, 2025
fc436af
feat: clean up environment call outs
stainless-app[bot] Jul 14, 2025
e924493
Merge pull request #241 from mmikita95/chore-header-envs
stainless-app[bot] Jul 16, 2025
aac4777
release: 2.2.1
stainless-app[bot] Jul 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@ on:
- 'integrated/**'
- 'stl-preview-head/**'
- 'stl-preview-base/**'
pull_request:
branches-ignore:
- 'stl-preview-head/**'
- 'stl-preview-base/**'

jobs:
lint:
timeout-minutes: 10
name: lint
runs-on: ${{ github.repository == 'stainless-sdks/writer-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4

Expand All @@ -30,10 +35,49 @@ jobs:
- name: Run lints
run: ./scripts/lint

build:
if: github.repository == 'stainless-sdks/writer-python' && (github.event_name == 'push' || github.event.pull_request.head.repo.fork)
timeout-minutes: 10
name: build
permissions:
contents: read
id-token: write
runs-on: depot-ubuntu-24.04
steps:
- uses: actions/checkout@v4

- name: Install Rye
run: |
curl -sSf https://rye.astral.sh/get | bash
echo "$HOME/.rye/shims" >> $GITHUB_PATH
env:
RYE_VERSION: '0.44.0'
RYE_INSTALL_OPTION: '--yes'

- name: Install dependencies
run: rye sync --all-features

- name: Run build
run: rye build

- name: Get GitHub OIDC Token
id: github-oidc
uses: actions/github-script@v6
with:
script: core.setOutput('github_token', await core.getIDToken());

- name: Upload tarball
env:
URL: https://pkg.stainless.com/s
AUTH: ${{ steps.github-oidc.outputs.github_token }}
SHA: ${{ github.sha }}
run: ./scripts/utils/upload-artifact.sh

test:
timeout-minutes: 10
name: test
runs-on: ${{ github.repository == 'stainless-sdks/writer-python' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
if: github.event_name == 'push' || github.event.pull_request.head.repo.fork
steps:
- uses: actions/checkout@v4

Expand Down
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "2.2.0"
".": "2.2.1"
}
4 changes: 2 additions & 2 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 32
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/writerai%2Fwriter-07dea48ea85e600712dcdfd99a688f6a9cb8dd1f56d0a06e0ab54fc8a98a89b1.yml
openapi_spec_hash: 0d30ab04c227bf53f3109dc4d861e5dc
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/writerai%2Fwriter-fab7a71148b6f413a4425ca9f2ce3d42557b65d35ab28c6f64daa7fce6d0ffe2.yml
openapi_spec_hash: 0ead6944545bc40172176e15cc704633
config_hash: c0c9f57ab19252f82cf765939edc61de
54 changes: 54 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,59 @@
# Changelog

## 2.2.1 (2025-07-16)

Full Changelog: [v2.2.0...v2.2.1](https://github.com/writer/writer-python/compare/v2.2.0...v2.2.1)

### Features

* clean up environment call outs ([fc436af](https://github.com/writer/writer-python/commit/fc436af17d30723e147c0cc8198886adfa43d0a1))
* **client:** add follow_redirects request option ([1bf8218](https://github.com/writer/writer-python/commit/1bf8218881286ddf4bf1c9c2c4c8e8b58837425b))
* **client:** add support for aiohttp ([843d69d](https://github.com/writer/writer-python/commit/843d69decc9eb5c1cb793fc466c026917e8036ce))


### Bug Fixes

* allow utf-8 encoded filename in headers ([27ebc83](https://github.com/writer/writer-python/commit/27ebc83f9eb76b7ab2208ed8ac991bd857773928))
* **ci:** correct conditional ([7f49d8d](https://github.com/writer/writer-python/commit/7f49d8d55819747831db0b7baa015b274b18108d))
* **ci:** release-doctor — report correct token name ([0d20a9e](https://github.com/writer/writer-python/commit/0d20a9e7d8be4f8fbc316480335afd314d112a8a))
* **client:** correctly parse binary response | stream ([55872c2](https://github.com/writer/writer-python/commit/55872c2302ae5458f872ab34809c85781f0f6f17))
* **client:** don't send Content-Type header on GET requests ([ffcc579](https://github.com/writer/writer-python/commit/ffcc5799423bca552deabaa0cf98dc2e67d11a39))
* merged_headers -> default_headers to avoid conflicts ([6b7aeb4](https://github.com/writer/writer-python/commit/6b7aeb4335534bcfafc2f9849fa4162f44002075))
* **package:** support direct resource imports ([2016cda](https://github.com/writer/writer-python/commit/2016cda2813d2b49abf8f6aa2dafbecdcaddfa36))
* **parsing:** correctly handle nested discriminated unions ([a4774a8](https://github.com/writer/writer-python/commit/a4774a8592d82d03ff1d2947ee61a909ac40d534))
* **tests:** fix: tests which call HTTP endpoints directly with the example parameters ([f5db115](https://github.com/writer/writer-python/commit/f5db1150f0c8b53e9c9b471c1b1f555cfa6be2df))


### Chores

* **ci:** change upload type ([9ee05fb](https://github.com/writer/writer-python/commit/9ee05fb02fede8fcba4418c55361080106f5172e))
* **ci:** enable for pull requests ([2dc262b](https://github.com/writer/writer-python/commit/2dc262bf297d3d0f42489cf2c3e2ea59cb1a17cc))
* **ci:** fix installation instructions ([b421fd0](https://github.com/writer/writer-python/commit/b421fd089015ede20a5cfa8214c19dc16b66f27c))
* **ci:** only run for pushes and fork pull requests ([ced5ec3](https://github.com/writer/writer-python/commit/ced5ec33765e4d8454c597a135d20be8b89e0c4e))
* **ci:** upload sdks to package manager ([bfc448f](https://github.com/writer/writer-python/commit/bfc448fb9516e07a3a5fa903ef04b2e838865a0a))
* **docs:** grammar improvements ([302e1a8](https://github.com/writer/writer-python/commit/302e1a8fb48a3f0fa83bef9fa1fb5ee2244893f1))
* **docs:** remove reference to rye shell ([b6a9aff](https://github.com/writer/writer-python/commit/b6a9aff0e0da58c0f19b4634448be6b6d539593c))
* **docs:** remove unnecessary param examples ([b78bf04](https://github.com/writer/writer-python/commit/b78bf04d813ce51075386f660a0cfa3647db77d3))
* **internal:** avoid errors for isinstance checks on proxies ([6bec701](https://github.com/writer/writer-python/commit/6bec701344af3c9cd7853cc9dcacfbd959dbf485))
* **internal:** avoid lint errors in pagination expressions ([abf0203](https://github.com/writer/writer-python/commit/abf02038a3857004cbb061cffaa9f0bf29f841b0))
* **internal:** bump pinned h11 dep ([383abab](https://github.com/writer/writer-python/commit/383ababb87995f734a70b58178d407b00df130ea))
* **internal:** codegen related update ([81c98bd](https://github.com/writer/writer-python/commit/81c98bd5948b7b5d0175134f43ced00a559d3f41))
* **internal:** update conftest.py ([f6aa1eb](https://github.com/writer/writer-python/commit/f6aa1eb979f08b6ee1f9518f19b618e9346c04c6))
* **package:** mark python 3.13 as supported ([fe9f5d9](https://github.com/writer/writer-python/commit/fe9f5d904f516d1eb37037acd07df4e43e86246a))
* parse environment variables for default headers ([fd7c358](https://github.com/writer/writer-python/commit/fd7c358ae9671a20c338d6868b4420b8a982fe17))
* **readme:** fix version rendering on pypi ([b93bb29](https://github.com/writer/writer-python/commit/b93bb292fe04ff647049ef0b1431181435463c92))
* **readme:** update badges ([52ec704](https://github.com/writer/writer-python/commit/52ec7049643a69006ad01aa7d3c47533e017afd9))
* **tests:** add tests for httpx client instantiation & proxies ([5e99c8f](https://github.com/writer/writer-python/commit/5e99c8fae8879b664c7982fc88a0f5dfd0f111d7))
* **tests:** run tests in parallel ([6c8b5ad](https://github.com/writer/writer-python/commit/6c8b5ad718480211ef16b7a81064eadb988c69de))
* **tests:** skip some failing tests on the latest python versions ([94bb5d6](https://github.com/writer/writer-python/commit/94bb5d63562691568da5e2a48e4890dbbbcda456))


### Documentation

* **api:** updates to API spec ([4902642](https://github.com/writer/writer-python/commit/4902642b8d9cc80b3bae1d5a10d44a0959e2d0b0))
* **api:** updates to API spec ([e704323](https://github.com/writer/writer-python/commit/e7043234b044b7fa0897c2f3d07685d429071c08))
* **client:** fix httpx.Timeout documentation reference ([f0cc6ef](https://github.com/writer/writer-python/commit/f0cc6ef6ac440627a7ed903142b79d49c3d0a22e))

## 2.2.0 (2025-04-30)

Full Changelog: [v2.2.0-rc1...v2.2.0](https://github.com/writer/writer-python/compare/v2.2.0-rc1...v2.2.0)
Expand Down
3 changes: 1 addition & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ $ rye sync --all-features
You can then run scripts using `rye run python script.py` or by activating the virtual environment:

```sh
$ rye shell
# or manually activate - https://docs.python.org/3/library/venv.html#how-venvs-work
# Activate the virtual environment - https://docs.python.org/3/library/venv.html#how-venvs-work
$ source .venv/bin/activate

# now you can omit the `rye run` prefix
Expand Down
53 changes: 45 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Writer Python API library

[![PyPI version](https://img.shields.io/pypi/v/writer-sdk.svg)](https://pypi.org/project/writer-sdk/)
<!-- prettier-ignore -->
[![PyPI version](https://img.shields.io/pypi/v/writer-sdk.svg?label=pypi%20(stable))](https://pypi.org/project/writer-sdk/)

The Writer Python library provides access to the Writer REST API from any Python 3.8+
application. It includes a set of tools and utilities that make it easy to integrate the capabilities
Expand Down Expand Up @@ -107,7 +108,46 @@ asyncio.run(main())

Functionality between the synchronous and asynchronous clients is otherwise identical.

## Streaming versus non-streaming responses
### With aiohttp

By default, the async client uses `httpx` for HTTP requests. However, for improved concurrency performance you may also use `aiohttp` as the HTTP backend.

You can enable this by installing `aiohttp`:

```sh
# install from PyPI
pip install writer-sdk[aiohttp]
```

Then you can enable it by instantiating the client with `http_client=DefaultAioHttpClient()`:

```python
import asyncio
from writerai import DefaultAioHttpClient
from writerai import AsyncWriter


async def main() -> None:
async with AsyncWriter(
api_key="My API Key",
http_client=DefaultAioHttpClient(),
) as client:
chat_completion = await client.chat.chat(
messages=[
{
"content": "Write a haiku about programming",
"role": "user",
}
],
model="palmyra-x5",
)
print(chat_completion.id)


asyncio.run(main())
```

## Streaming responses

The Writer Python library provides support for streaming responses using Server Side Events (SSE).

Expand Down Expand Up @@ -255,10 +295,7 @@ client = Writer()
chat_completion = client.chat.chat(
messages=[{"role": "user"}],
model="model",
response_format={
"type": "text",
"json_schema": {},
},
response_format={"type": "text"},
)
print(chat_completion.response_format)
```
Expand Down Expand Up @@ -365,8 +402,8 @@ client.with_options(max_retries=5).chat.chat(

### Timeouts

By default, requests time out after three minutes. You can configure this with a `timeout` option,
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/#fine-tuning-the-configuration) object:
By default requests time out after three minutes. You can configure this with a `timeout` option,
which accepts a float or an [`httpx.Timeout`](https://www.python-httpx.org/advanced/timeouts/#fine-tuning-the-configuration) object:

```python
import httpx
Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ before making any information public.
## Reporting Non-SDK Related Security Issues

If you encounter security issues that are not directly related to SDKs but pertain to the services
or products provided by Writer please follow the respective company's security reporting guidelines.
or products provided by Writer, please follow the respective company's security reporting guidelines.

### Writer Terms and Policies

Please contact dev-feedback@writer.com for any questions or concerns regarding security of our services.
Please contact dev-feedback@writer.com for any questions or concerns regarding the security of our services.

---

Expand Down
2 changes: 1 addition & 1 deletion bin/check-release-environment
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
errors=()

if [ -z "${PYPI_TOKEN}" ]; then
errors+=("The WRITER_PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets.")
errors+=("The PYPI_TOKEN secret has not been set. Please set it in either this repository's secrets or your organization secrets.")
fi

lenErrors=${#errors[@]}
Expand Down
10 changes: 7 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "writer-sdk"
version = "2.2.0"
version = "2.2.1"
description = "The official Python library for the writer API"
dynamic = ["readme"]
license = "Apache-2.0"
Expand All @@ -26,6 +26,7 @@ classifiers = [
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Operating System :: OS Independent",
"Operating System :: POSIX",
"Operating System :: MacOS",
Expand All @@ -39,6 +40,8 @@ classifiers = [
Homepage = "https://github.com/writer/writer-python"
Repository = "https://github.com/writer/writer-python"

[project.optional-dependencies]
aiohttp = ["aiohttp", "httpx_aiohttp>=0.1.8"]

[tool.rye]
managed = true
Expand All @@ -56,7 +59,8 @@ dev-dependencies = [
"importlib-metadata>=6.7.0",
"rich>=13.7.1",
"inline-snapshot >=0.7.0",
"nest_asyncio==1.6.0"
"nest_asyncio==1.6.0",
"pytest-xdist>=3.6.1",
]

[tool.rye.scripts]
Expand Down Expand Up @@ -128,7 +132,7 @@ replacement = '[\1](https://github.com/writer/writer-python/tree/main/\g<2>)'

[tool.pytest.ini_options]
testpaths = ["tests"]
addopts = "--tb=short"
addopts = "--tb=short -n auto"
xfail_strict = true
asyncio_mode = "auto"
asyncio_default_fixture_loop_scope = "session"
Expand Down
35 changes: 33 additions & 2 deletions requirements-dev.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,24 @@
# universal: false

-e file:.
aiohappyeyeballs==2.6.1
# via aiohttp
aiohttp==3.12.8
# via httpx-aiohttp
# via writer-sdk
aiosignal==1.3.2
# via aiohttp
annotated-types==0.6.0
# via pydantic
anyio==4.4.0
# via httpx
# via writer-sdk
argcomplete==3.1.2
# via nox
async-timeout==5.0.1
# via aiohttp
attrs==25.3.0
# via aiohttp
asttokens==3.0.0
# via inline-snapshot
certifi==2023.7.22
Expand All @@ -34,18 +45,27 @@ exceptiongroup==1.2.2
# via pytest
executing==2.2.0
# via inline-snapshot
execnet==2.1.1
# via pytest-xdist
filelock==3.12.4
# via virtualenv
h11==0.14.0
frozenlist==1.6.2
# via aiohttp
# via aiosignal
h11==0.16.0
# via httpcore
httpcore==1.0.2
httpcore==1.0.9
# via httpx
httpx==0.28.1
# via httpx-aiohttp
# via respx
# via writer-sdk
httpx-aiohttp==0.1.8
# via writer-sdk
idna==3.4
# via anyio
# via httpx
# via yarl
importlib-metadata==7.0.0
iniconfig==2.0.0
# via pytest
Expand All @@ -56,6 +76,9 @@ markdown-it-py==3.0.0
# via rich
mdurl==0.1.2
# via markdown-it-py
multidict==6.4.4
# via aiohttp
# via yarl
mypy==1.14.1
mypy-extensions==1.0.0
# via mypy
Expand All @@ -70,6 +93,9 @@ platformdirs==3.11.0
# via virtualenv
pluggy==1.5.0
# via pytest
propcache==0.3.1
# via aiohttp
# via yarl
pydantic==2.10.3
# via writer-sdk
pydantic-core==2.27.1
Expand All @@ -79,7 +105,9 @@ pygments==2.18.0
pyright==1.1.399
pytest==8.3.3
# via pytest-asyncio
# via pytest-xdist
pytest-asyncio==0.24.0
pytest-xdist==3.7.0
python-dateutil==2.8.2
# via time-machine
pytz==2023.3.post1
Expand All @@ -102,12 +130,15 @@ tomli==2.0.2
# via pytest
typing-extensions==4.12.2
# via anyio
# via multidict
# via mypy
# via pydantic
# via pydantic-core
# via pyright
# via writer-sdk
virtualenv==20.24.5
# via nox
yarl==1.20.0
# via aiohttp
zipp==3.17.0
# via importlib-metadata
Loading