Skip to content

release: 3.0.0-rc1#253

Merged
adeweaver merged 37 commits intomainfrom
release-please--branches--main--changes--next
Apr 13, 2026
Merged

release: 3.0.0-rc1#253
adeweaver merged 37 commits intomainfrom
release-please--branches--main--changes--next

Conversation

@stainless-app
Copy link
Copy Markdown
Contributor

@stainless-app stainless-app Bot commented Apr 8, 2026

Automated Release PR

3.0.0-rc1 (2026-04-13)

Full Changelog: v2.4.0...v3.0.0-rc1

Features

  • api: Deprecate AI Detection, Medical Comprehend, and Context-Aware Text Splitting (c6bee06)
  • client: add custom JSON encoder for extended type support (a855555)
  • client: add support for binary request streaming (56bd96e)
  • internal: implement indices array format for query and form serialization (898e230)

Bug Fixes

  • client: preserve hardcoded query params when merging with user params (70761a4)
  • deps: bump minimum typing-extensions version (e8e396e)
  • docs: fix mcp installation instructions for remote servers (b448904)
  • ensure file data are only sent as 1 parameter (ae4c4ad)
  • pydantic: do not pass by_alias unless set (f8a82fe)
  • remove custom binary_request handling superseded by codegen (#28) (763afaf)
  • resolve duplicate code (#29) (57837bc)
  • sanitize endpoint path params (e87c2a0)

Chores

  • ci: skip lint on metadata-only changes (e8479c1)
  • ci: skip uploading artifacts on stainless-internal branches (f8763df)
  • ci: upgrade actions/github-script (aa28320)
  • format all api.md files (0d10457)
  • internal: add request options to SSE classes (fead372)
  • internal: bump dependencies (6d39e6e)
  • internal: fix lint error on Python 3.14 (0cf9c5f)
  • internal: make test_proxy_environment_variables more resilient (00a019f)
  • internal: make test_proxy_environment_variables more resilient to env (2ec43af)
  • internal: tweak CI branches (cff7016)
  • internal: update actions/checkout version (4de949f)
  • internal: update gitignore (c1351cf)
  • internal: version bump (6733bea)
  • test: do not count install time for mock server timeout (ca18be8)
  • tests: bump steady to v0.19.4 (57552b1)
  • tests: bump steady to v0.19.5 (ec60cc4)
  • tests: bump steady to v0.19.6 (54e2229)
  • tests: bump steady to v0.19.7 (9b78194)
  • tests: bump steady to v0.20.1 (09fa209)
  • tests: bump steady to v0.20.2 (4bb6605)
  • update mock server docs (dd5b8a9)
  • update placeholder string (3d66005)

Documentation

  • api: updates to API spec (832318c)

Refactors

  • tests: switch from prism to steady (b63e313)

This pull request is managed by Stainless's GitHub App.

The semver version number is based on included commit messages. Alternatively, you can manually set the version number in the title of this pull request.

For a better experience, it is recommended to use either rebase-merge or squash-merge when merging this pull request.

🔗 Stainless website
📚 Read the docs
🙋 Reach out for help or questions

* fix: remove custom binary_request handling superseded by codegen

The codegen now natively supports a `content` parameter for binary
request streaming. Remove the custom `binary_request` parameter and
content routing that conflicts with this new codegen feature. Move
file transformation to the call site in resources/files.py.

* style: fix import ordering
stainless-app Bot added 28 commits April 9, 2026 19:30
Note that we still want to run tests, as these depend on the metadata.
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 1fc4567 to 2493bf0 Compare April 9, 2026 19:32
@stainless-app stainless-app Bot changed the title release: 2.4.1 release: 2.5.0 Apr 9, 2026
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch 2 times, most recently from aac51c1 to 7431f87 Compare April 9, 2026 19:33
@hackerone-code
Copy link
Copy Markdown

hackerone-code Bot commented Apr 9, 2026

HackerOne Code Security Review

🟢 Scan Complete: 3 Issue(s)
🟢 Validation Complete: Any Issues detected were validated by one of our engineers. None were determined to require immediate action.

Here's how the code changes were interpreted and info about the tools used for scanning.

📖 Summary of Changes The update introduces version 3.0.0-rc1 with significant changes across the project. Key modifications include deprecating some AI tools, adding custom JSON encoder support, and improving binary request streaming. The update involves updates to workflow files, dependencies, and source code, with a focus on enhancing type safety, URL path generation, and overall SDK functionality. Several tools and type definitions have been removed or restructured.
File Summary
.github/workflows/ci.yml The workflow file was updated with changes to branch filtering, GitHub Actions versions, and added conditions for skipping certain jobs. Modifications include updating checkout and GitHub script actions, and adding more specific branch and commit message filters.
.github/workflows/publish-pypi.yml The workflow file was updated to use actions/checkout@v6 instead of actions/checkout@v4, with all other content remaining the same.
.github/workflows/release-doctor.yml The GitHub Actions workflow file was updated to use actions/checkout@v6 instead of actions/checkout@v4, with all other content remaining the same.
.gitignore The .gitignore file now includes an additional log file (.stdy.log) alongside the existing .prism.log entry, with no other changes to the file's contents.
.release-please-manifest.json The version number has been updated from 2.4.0 to 3.0.0-rc1, indicating a potential major version release or release candidate.
.stats.yml The configuration file shows a reduction in configured endpoints from 33 to 30, and updates to the OpenAPI spec URL, spec hash, and config hash values.
CHANGELOG.md The changelog has been updated to include a new version 3.0.0-rc1, which introduces several new features, bug fixes, and chores. Key changes include deprecating some AI tools, adding custom JSON encoder support, and improving binary request streaming and serialization.
CONTRIBUTING.md The changes include updating the mock server reference from Prism to Steady and modifying the mock server setup command from using npx to a local script ./scripts/mock.
README.md The changes include adding environment variables to Cursor and VS Code MCP installation links, and modifying the pip install command from pip install '--pre writer-sdk' to pip install --pre writer-sdk.
api.md The changes include removal of AI detect and context aware splitting tools, consolidation of tools import, and slight restructuring of the tools section with a modified import statement and method references.
pyproject.toml Version updated from 2.4.0 to 3.0.0-rc1, typing-extensions dependency bumped to >=4.14, and format:docs script modified to use bash and find multiple api.md files.
requirements-dev.lock The lockfile was updated with version bumps for several dependencies, including aiohttp from 3.13.2 to 3.13.3, httpx-aiohttp from 0.1.9 to 0.1.12, and ruff from 0.14.7 to 0.14.13, along with minor version updates to other packages.
requirements.lock The lockfile shows version updates for several dependencies, including aiohttp from 3.13.2 to 3.13.3, anyio from 4.12.0 to 4.12.1, certifi from 2025.11.12 to 2026.1.4, and httpx-aiohttp from 0.1.9 to 0.1.12.
scripts/mock The script was updated to replace Prism mock server with Steady mock server, adding pre-installation, specific host and port configuration, health endpoint checking, and more detailed startup timeout and error handling.
src/writerai/_base_client.py The changes include adding new type hints for binary content, introducing warnings for deprecated byte handling, preserving query parameters from URLs, and adding a new JSON serialization utility function. The modifications primarily enhance type safety and request handling in the HTTP client implementation.
src/writerai/_client.py The files are nearly identical, with a minor change in the import order for the resources. Specifically, the order of imported resources in the TYPE_CHECKING block has been slightly rearranged, with no functional difference.
src/writerai/_compat.py Added a new TypedDict _ModelDumpKwargs and modified the model_dump function to support an optional by_alias parameter, with handling for both Pydantic v1 and v2 compatibility.
src/writerai/_models.py The changes include modifications to the import statements, adding support for bytes, bytearray, IO, Iterable, and AsyncIterable types in the FinalRequestOptionsInput and FinalRequestOptions classes, and updating the content attribute type.
src/writerai/_qs.py The file now includes an implementation for the "indices" array format in the _stringify_item method, which adds index-based keys when converting list or tuple values to query string parameters.
src/writerai/_response.py Minor changes to the BaseAPIResponse._parse method, specifically adding the options parameter when initializing stream classes and stream chunk types. The core logic and structure of the file remain largely unchanged.
src/writerai/_streaming.py Added an optional options parameter to Stream and AsyncStream constructors, and imported FinalRequestOptions in the type checking section. The _options attribute is now an optional class attribute for both stream classes.
src/writerai/_types.py The file has been updated to include new type definitions for binary data types, adding BinaryTypes and AsyncBinaryTypes to support raw binary and streaming data in request bodies.
src/writerai/_utils/init.py A new import for path_template from ._path module was added at the beginning of the import list, while all other imports remained unchanged.
src/writerai/_utils/_compat.py A type ignore comment was added to the is_union function for the types.UnionType comparison, addressing potential type checking warnings or errors in the code.
src/writerai/_utils/_json.py A new Python file has been added that defines a custom JSON encoder for serializing objects, with support for datetime and Pydantic models, and includes an openapi_dumps function for converting objects to UTF-8 encoded JSON bytes.
src/writerai/_utils/_path.py A new file has been added that provides a utility function path_template for safely interpolating and percent-encoding URI templates with placeholders, including handling of path, query, and fragment components while preventing dot-segment attacks.
src/writerai/_utils/_utils.py The primary change is in the _extract_items function, specifically in the dictionary handling logic. The condition for removing dictionary keys has been modified to check for array traversal markers more comprehensively.
src/writerai/_version.py Version updated from 2.4.0 to 3.0.0-rc1, indicating a potential release candidate or pre-release version of the package.
src/writerai/resources/applications/applications.py The file now uses path_template() function for constructing URL paths in retrieve() and generate_content() methods, replacing direct string interpolation. This change likely improves URL path generation and potentially adds more robust parameter handling.
src/writerai/resources/applications/graphs.py The file now imports the path_template function and uses it to construct URL paths in the update and list methods for both sync and async graph resources, replacing direct string formatting.
src/writerai/resources/applications/jobs.py The file now uses path_template() for URL generation instead of direct string formatting, which provides a more robust way of constructing API endpoint URLs with dynamic parameters.
src/writerai/resources/files.py The main change is the addition of the path_template() function from .._utils in method calls like retrieve(), delete(), and download(), which replaces direct string formatting of file IDs in URL paths.
src/writerai/resources/graphs.py Added path_template import and replaced hardcoded URL string concatenations with path_template function calls in various method signatures, improving URL generation consistency and readability.
src/writerai/resources/tools.py The file is a newly added Python module for a tools resource, containing synchronous and asynchronous classes for PDF parsing and web searching, with deprecated method annotations and extensive type hinting and parameter support.
src/writerai/resources/tools/init.py The file has been deleted. The previous version contained import statements and exports for Comprehend and Tools resources with various synchronous and asynchronous response types.
src/writerai/resources/tools/comprehend.py The file has been completely deleted. No content remains in the new version of the file, indicating a full removal of the previous implementation of the comprehend medical resource.
src/writerai/types/init.py The file has had two import lines removed: one for ToolAIDetectParams and another for ToolAIDetectResponse, and one line for ToolContextAwareSplittingParams and its corresponding response. No other changes were made to the file.
src/writerai/types/tool_ai_detect_params.py The file has been deleted. It previously contained a TypedDict class definition for ToolAIDetectParams with a required input field and documentation about AI detection content requirements.
src/writerai/types/tool_ai_detect_response.py The file ToolAIDetectResponse has been deleted. The file previously defined a response model with a label literal of "fake" or "real" and a float score attribute.
src/writerai/types/tool_context_aware_splitting_params.py The file has been deleted. The original file contained a TypedDict class definition for ToolContextAwareSplittingParams with strategy and text parameters, specifying splitting strategies for text processing.
src/writerai/types/tool_context_aware_splitting_response.py The file has been deleted. It previously contained a Python class definition for ToolContextAwareSplittingResponse with a list of string chunks and a docstring describing the purpose of the chunks.
src/writerai/types/tools/init.py The file has been deleted. It previously contained import statements for ComprehendMedicalParams and ComprehendMedicalResponse, along with a comment about file generation from an OpenAPI specification.
src/writerai/types/tools/comprehend_medical_params.py The file has been deleted. The original file defined a TypedDict for Comprehend Medical parameters with content and response type fields, specifying medical analysis response structures.
src/writerai/types/tools/comprehend_medical_response.py The file has been completely deleted. The deletion removes all class definitions related to Comprehend Medical response models, including entity, attribute, concept, and trait classes.
ℹ️ Issues Detected

NOTE: These may not require action!

Below are unvalidated results from the Analysis Tools that ran during the latest scan for transparency. We investigate each of these for accuracy and relevance before surfacing them as a potential problem.

How will I know if something is a problem?
When validation completes, any concerns that warrant attention prior to merge will be posted as inline comments. These will show up in 2 ways:

  • Expert review (most cases): Issues will be posted by experts who manually reviewed and validated them. These are real HackerOne engineers (not bots) reviewing through an integrated IDE-like tool. You can communicate with them like any other reviewer. They'll stay assigned and get notified with commit & comment updates.
  • Automatically: In cases where our validation checks have highest confidence the problem is legitimate and urgent. These will include a description of contextual reasoning why & actionable next steps.
File & Line Issue
README.md Line 16 The changed lines on 16 and 17 embed a placeholder API key value ('My API Key') directly into MCP deep-link URLs that are publicly visible in the README. Specifically, the base64/URL-encoded config parameters now include "WRITER_API_KEY":"My API Key" in the Cursor deep-link (line 16) and "WRITER_API_KEY":"My%20API%20Key" in the VS Code deep-link (line 17). While 'My API Key' is clearly a placeholder and not a real credential, this pattern normalizes embedding API keys directly into clickable install links. If a real key were accidentally substituted here (e.g., during a copy-paste or templating error), it would be publicly exposed in version control and the published README. This is a credential exposure risk pattern that should be avoided; the links should instead instruct users to set the environment variable separately rather than encoding it into the deep-link config.
src/writerai/resources/files.py Line 84 The path_template function is used to interpolate user-supplied file_id values directly into URL paths (e.g., /v1/files/{file_id}, /v1/files/{file_id}/download). If path_template does not properly encode or sanitize the file_id value, a caller could supply a crafted file_id containing path traversal sequences (e.g., ../admin) or URL-encoded characters that alter the intended API path. While there is a non-empty check (if not file_id), this does not prevent path traversal or injection. The security of this pattern depends entirely on whether path_template performs URL-encoding of the substituted values. If it does not, this introduces a URL path injection / path traversal risk. This affects all four changed call sites: retrieve (line 84), delete (line 192), download (line 228), and their async counterparts (lines 372, 480, 516).
src/writerai/resources/graphs.py Line 133 The change replaces direct f-string URL construction (e.g., f"/v1/graphs/{graph_id}") with calls to path_template("/v1/graphs/{graph_id}", graph_id=graph_id). The security impact depends entirely on the implementation of path_template in .._utils. If path_template does not properly URL-encode/percent-encode the substituted values, a caller-supplied graph_id or file_id containing path-separator characters (e.g., ../, /) could manipulate the resulting URL path, potentially targeting unintended API endpoints (path traversal / URL manipulation). The previous f-string approach had the same weakness, but the introduction of a new utility function that is not shown in this diff makes it worth flagging for review to confirm that path_template applies proper URL encoding to all substituted values.
🧰 Analysis tools

⏱️ Latest scan covered changes up to commit e000ecd (latest)

@hackerone-code
Copy link
Copy Markdown

hackerone-code Bot commented Apr 9, 2026

✅ Graham C reviewed all the included code changes and associated automation findings and determined that there were no immediately actionable security flaws. Note that they will continue to be notified of any new commits or comments and follow up as needed throughout the duration of this pull request's lifecycle.

Image of Graham C Graham C


Reviewed with ❤️ by HackerOne Code

…are Text Splitting

Remove AI Detection, Medical Comprehend, text to graph, and Context-Aware Text Splitting from SDKs.
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 7431f87 to 79972e3 Compare April 9, 2026 19:46
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 79972e3 to 87d59e2 Compare April 9, 2026 20:18
@hackerone-code
Copy link
Copy Markdown

hackerone-code Bot commented Apr 9, 2026

HackerOne Code reviewed the updates made to #253 up until the latest commit (87d59e2). No further issues were found.

Reviewed by:

Image of Graham C Graham C

@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 87d59e2 to d28e7e2 Compare April 10, 2026 15:01
@hackerone-code
Copy link
Copy Markdown

HackerOne Code reviewed the updates made to #253 up until the latest commit (d28e7e2). No further issues were found.

Reviewed by:

Image of Graham C Graham C

@adeweaver adeweaver changed the title release: 2.5.0 release: 3.0.0 Apr 13, 2026
@stainless-app
Copy link
Copy Markdown
Contributor Author

stainless-app Bot commented Apr 13, 2026

Release version edited manually

The Pull Request version has been manually set to 3.0.0 and will be used for the release.

If you instead want to use the version number 2.5.0 generated from conventional commits, just remove the label autorelease: custom version from this Pull Request.

@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from d28e7e2 to 0c46b8d Compare April 13, 2026 18:24
@adeweaver adeweaver changed the title release: 3.0.0 release: 3.0.0-rc1 Apr 13, 2026
@stainless-app stainless-app Bot force-pushed the release-please--branches--main--changes--next branch from 0c46b8d to e000ecd Compare April 13, 2026 20:01
@adeweaver adeweaver merged commit 1ebd7bb into main Apr 13, 2026
11 checks passed
@adeweaver adeweaver deleted the release-please--branches--main--changes--next branch April 13, 2026 20:14
@stainless-app
Copy link
Copy Markdown
Contributor Author

stainless-app Bot commented Apr 13, 2026

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants