Skip to content

Add VuMark Generation API endpoint (#473)#2878

Closed
adamtheturtle wants to merge 14 commits intomainfrom
adamtheturtle/remove-mock-prefix
Closed

Add VuMark Generation API endpoint (#473)#2878
adamtheturtle wants to merge 14 commits intomainfrom
adamtheturtle/remove-mock-prefix

Conversation

@adamtheturtle
Copy link
Member

@adamtheturtle adamtheturtle commented Jan 28, 2026

Implements POST /targets/<target_id>/instances endpoint for generating VuMark instance images in SVG, PNG, or PDF format. Includes validators, exception classes, image generators, and comprehensive test coverage for both requests-mock and Flask implementations.

Closes #473

🤖 Generated with Claude Code


Note

Medium Risk
Adds a new API endpoint returning binary payloads (SVG/PNG/PDF) and introduces new validation/error paths plus new target_type/default_target_type fields that affect target/database serialization and test fixtures.

Overview
Implements POST /targets/{target_id}/instances (VuMark Generation API) across both the Flask app and the responses/requests-mock backend, returning placeholder image/svg+xml, image/png, or application/pdf content based on the Accept header and validating instance_id, target type, and target success status.

Extends the data model to support VuMark targets by adding default_target_type to VuforiaDatabase and target_type to Target (propagated through target/database creation/serialization), adds new validator exceptions/result codes for invalid Accept/header/instance/target type, updates target-id parsing to handle /targets/{id}/instances, and adds comprehensive tests + CI matrix entries (plus minor vulture/spellcheck updates).

Written by Cursor Bugbot for commit fc1e301. This will update automatically on new commits. Configure here.

Implement POST /targets/<target_id>/instances endpoint for generating
VuMark instance images in SVG, PNG, or PDF format. Includes validators,
exception classes, image generators, and comprehensive test coverage for
both requests-mock and Flask implementations.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Address mypy type checking issues in vumark implementation:
- Use keyword arguments for PIL Image/ImageDraw methods
- Add proper type annotation for accept_header variable
- Use str(object=...) syntax for strict type checking

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Add 'svg' to spelling dictionary and fix 'pdf' to 'PDF' in comments
to pass pylint spell checking.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
Use the standard test pattern with the verify_mock_vuforia fixture so
tests run against all backends (real, mock, docker). Add test classes
to the CI matrix in test.yml.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- PNG: Use white background (was black, making text invisible)
- SVG: Escape instance_id with xml.sax.saxutils.escape to prevent
  malformed XML from special characters
- PDF: Compute stream length, xref offsets, and startxref dynamically
  instead of hardcoding them. Escape PDF string literal characters.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Return exc.response_text as str (consistent with all other endpoints)
instead of encoding to bytes on error paths.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Real Vuforia returns 422 InvalidTargetType because the test targets
are regular image targets, not VuMark targets. Use mock_only_vuforia
to skip real Vuforia backend.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
return requests.post(url=url, data=content, headers=headers, timeout=30)


@pytest.mark.usefixtures("mock_only_vuforia")
Copy link
Member Author

Choose a reason for hiding this comment

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

This needs to not be mock-only

"""Tests for successful VuMark instance generation."""

@pytest.fixture
def vuforia_database( # pylint: disable=no-self-use
Copy link
Member Author

Choose a reason for hiding this comment

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

Instead, let's have a conftest.py fixture for a vucloud dataabse

pyproject.toml Outdated
"@*APP.route",
"@*APP.before_request",
"@*APP.errorhandler",
# requests-mock server
Copy link
Member Author

Choose a reason for hiding this comment

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

Not sure why we need this

Copy link

@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 2 potential issues.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

vucloud_database: VuforiaDatabase,
) -> VuforiaDatabase:
"""Use a VuCloud database for VuMark generation tests."""
return vucloud_database
Copy link

Choose a reason for hiding this comment

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

Circular fixture dependency in TestSuccessfulGeneration class

High Severity

The class-level vuforia_database fixture depends on vucloud_database (from conftest), which in turn depends on vuforia_database. Pytest resolves all fixture dependencies from the test's scope, so vucloud_database's vuforia_database parameter resolves to the class-level override — creating a circular dependency. The other test classes (TestTargetStatusNotSuccess, TestResponseHeaders) avoid this by using the self-referencing pattern def vuforia_database(self, vuforia_database), which pytest special-cases to resolve to the outer scope.

Additional Locations (1)

Fix in Cursor Fix in Web

_ROUTES: set[Route] = set()

_ResponseType = tuple[int, Mapping[str, str], str]
_ResponseType = tuple[int, Mapping[str, str], str | bytes]
Copy link

Choose a reason for hiding this comment

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

_ResponseType in decorators not updated for bytes

Medium Severity

The _ResponseType in mock_web_services_api.py was updated to str | bytes to support the vumark endpoint returning binary content, but the corresponding _ResponseType in decorators.py still uses str. The _Callback type and wrapped function's return annotation in _wrap_callback incorrectly claim only str bodies are supported. This type mismatch could cause static type checker failures and is misleading.

Fix in Cursor Fix in Web

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.

Add VuMark Generation API

1 participant