Accept legacy request field names alongside new canonical ones (fixes asset-level force_new_job_creation gap)#2352
Open
Flix6x wants to merge 2 commits into
Open
Conversation
Adds a shared `SupportsLegacyFieldAliases` pre_load mixin (flexmeasures/data/schemas/utils.py) and applies it so several request fields now accept both spellings without breaking existing clients: - `force_new_job_creation` / `force-new-job-creation` on the asset-level scheduling trigger (previously only the sensor-level endpoint accepted both; this is what flexmeasures-client#218 had to work around client-side with server-version sniffing). - `per_page`/`per-page`, `sort_by`/`sort-by`, `sort_dir`/`sort-dir` on all paginated list endpoints. - `account_id`/`account` and `asset_id`/`asset` on GET /sensors, GET /assets, GET /users query filters. Response fields still need explicit dual-field output for backward compatibility (can't "accept either" on the way out), but request fields don't -- this generalizes the one-off alias hook that already existed for source-account/source-type filtering, so future field renames on the request side can ship immediately, without waiting for a new API version. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Documentation build overview
|
_apply_legacy_field_aliases unconditionally rebuilt the incoming request data into a plain dict, even when none of its declared legacy aliases were present. That silently broke AssetTriggerSchema.normalize_flex_context_format, which detects a multi-commodity flex-context list via MultiDict.getlist() -- CI caught this via test_asset_trigger_with_multi_commodity_flex_context failing (the scheduling job never finished, since flex-context normalization saw a single dict instead of the intended commodities list). Now the hook only rebuilds `data` when one of its own legacy keys is actually present, leaving MultiDict-like inputs untouched otherwise. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Follow-up to the API v4 discussion (#2349): for request fields (unlike response fields), a legacy field name can keep working immediately, without waiting for a new API version — a client can accept both spellings via a
@pre_loadhook. This PR generalizes a pattern that already existed for exactly one schema and applies it to close a real, confirmed gap.The concrete bug this fixes
POST /assets/<id>/schedules/trigger(AssetTriggerSchema) never accepted the legacyforce_new_job_creationfield name — onlyforce-new-job-creation. The sensor-level trigger endpoint already had this backward-compat shim (added in #2182), but it was never applied to the asset-level one.This is exactly why flexmeasures-client#218 had to add client-side server-version sniffing to decide which field name to send — its own PR description documents the asset endpoint returning a 422 when sent the legacy key. With this fix, the server accepts both, and that client-side workaround becomes unnecessary (flexmeasures-client does not need to be updated for this PR to be compatible).
What changed
SupportsLegacyFieldAliases, a small@pre_loadmixin (flexmeasures/data/schemas/utils.py), generalizing the one-off alias hook that already existed inGetSensorDataFilterSchemaMixin(sensor_data.py) forsource-account/source-type. A schema declareslegacy_field_aliases = {"old_key": "new-data-key"}and both spellings are accepted; only the canonical one is deserialized.AssetTriggerSchema.force_new_job_creation→force-new-job-creation(the actual bug fix above).TriggerScheduleKwargsSchema.force_new_job_creation(sensor-level) — replaced its hand-rolled equivalent with the shared mixin, no behavior change.PaginationSchema:per_page/sort_by/sort_dirnow also acceptper-page/sort-by/sort-dir(used by every paginated list endpoint).AssetAPIQuerySchema,UserAPIQuerySchema,SensorKwargsSchema:account_id/asset_idnow also acceptaccount/asset(candidate canonical names from the naming policy in #2127).PaginationSchemasubclasses (AssetPaginationSchema,AssetAuditLogPaginationSchema,UserAuditlogSchema,AccountAPIQuerySchema) were overridingsort_by/sort_dirwithout the parent'sdata_key, silently losing the hyphenated spelling — fixed as part of this pass.documentation/api/change_log.rst.What this doesn't do
Response fields aren't touched here — a response can't "accept either" key, so response-side backward compatibility means including both keys in the output (as #2224/#2350 did for
job/schedule). That's a separate, larger effort tracked in #2349 forgeneric_asset_id,flex_model/flex_context,consultancy_account_id,parent_asset_id, and the account color/logo fields.How to test
force_new_job_creationbackward-compat tests (test_sensor_schedules_fresh_db.py) continue to cover that field via the now-shared mixin._apply_legacy_field_aliasesfor all affected schemas (PaginationSchemaand its subclasses,AssetAPIQuerySchema,UserAPIQuerySchema,SensorKwargsSchema,AssetTriggerSchema) — legacy keys map to the correct canonicaldata_key.force_new_job_creationfix specifically; flagging that as a gap — happy to add one if desired.docker-qa.yml) against this branch withflexmeasures-client-ref=main(unmodified), to confirm the HEMS walkthrough and tutorials still pass without any client-side changes.