Skip to content

Regenerate SDK from server specification version 1.88.0 - #114

Open
bradymholt wants to merge 3 commits into
mainfrom
brady/openapi-codegen-pr-4af253
Open

bradymholt wants to merge 3 commits into
mainfrom
brady/openapi-codegen-pr-4af253

Conversation

@bradymholt

@bradymholt bradymholt commented Nov 2, 2026 •

Copy link
Copy Markdown
Member

This regenerates the client from YNAB API spec 1.88.0 (previously 1.86.0) and bumps the version to 5.0.0.

The spec change deprecates import_transactions, which now raises a DeprecationWarning and no longer maps a 201 response. The rest is description updates for goal fields on loan-paired categories and split rules.

Worth a close look: openapi-generator moved from 7.23.0 to 7.27.0, which accounts for most of the diff. api_client.py now merges headers case-insensitively, lowercases booleans in query strings, and falls back to a default response type. Every model's to_dict now emits an explicit null for any nullable field explicitly set to None, where it previously omitted the field. On update requests this clears a value that used to be left unchanged, for example ExistingTransaction(memo=None) or ExistingCategory(note=None), hence the major bump. Fields that are not passed are still omitted, including with from_dict/from_json, which a new model_generic.mustache override limits to keys present in the input. The null behavior needs a hand-written note in the release notes. __version__ and the User-Agent, stale at 4.2.0, now match 5.0.0.

Regenerated the client from the YNAB API spec 1.88.0 (previously 1.86.0)
using openapi-generator 7.27.0 (previously 7.23.0), and bumped the
package version to 4.5.0.
@bradymholt
bradymholt marked this pull request as ready for review November 2, 2026 14:07
@bradymholt
bradymholt requested review from a team and ytakane and removed request for a team November 2, 2026 14:09

@ytakane ytakane left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, it may take me a bit to get through this a-hem 1000 LOC PR. But for now I sicced Claude on it and it came up with these comments. I'll work on a human review later today or tomorrow.

_dict['subtransactions'] = _items
# set to None if payee_id (nullable) is None
# and model_fields_set contains the field
if self.payee_id is None and "payee_id" in self.model_fields_set:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These new null checks key off model_fields_set, but from_dict (and from_json, which calls it) passes every field to model_validate via obj.get(...). A missing key comes through as an explicit None, so pydantic counts it as set.

That means ExistingTransaction.from_dict({"amount": -5000}) will now send payee_id, payee_name, category_id and memo as null, which clears them on the transaction. flag_color already behaves this way on main, so it's the same mechanism, just on more fields now. The same goes for ExistingCategory (note, goal_target, etc.) and the other request models.

The description says fields that aren't passed are still omitted. That's true for keyword construction, but not for from_dict/from_json, and the generated model docs show both as ways to build these. I think this needs either a template override so from_dict only passes keys that are actually present, or a clear breaking-change callout (see my comment on the version).

@bradymholt bradymholt Nov 2, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call. Added a model_generic.mustache override so from_dict only passes keys present in the input to model_validate, and regenerated, in 94afa25. ExistingTransaction.from_dict({"amount": -5000}).to_dict() is now {"amount": -5000}, which also fixes the existing flag_color case. An explicit "memo": None still sends null.

Comment thread pyproject.toml Outdated
name = "ynab"
version = "4.4.1"
description = "Official Python client for the YNAB API. API documentation available at https://api.ynab.com. Generated from server specification version 1.86.0"
version = "4.5.0"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm concerned a minor bump undersells this one. Update requests can now clear values that 4.4.1 left alone, both for anyone passing None explicitly and for anyone building request models with from_dict/from_json. Would 5.0.0 make sense here (scripts/generate.sh major)?

Also, the GitHub release notes are built from PR titles, so the null behavior note won't show up there unless it's added by hand when publishing.

@bradymholt bradymholt Nov 2, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, you're right. Bumped to 5.0.0 in d8af999, since passing None explicitly on an update request now clears values that 4.4.1 left unchanged. I'll add the null behavior note to the release notes by hand when publishing.

from_dict passed obj.get() for every field, so a missing key came
through as an explicit None and counted as set. to_dict then sent null
for it, clearing values on update requests built from a dict.
Passing None explicitly on an update request now sends null and clears
the value, where 4.4.1 left it unchanged. That breaks existing callers
silently, so it needs a major version.
@bradymholt
bradymholt requested a review from ytakane November 2, 2026 18:50
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.

2 participants