From e97ef9a890e225670af117ccce559886fac48302 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Thu, 10 Sep 2026 11:30:01 +0100 Subject: [PATCH] Avoid Snapper role-continuation bug --- .snapperrc.toml | 5 -- docs/source/differences-to-vws.rst | 89 ++++++++++-------------------- 2 files changed, 29 insertions(+), 65 deletions(-) delete mode 100644 .snapperrc.toml diff --git a/.snapperrc.toml b/.snapperrc.toml deleted file mode 100644 index fa79f32df..000000000 --- a/.snapperrc.toml +++ /dev/null @@ -1,5 +0,0 @@ -# https://github.com/TurtleTech-ehf/snapper/issues/126 -# This file contains an RST bullet continuation that Snapper does not yet preserve. -ignore = [ - "docs/source/differences-to-vws.rst", -] diff --git a/docs/source/differences-to-vws.rst b/docs/source/differences-to-vws.rst index f80ff948e..4003332e3 100644 --- a/docs/source/differences-to-vws.rst +++ b/docs/source/differences-to-vws.rst @@ -34,8 +34,7 @@ Sometimes the real summary skips image states such as the processing state. The mock is accurate immediately with regards to images. The mock does not count recognitions. -Real Vuforia's recognition counts lag behind its queries by far longer than a -test runs, so a query in the mock does not change any count either. +Real Vuforia's recognition counts lag behind its queries by far longer than a test runs, so a query in the mock does not change any count either. Set the counts you want to see instead: :paramref:`mock_vws.database.CloudDatabase.total_recos`, :paramref:`mock_vws.database.CloudDatabase.current_month_recos`, @@ -44,10 +43,8 @@ Set the counts you want to see instead: summary report, and :meth:`mock_vws.MockVWS.set_target_recognition_counts` for the counts of a target, which the target summary report and the reco counts report show. -Targets are created by API requests, so their counts are set after the target -is created. -The Flask and Docker mock has an equivalent target manager endpoint, described -in :doc:`docker`. +Targets are created by API requests, so their counts are set after the target is created. +The Flask and Docker mock has an equivalent target manager endpoint, described in :doc:`docker`. Image quality and ratings ------------------------- @@ -231,8 +228,8 @@ Vuforia also documents that ``GET /targets`` fails for databases with more than Configurable Cloud Query failures --------------------------------- -The Vuforia Cloud Query API documents failure responses with JSON, arbitrary -content, or no body. Use +The Vuforia Cloud Query API documents failure responses with JSON, arbitrary content, or no body. +Use :paramref:`mock_vws.MockVWS.cloud_query_failure_response` to make every Cloud Query request return a particular documented failure shape through the in-process ``requests``, ``httpx`` and ``httpx2`` backends:: @@ -297,20 +294,14 @@ The other three come from Vuforia's result codes table rather than from a respon * ``TargetQuotaReached`` is returned when adding a target to a :class:`mock_vws.database.CloudDatabase` which already contains ``target_quota`` targets. -* ``ProjectSuspended`` is returned with status code 403 by every VWS endpoint - when a database uses the +* ``ProjectSuspended`` is returned with status code 403 by every VWS endpoint when a database uses the :attr:`mock_vws.states.States.PROJECT_SUSPENDED` state. - Real Vuforia has returned this result code for a database which passed its - monthly recognition threshold, but its status code, body and headers were - not recorded, and reads such as ``GET /targets`` and the database summary - kept working there. + Real Vuforia has returned this result code for a database which passed its monthly recognition threshold, but its status code, body and headers were not recorded, and reads such as ``GET /targets`` and the database summary kept working there. * ``ProjectHasNoApiAccess`` is returned by VWS endpoints when a database uses the :attr:`mock_vws.states.States.PROJECT_HAS_NO_API_ACCESS` state. This casing comes from Vuforia's result codes table, as no response from a real database in this state has been seen. ``vws-python`` and ``vws-cli`` map this result code by the ``ProjectHasNoAPIAccess`` spelling, so they do not recognize this response until they are updated. -* ``TooManyRequests`` is returned when a - :class:`mock_vws.database.CloudDatabase` exceeds a configured request rate - limit. Set ``requests_per_second_limit`` to ``0`` to return this result code - for every VWS request. +* ``TooManyRequests`` is returned when a :class:`mock_vws.database.CloudDatabase` exceeds a configured request rate limit. + Set ``requests_per_second_limit`` to ``0`` to return this result code for every VWS request. ``Content-Length`` headers -------------------------- @@ -328,39 +319,25 @@ Model Target datasets --------------------- The Model Target Web API mock supports OAuth2 token requests, standard and advanced dataset creation, status polling, dataset downloads, and deletion. -The generated dataset download is a small valid ``full-dataset.zip`` with the -same ``MTDataset.dat`` and ``MTDataset.xml`` filenames as Vuforia. Its contents -are synthetic request metadata and minimal XML, not a real Vuforia Engine -Model Target dataset. -Use :paramref:`mock_vws.MockVWS.model_target_generation_failure` to make -in-process Model Target datasets finish with a ``failed`` status and an -``error`` object. The failure is returned after the configured +The generated dataset download is a small valid ``full-dataset.zip`` with the same ``MTDataset.dat`` and ``MTDataset.xml`` filenames as Vuforia. +Its contents are synthetic request metadata and minimal XML, not a real Vuforia Engine Model Target dataset. +Use :paramref:`mock_vws.MockVWS.model_target_generation_failure` to make in-process Model Target datasets finish with a ``failed`` status and an ``error`` object. +The failure is returned after the configured :paramref:`~mock_vws.MockVWS.processing_time_seconds`, so callers can test -both processing and failed states. This configuration is not supported by the -Flask/Docker backend. +both processing and failed states. +This configuration is not supported by the Flask/Docker backend. Use :paramref:`mock_vws.MockVWS.model_target_training_allowance_exceeded` to make -in-process Model Target dataset creation return Vuforia's -``TRAINING_ALLOWANCE_EXCEEDED`` response. Set the +in-process Model Target dataset creation return Vuforia's ``TRAINING_ALLOWANCE_EXCEEDED`` response. +Set the :envvar:`MODEL_TARGET_TRAINING_ALLOWANCE_EXCEEDED` environment variable to -``true`` to configure the same response in the Flask/Docker backend. -Use :paramref:`mock_vws.MockVWS.model_target_generation_warning` to make -successful in-process Model Target datasets include a Vuforia-shaped -``warning`` object after processing completes. This configuration is not -supported by the Flask/Docker backend. -Model Target API routes require a three-part JSON Web Token with JSON object -header and payload parts, a non-``none`` ``alg`` value, and a non-empty -base64url-encoded signature, such as the token returned by the mock OAuth2 -route. -The mock does not verify token signatures, payload claims such as expiry, or -token revocation. -The OAuth2 route supports both the ``client_credentials`` and ``password`` -grants. Tokens returned by the mock contain explicit scopes, and -standard and advanced dataset routes require their corresponding Model Target -scope. A token carrying ``modeltargets.all`` can access both route families. -The OAuth2 client-credentials management routes support creating, listing, -updating and deleting credentials, including Vuforia's limit of 100 created -credentials per account. +``true`` to configure the same response in the Flask/Docker backend. Use :paramref:`mock_vws.MockVWS.model_target_generation_warning` to make successful in-process Model Target datasets include a Vuforia-shaped ``warning`` object after processing completes. This configuration is not supported by the Flask/Docker backend. +Model Target API routes require a three-part JSON Web Token with JSON object header and payload parts, a non-``none`` ``alg`` value, and a non-empty base64url-encoded signature, such as the token returned by the mock OAuth2 route. +The mock does not verify token signatures, payload claims such as expiry, or token revocation. +The OAuth2 route supports both the ``client_credentials`` and ``password`` grants. +Tokens returned by the mock contain explicit scopes, and standard and advanced dataset routes require their corresponding Model Target scope. +A token carrying ``modeltargets.all`` can access both route families. +The OAuth2 client-credentials management routes support creating, listing, updating and deleting credentials, including Vuforia's limit of 100 created credentials per account. Dataset creation request bodies which are valid JSON but not JSON objects are reported as missing every required top-level field. Dataset creation request bodies which cannot be decoded as UTF-8 are reported as invalid JSON, as malformed JSON bodies are. @@ -422,12 +399,8 @@ As with real Vuforia, the report is served with a ``text/plain`` content type ra Real Vuforia assigns a database an ID, which the target manager shows. The ID of a database in the mock is :paramref:`mock_vws.database.CloudDatabase.database_id`, which defaults to a -random string, so the path of a request to this endpoint is built by reading -that attribute rather than by looking the ID up. -As real Vuforia does, the mock returns a 401 response with the -``AuthenticationFailure`` result code for a request which is signed with valid -server keys but which names any other database, including one named by its -name rather than by its ID. +random string, so the path of a request to this endpoint is built by reading that attribute rather than by looking the ID up. +As real Vuforia does, the mock returns a 401 response with the ``AuthenticationFailure`` result code for a request which is signed with valid server keys but which names any other database, including one named by its name rather than by its ID. Real Vuforia returns a presigned URL for cloud storage, of this form: @@ -442,15 +415,11 @@ Real Vuforia returns a presigned URL for cloud storage, of this form: &X-Amz-Expires=604799 &X-Amz-Signature=... -The mock returns a URL with the same path and the same query parameters, -served by the mock itself rather than by cloud storage. +The mock returns a URL with the same path and the same query parameters, served by the mock itself rather than by cloud storage. The URL returned by the Flask and Docker mock is built from the :envvar:`VWS_BASE_URL` environment variable. -The credential, the security token and the signature are placeholders of -the right shape. -The mock does not check the signature, so a URL whose signature or file name -has been changed, which real Vuforia refuses with a ``SignatureDoesNotMatch`` -error document, is served by the mock as if it were signed. +The credential, the security token and the signature are placeholders of the right shape. +The mock does not check the signature, so a URL whose signature or file name has been changed, which real Vuforia refuses with a ``SignatureDoesNotMatch`` error document, is served by the mock as if it were signed. Real Vuforia names the report file after the requested month, and does so differently for each of the two months it accepts. A report for the current month is named for the UTC date and hour, such as ``2026-08-08-21.csv``, and a report for the previous month is named for the month, such as ``2026-07.csv``.