Skip to content

Add typed response models and fix retrieve_enhanced_track key name bug#5

Merged
daveronan merged 4 commits into
masterfrom
fix-docs
Apr 22, 2026
Merged

Add typed response models and fix retrieve_enhanced_track key name bug#5
daveronan merged 4 commits into
masterfrom
fix-docs

Conversation

@daveronan
Copy link
Copy Markdown
Collaborator

@daveronan daveronan commented Apr 22, 2026

Summary

  • Bug fix (key name): retrieve_enhanced_track was using revived_track_tasks_results (snake_case) to read the server response, but the server returns revivedTrackTaskResults (camelCase). This silently broke the primary extraction path, causing the method to always fall through to a slower fallback or fail entirely.
  • Bug fix (polling): retrieve_enhanced_track polling exited early on 202 responses because revivedTrackTaskResults was present (with null URLs). Now checks that at least one download URL is populated before treating the task as complete.
  • Typed responses: All 7 retrieval methods (retrieve_enhanced_track, retrieve_preview_mix, retrieve_final_mix, retrieve_final_mix_advanced, retrieve_preview_master, retrieve_final_master, analyze_mix) now return typed dataclasses instead of raw dict. New models: EnhancedTrackResult, PreviewMixResult, FinalMixResult, PreviewMasterResult, FinalMasterResult, AnalysisResult.
  • Docstring rewrite: Replaced inaccurate/fabricated docstrings across all retrieval methods with accurate field-level documentation matching actual server responses (including the previously undocumented preview_start_time field).
  • Examples & tests updated: All example scripts, integration tests, and the smoke test updated from dict .get() access to typed attribute access.

Test plan

  • 142 unit tests pass (pytest tests/unit/ -q)
  • Smoke test passes against live API (import, enums, health, upload, analysis, enhance preview)
  • All 5 runnable examples verified end-to-end against live API:
    • upload_example.py — file uploaded
    • analysis_example.py — full analysis with metrics returned
    • enhance_example.py — preview + full enhancement + 4 stems downloaded
    • mastering_example.py — preview + final master downloaded
    • audio_cleanup_example.py — cleaned audio downloaded
  • mix_example.py / advanced_mix_example.py imports verified (require multiple audio files)
  • New response dataclasses JSON-serializable via dataclasses.asdict()
  • Version bumped to 1.3.2, CHANGELOG updated

Note

Medium Risk
Public return types change from dict to dataclasses across multiple controllers, which can break downstream callers and subtly alter fallback parsing behavior.

Overview
Adds typed response models and normalizes retrieval parsing across the SDK. The mix, mastering, enhance, and analysis retrieval methods now return dedicated dataclasses (PreviewMixResult, FinalMixResult, PreviewMasterResult, FinalMasterResult, EnhancedTrackResult, AnalysisResult) instead of raw dicts, and examples/tests were updated to use attribute access (plus asdict() for JSON serialization).

Fixes an enhance retrieval bug and cleans up API response handling/docs. retrieve_enhanced_track now reads the correct server key (revivedTrackTaskResults), polling/parsing logic in several controllers was simplified to extract the expected nested result objects, and docstrings were rewritten to match actual response shapes (including preview_start_time). Version bumped to 1.3.2 with changelog updates.

Reviewed by Cursor Bugbot for commit aee61d0. Bugbot is set up for automated code reviews on this repo. Configure here.

Dave Ronan added 3 commits April 22, 2026 12:26
- Fix retrived_track_tasks_results -> revivedTrackTaskResults (camelCase)
  in enhance_controller.py, which silently broke the primary extraction path
- Add 6 typed response dataclasses: EnhancedTrackResult, PreviewMixResult,
  FinalMixResult, PreviewMasterResult, FinalMasterResult, AnalysisResult
- Update all 7 retrieval methods to return typed models instead of raw dicts
- Rewrite inaccurate docstrings to reflect actual server response shapes
- Update unit tests for new return types and corrected key names
- Bump version to 1.3.2

Made-with: Cursor
All example scripts still used .get() / [] on return values that are
now dataclass instances (EnhancedTrackResult, PreviewMasterResult, etc).
Updated to use attribute access (.download_url_revived, .payload, etc).

Made-with: Cursor
- advanced_mix_example.py: use .download_url_preview_mixed / .download_url_mixed
- test_mastering_integration.py: use .download_url_mastered_preview attribute
- test_analysis_integration.py: use .payload attribute instead of dict .get()
- smoke_test.py: bump version assertion to 1.3.2, use .payload on AnalysisResult

Made-with: Cursor
Comment thread tests/unit/test_controllers/test_mix_controller.py
The API returns revivedTrackTaskResults with null download URLs in 202
(still processing) responses. The polling loop treated any truthy dict
as completion, causing retrieve_enhanced_track to return an
EnhancedTrackResult with all None fields. Now checks that at least one
download URL is populated before considering the task complete.

Made-with: Cursor
@daveronan daveronan merged commit 1415595 into master Apr 22, 2026
1 check passed
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit aee61d0. Configure here.

else:
# If the response doesn't indicate it's processing, return it as is
return response
return _parse_preview_result(response)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Early return silently drops nested preview mix results

Low Severity

When the API returns previewMixTaskResults with completed data but without a top-level status key, the first condition (line 157) fails because response.get("status") is None. The second condition (line 161) also fails because "status" not in response. The else branch then calls _parse_preview_result(response) on the outer response dict, which only looks for download_url_preview_mixed etc. at the top level — missing the data nested inside previewMixTaskResults. This returns an empty PreviewMixResult and skips polling entirely. The old code returned the raw response dict, which at least preserved the nested data for callers to inspect.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit aee61d0. Configure here.

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