From 0826fc00957be76048b1fb7c4262c222ccdde12d Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 17 Feb 2026 08:37:38 +0000 Subject: [PATCH 1/6] Use upload_vumark_template for VuMark target ID --- admin/create_secrets_files.py | 91 ++++++++++++++++++++++++++++++++--- pyproject.toml | 2 +- vuforia_secrets.env.example | 1 + 3 files changed, 87 insertions(+), 7 deletions(-) diff --git a/admin/create_secrets_files.py b/admin/create_secrets_files.py index a5c68238a..30e1b7d67 100644 --- a/admin/create_secrets_files.py +++ b/admin/create_secrets_files.py @@ -6,6 +6,7 @@ import datetime import os import sys +import tempfile import textwrap from pathlib import Path from typing import TYPE_CHECKING @@ -32,6 +33,15 @@ reraise=True, ) +VUMARK_TEMPLATE_SVG = textwrap.dedent( + text="""\ + + + + + """, +) + def _create_and_get_database_details( driver: "WebDriver", @@ -87,6 +97,7 @@ def _generate_secrets_file_content( database_details: "DatabaseDict", vumark_details: "VuMarkDatabaseDict", inactive_database_details: "DatabaseDict", + vumark_target_id: str, ) -> str: """Generate the content of a secrets file.""" return textwrap.dedent( @@ -104,12 +115,65 @@ def _generate_secrets_file_content( INACTIVE_VUFORIA_CLIENT_SECRET_KEY={inactive_database_details["client_secret_key"]} VUMARK_VUFORIA_TARGET_MANAGER_DATABASE_NAME={vumark_details["database_name"]} + VUMARK_VUFORIA_TARGET_ID={vumark_target_id} VUMARK_VUFORIA_SERVER_ACCESS_KEY={vumark_details["server_access_key"]} VUMARK_VUFORIA_SERVER_SECRET_KEY={vumark_details["server_secret_key"]} """, ) +def _create_and_get_vumark_target_id( + driver: "WebDriver", + vumark_database_name: str, + vumark_template_name: str, +) -> str: + """Upload a VuMark template and get its target ID.""" + with tempfile.TemporaryDirectory() as temporary_directory: + svg_file_path = Path(temporary_directory) / "template.svg" + svg_file_path.write_text( + data=VUMARK_TEMPLATE_SVG, + encoding="utf-8", + ) + upload_result = RETRY_ON_TIMEOUT(vws_web_tools.upload_vumark_template)( + driver=driver, + database_name=vumark_database_name, + svg_file_path=svg_file_path, + template_name=vumark_template_name, + width=100.0, + ) + + if isinstance(upload_result, str): + return upload_result + + if isinstance(upload_result, dict): + target_id = upload_result.get("target_id") + if isinstance(target_id, str): + return target_id + + target_id = getattr(upload_result, "target_id", None) + if isinstance(target_id, str): + return target_id + + msg = ( + "Expected `upload_vumark_template` to return a target ID. " + "Upgrade `vws-web-tools` to a version that returns one." + ) + raise RuntimeError(msg) + + +def _create_vuforia_resource_names() -> tuple[str, str, str, str]: + """Create names for Vuforia resources.""" + time = datetime.datetime.now(tz=datetime.UTC).strftime( + format="%Y-%m-%d-%H-%M-%S", + ) + return ( + f"my-license-{time}", + f"my-database-{time}", + f"my-vumark-database-{time}", + f"my-vumark-template-{time}", + ) + + def main() -> None: """Create secrets files.""" email_address = os.environ["VWS_EMAIL_ADDRESS"] @@ -146,12 +210,12 @@ def main() -> None: driver = vws_web_tools.create_chrome_driver() file = files_to_create[-1] sys.stdout.write(f"Creating database {file.name}\n") - time = datetime.datetime.now(tz=datetime.UTC).strftime( - format="%Y-%m-%d-%H-%M-%S", - ) - license_name = f"my-license-{time}" - database_name = f"my-database-{time}" - vumark_database_name = f"my-vumark-database-{time}" + ( + license_name, + database_name, + vumark_database_name, + vumark_template_name, + ) = _create_vuforia_resource_names() try: database_details = _create_and_get_database_details( @@ -182,6 +246,20 @@ def main() -> None: driver = None continue + try: + vumark_target_id = _create_and_get_vumark_target_id( + driver=driver, + vumark_database_name=vumark_database_name, + vumark_template_name=vumark_template_name, + ) + except TimeoutException: + sys.stderr.write( + "Timed out waiting for VuMark template upload after retries\n" + ) + driver.quit() + driver = None + continue + driver.quit() driver = None @@ -189,6 +267,7 @@ def main() -> None: database_details=database_details, vumark_details=vumark_details, inactive_database_details=inactive_database_details, + vumark_target_id=vumark_target_id, ) file.write_text(data=file_contents) sys.stdout.write(f"Created database {file.name}\n") diff --git a/pyproject.toml b/pyproject.toml index dead7dba2..9948bb41a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,7 +104,7 @@ optional-dependencies.dev = [ "vulture==2.14", "vws-python==2026.2.15", "vws-test-fixtures==2023.3.5", - "vws-web-tools==2026.2.16.1", + "vws-web-tools==2026.2.17", "yamlfix==1.19.1", "zizmor==1.22.0", ] diff --git a/vuforia_secrets.env.example b/vuforia_secrets.env.example index 5e843a117..ea7273354 100644 --- a/vuforia_secrets.env.example +++ b/vuforia_secrets.env.example @@ -15,6 +15,7 @@ INACTIVE_VUFORIA_CLIENT_ACCESS_KEY= INACTIVE_VUFORIA_CLIENT_SECRET_KEY= VUMARK_VUFORIA_TARGET_MANAGER_DATABASE_NAME= +VUMARK_VUFORIA_TARGET_ID= VUMARK_VUFORIA_SERVER_ACCESS_KEY= VUMARK_VUFORIA_SERVER_SECRET_KEY= From 72292913f84686e19f9e46abb4675208ab3f8bc3 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 17 Feb 2026 09:02:53 +0000 Subject: [PATCH 2/6] Use checked-in VuMark SVG template --- admin/create_secrets_files.py | 30 ++++++++---------------------- admin/vumark_template.svg | 4 ++++ 2 files changed, 12 insertions(+), 22 deletions(-) create mode 100644 admin/vumark_template.svg diff --git a/admin/create_secrets_files.py b/admin/create_secrets_files.py index 30e1b7d67..dbb4b980e 100644 --- a/admin/create_secrets_files.py +++ b/admin/create_secrets_files.py @@ -6,7 +6,6 @@ import datetime import os import sys -import tempfile import textwrap from pathlib import Path from typing import TYPE_CHECKING @@ -33,14 +32,7 @@ reraise=True, ) -VUMARK_TEMPLATE_SVG = textwrap.dedent( - text="""\ - - - - - """, -) +VUMARK_TEMPLATE_SVG_FILE_PATH = Path(__file__).with_name("vumark_template.svg") def _create_and_get_database_details( @@ -128,19 +120,13 @@ def _create_and_get_vumark_target_id( vumark_template_name: str, ) -> str: """Upload a VuMark template and get its target ID.""" - with tempfile.TemporaryDirectory() as temporary_directory: - svg_file_path = Path(temporary_directory) / "template.svg" - svg_file_path.write_text( - data=VUMARK_TEMPLATE_SVG, - encoding="utf-8", - ) - upload_result = RETRY_ON_TIMEOUT(vws_web_tools.upload_vumark_template)( - driver=driver, - database_name=vumark_database_name, - svg_file_path=svg_file_path, - template_name=vumark_template_name, - width=100.0, - ) + upload_result = RETRY_ON_TIMEOUT(vws_web_tools.upload_vumark_template)( + driver=driver, + database_name=vumark_database_name, + svg_file_path=VUMARK_TEMPLATE_SVG_FILE_PATH, + template_name=vumark_template_name, + width=100.0, + ) if isinstance(upload_result, str): return upload_result diff --git a/admin/vumark_template.svg b/admin/vumark_template.svg new file mode 100644 index 000000000..3d3c3d89e --- /dev/null +++ b/admin/vumark_template.svg @@ -0,0 +1,4 @@ + + + + From 222ad7209ed759b695ce7f1f22c695043b851db8 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 17 Feb 2026 10:01:44 +0000 Subject: [PATCH 3/6] Remove local retry wrapper and simplify VuMark upload return handling --- admin/create_secrets_files.py | 34 ++++------------------------------ 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/admin/create_secrets_files.py b/admin/create_secrets_files.py index dbb4b980e..06db5dfc5 100644 --- a/admin/create_secrets_files.py +++ b/admin/create_secrets_files.py @@ -13,25 +13,12 @@ import vws_web_tools from dotenv import load_dotenv from selenium.common.exceptions import TimeoutException -from tenacity import ( - retry, - retry_if_exception_type, - stop_after_attempt, - wait_exponential, -) if TYPE_CHECKING: from selenium.webdriver.remote.webdriver import WebDriver from vws_web_tools import DatabaseDict, VuMarkDatabaseDict -RETRY_ON_TIMEOUT = retry( - retry=retry_if_exception_type(exception_types=TimeoutException), - stop=stop_after_attempt(max_attempt_number=3), - wait=wait_exponential(multiplier=2, min=5, max=30), - reraise=True, -) - VUMARK_TEMPLATE_SVG_FILE_PATH = Path(__file__).with_name("vumark_template.svg") @@ -60,7 +47,7 @@ def _create_and_get_database_details( license_name=license_name, ) - return RETRY_ON_TIMEOUT(vws_web_tools.get_database_details)( + return vws_web_tools.get_database_details( driver=driver, database_name=database_name, ) @@ -79,7 +66,7 @@ def _create_and_get_vumark_details( database_name=vumark_database_name, ) - return RETRY_ON_TIMEOUT(vws_web_tools.get_vumark_database_details)( + return vws_web_tools.get_vumark_database_details( driver=driver, database_name=vumark_database_name, ) @@ -120,30 +107,17 @@ def _create_and_get_vumark_target_id( vumark_template_name: str, ) -> str: """Upload a VuMark template and get its target ID.""" - upload_result = RETRY_ON_TIMEOUT(vws_web_tools.upload_vumark_template)( + target_id = vws_web_tools.upload_vumark_template( driver=driver, database_name=vumark_database_name, svg_file_path=VUMARK_TEMPLATE_SVG_FILE_PATH, template_name=vumark_template_name, width=100.0, ) - - if isinstance(upload_result, str): - return upload_result - - if isinstance(upload_result, dict): - target_id = upload_result.get("target_id") - if isinstance(target_id, str): - return target_id - - target_id = getattr(upload_result, "target_id", None) if isinstance(target_id, str): return target_id - msg = ( - "Expected `upload_vumark_template` to return a target ID. " - "Upgrade `vws-web-tools` to a version that returns one." - ) + msg = "Expected `upload_vumark_template` to return a string target ID." raise RuntimeError(msg) From a2107881489236c0608b64459984c7546166edcd Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 17 Feb 2026 10:02:48 +0000 Subject: [PATCH 4/6] Fix mypy call style for Path.with_name --- admin/create_secrets_files.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/admin/create_secrets_files.py b/admin/create_secrets_files.py index 06db5dfc5..4d9210b37 100644 --- a/admin/create_secrets_files.py +++ b/admin/create_secrets_files.py @@ -19,7 +19,9 @@ from vws_web_tools import DatabaseDict, VuMarkDatabaseDict -VUMARK_TEMPLATE_SVG_FILE_PATH = Path(__file__).with_name("vumark_template.svg") +VUMARK_TEMPLATE_SVG_FILE_PATH = Path(__file__).with_name( + name="vumark_template.svg", +) def _create_and_get_database_details( From 097b16262d0c39791c7d1686f65e30acfd8414f2 Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 17 Feb 2026 10:04:17 +0000 Subject: [PATCH 5/6] Align VuMark target ID helper with strict static typing --- admin/create_secrets_files.py | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/admin/create_secrets_files.py b/admin/create_secrets_files.py index 4d9210b37..396c513e0 100644 --- a/admin/create_secrets_files.py +++ b/admin/create_secrets_files.py @@ -8,7 +8,7 @@ import sys import textwrap from pathlib import Path -from typing import TYPE_CHECKING +from typing import TYPE_CHECKING, cast import vws_web_tools from dotenv import load_dotenv @@ -109,18 +109,16 @@ def _create_and_get_vumark_target_id( vumark_template_name: str, ) -> str: """Upload a VuMark template and get its target ID.""" - target_id = vws_web_tools.upload_vumark_template( - driver=driver, - database_name=vumark_database_name, - svg_file_path=VUMARK_TEMPLATE_SVG_FILE_PATH, - template_name=vumark_template_name, - width=100.0, + return cast( + "str", + vws_web_tools.upload_vumark_template( + driver=driver, + database_name=vumark_database_name, + svg_file_path=VUMARK_TEMPLATE_SVG_FILE_PATH, + template_name=vumark_template_name, + width=100.0, + ), ) - if isinstance(target_id, str): - return target_id - - msg = "Expected `upload_vumark_template` to return a string target ID." - raise RuntimeError(msg) def _create_vuforia_resource_names() -> tuple[str, str, str, str]: From 206f3796344b61033f9182d9e12a6a829c3b91ee Mon Sep 17 00:00:00 2001 From: Adam Dangoor Date: Tue, 17 Feb 2026 17:56:19 +0000 Subject: [PATCH 6/6] Use get_vumark_target_id and pin vws-web-tools 2026.2.17.1 --- admin/create_secrets_files.py | 22 ++++++++++++---------- pyproject.toml | 2 +- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/admin/create_secrets_files.py b/admin/create_secrets_files.py index 396c513e0..13d2310d0 100644 --- a/admin/create_secrets_files.py +++ b/admin/create_secrets_files.py @@ -8,7 +8,7 @@ import sys import textwrap from pathlib import Path -from typing import TYPE_CHECKING, cast +from typing import TYPE_CHECKING import vws_web_tools from dotenv import load_dotenv @@ -109,15 +109,17 @@ def _create_and_get_vumark_target_id( vumark_template_name: str, ) -> str: """Upload a VuMark template and get its target ID.""" - return cast( - "str", - vws_web_tools.upload_vumark_template( - driver=driver, - database_name=vumark_database_name, - svg_file_path=VUMARK_TEMPLATE_SVG_FILE_PATH, - template_name=vumark_template_name, - width=100.0, - ), + vws_web_tools.upload_vumark_template( + driver=driver, + database_name=vumark_database_name, + svg_file_path=VUMARK_TEMPLATE_SVG_FILE_PATH, + template_name=vumark_template_name, + width=100.0, + ) + return vws_web_tools.get_vumark_target_id( + driver=driver, + database_name=vumark_database_name, + target_name=vumark_template_name, ) diff --git a/pyproject.toml b/pyproject.toml index d0c04be1a..83b732734 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -104,7 +104,7 @@ optional-dependencies.dev = [ "vulture==2.14", "vws-python==2026.2.15", "vws-test-fixtures==2023.3.5", - "vws-web-tools==2026.2.17", + "vws-web-tools==2026.2.17.1", "yamlfix==1.19.1", "zizmor==1.22.0", ]