vws-python¶
Installation¶
$ pip install vws-python
This is tested on Python 3.14+.
Get in touch with adamdangoor@gmail.com if you would like to use this with another language.
Usage¶
See the API Reference for full usage details.
"""Add a target to VWS and then query it."""
import os
import pathlib
import uuid
from vws import VWS, CloudRecoService
server_access_key = os.environ["VWS_SERVER_ACCESS_KEY"]
server_secret_key = os.environ["VWS_SERVER_SECRET_KEY"]
client_access_key = os.environ["VWS_CLIENT_ACCESS_KEY"]
client_secret_key = os.environ["VWS_CLIENT_SECRET_KEY"]
vws_client = VWS(
server_access_key=server_access_key,
server_secret_key=server_secret_key,
)
cloud_reco_client = CloudRecoService(
client_access_key=client_access_key,
client_secret_key=client_secret_key,
)
name = "my_image_name_" + uuid.uuid4().hex
image = pathlib.Path("high_quality_image.jpg")
with image.open(mode="rb") as my_image_file:
target_id = vws_client.add_target(
name=name,
width=1,
image=my_image_file,
active_flag=True,
application_metadata=None,
)
vws_client.wait_for_target_processed(target_id=target_id)
with image.open(mode="rb") as my_image_file:
matching_targets = cloud_reco_client.query(image=my_image_file)
assert matching_targets[0].target_id == target_id
Recognition counts¶
Vuforia can generate a report of the number of recognitions of each target in a database in a month. Only the current month and the previous month can be requested.
This needs the ID of the database, which is shown in the Vuforia target manager.
The report is generated in the background, and the URL it is served from expires just under seven days after it is requested.
"""Get the number of recognitions of each target this month."""
import calendar
import datetime
import os
from vws import VWS
server_access_key = os.environ["VWS_SERVER_ACCESS_KEY"]
server_secret_key = os.environ["VWS_SERVER_SECRET_KEY"]
database_id = os.environ["VWS_DATABASE_ID"]
vws_client = VWS(
server_access_key=server_access_key,
server_secret_key=server_secret_key,
database_id=database_id,
)
now = datetime.datetime.now(tz=datetime.UTC)
report_request = vws_client.request_database_reco_counts_report(
year=now.year,
month=calendar.Month(value=now.month),
)
report = vws_client.wait_for_reco_counts_report(
presigned_url=report_request.presigned_url,
)
reco_counts_by_target_id = {
item.target_id: item.reco_count for item in report.reco_counts
}
# This database has no targets, so nothing has been recognized.
assert not reco_counts_by_target_id
Model Targets¶
Vuforia generates Model Target datasets from CAD models. This uses OAuth2 client credentials, which are separate from the VWS server keys.
Dataset generation happens in the background, and the generated dataset is downloaded as a zip file.
"""Generate a Model Target dataset and download it."""
import os
from vws import ModelTargetService
from vws.model_target_datasets import (
CadDataFormat,
GuideViewPosition,
ModelTargetDatasetType,
ModelTargetModel,
ModelTargetView,
)
from vws.reports import ModelTargetDatasetStatuses
client_id = os.environ["VWS_MODEL_TARGET_CLIENT_ID"]
client_secret = os.environ["VWS_MODEL_TARGET_CLIENT_SECRET"]
model_target_client = ModelTargetService(
client_id=client_id,
client_secret=client_secret,
)
model = ModelTargetModel(
name="my_model",
cad_data_url="https://example.com/my_model.zip",
cad_data_format=CadDataFormat.ZIP,
views=[
ModelTargetView(
name="front",
guide_view_position=GuideViewPosition(
rotation=[0.0, 0.0, 0.0, 1.0],
translation=[0.0, 0.0, 1.0],
),
),
],
)
dataset_uuid = model_target_client.create_dataset(
name="my_dataset",
target_sdk="11.0",
models=[model],
dataset_type=ModelTargetDatasetType.STANDARD,
)
report = model_target_client.wait_for_dataset_generated(
dataset_uuid=dataset_uuid,
dataset_type=ModelTargetDatasetType.STANDARD,
)
assert report.status == ModelTargetDatasetStatuses.DONE
dataset = model_target_client.download_dataset(
dataset_uuid=dataset_uuid,
dataset_type=ModelTargetDatasetType.STANDARD,
)
# The dataset is a zip file.
assert dataset.startswith(b"PK")
model_target_client.delete_dataset(
dataset_uuid=dataset_uuid,
dataset_type=ModelTargetDatasetType.STANDARD,
)
Testing¶
To write unit tests for code which uses this library, without using your Vuforia quota, you can use the VWS Python Mock tool:
$ pip install vws-python-mock
"""Add a target to VWS and then query it."""
import pathlib
from mock_vws import MockVWS
from mock_vws.database import CloudDatabase
from vws import VWS, CloudRecoService
with MockVWS() as mock:
database = CloudDatabase()
mock.add_cloud_database(cloud_database=database)
vws_client = VWS(
server_access_key=database.server_access_key,
server_secret_key=database.server_secret_key,
)
cloud_reco_client = CloudRecoService(
client_access_key=database.client_access_key,
client_secret_key=database.client_secret_key,
)
image = pathlib.Path("high_quality_image.jpg")
with image.open(mode="rb") as my_image_file:
target_id = vws_client.add_target(
name="example_image_name",
width=1,
image=my_image_file,
application_metadata=None,
active_flag=True,
)
vws_client.wait_for_target_processed(target_id=target_id)
matching_targets = cloud_reco_client.query(image=my_image_file)
assert matching_targets[0].target_id == target_id
There are some differences between the mock and the real Vuforia. See https://vws-python.github.io/vws-python-mock/differences-to-vws for details.
Reference¶
- API Reference
VWSVWS.make_request()VWS.add_target()VWS.get_target_record()VWS.wait_for_target_processed()VWS.list_targets()VWS.get_target_summary_report()VWS.get_database_summary_report()VWS.request_database_reco_counts_report()VWS.download_reco_counts_report()VWS.wait_for_reco_counts_report()VWS.delete_target()VWS.get_duplicate_targets()VWS.update_target()
AsyncCloudRecoServiceAsyncModelTargetServiceAsyncModelTargetService.aclose()AsyncModelTargetService.get_access_token()AsyncModelTargetService.make_request()AsyncModelTargetService.create_dataset()AsyncModelTargetService.get_dataset_status()AsyncModelTargetService.wait_for_dataset_generated()AsyncModelTargetService.download_dataset()AsyncModelTargetService.delete_dataset()
AsyncVWSAsyncVWS.aclose()AsyncVWS.make_request()AsyncVWS.add_target()AsyncVWS.get_target_record()AsyncVWS.wait_for_target_processed()AsyncVWS.list_targets()AsyncVWS.get_target_summary_report()AsyncVWS.get_database_summary_report()AsyncVWS.request_database_reco_counts_report()AsyncVWS.download_reco_counts_report()AsyncVWS.wait_for_reco_counts_report()AsyncVWS.delete_target()AsyncVWS.get_duplicate_targets()AsyncVWS.update_target()
AsyncVuMarkServiceCloudRecoServiceModelTargetServiceVuMarkServiceAsyncVWSAsyncVWS.aclose()AsyncVWS.make_request()AsyncVWS.add_target()AsyncVWS.get_target_record()AsyncVWS.wait_for_target_processed()AsyncVWS.list_targets()AsyncVWS.get_target_summary_report()AsyncVWS.get_database_summary_report()AsyncVWS.request_database_reco_counts_report()AsyncVWS.download_reco_counts_report()AsyncVWS.wait_for_reco_counts_report()AsyncVWS.delete_target()AsyncVWS.get_duplicate_targets()AsyncVWS.update_target()
AsyncCloudRecoServiceAsyncVuMarkServiceModelTargetServiceAsyncModelTargetServiceAsyncModelTargetService.aclose()AsyncModelTargetService.get_access_token()AsyncModelTargetService.make_request()AsyncModelTargetService.create_dataset()AsyncModelTargetService.get_dataset_status()AsyncModelTargetService.wait_for_dataset_generated()AsyncModelTargetService.download_dataset()AsyncModelTargetService.delete_dataset()
ModelTargetDatasetTypeAutomaticColoringCadDataFormatMotionHintOptimizeTrackingForRealisticAppearanceSimplifyTrackingModeGuideViewPositionModelTargetViewModelTargetModelModelTargetModel.nameModelTargetModel.cad_data_urlModelTargetModel.cad_data_blobModelTargetModel.automatic_coloringModelTargetModel.cad_data_formatModelTargetModel.motion_hintModelTargetModel.optimize_tracking_forModelTargetModel.realistic_appearanceModelTargetModel.simplifyModelTargetModel.tracking_modeModelTargetModel.state_based_configuration_json_stringModelTargetModel.views
DatabaseSummaryReportDatabaseSummaryReport.active_imagesDatabaseSummaryReport.current_month_recosDatabaseSummaryReport.failed_imagesDatabaseSummaryReport.inactive_imagesDatabaseSummaryReport.nameDatabaseSummaryReport.previous_month_recosDatabaseSummaryReport.processing_imagesDatabaseSummaryReport.reco_thresholdDatabaseSummaryReport.request_quotaDatabaseSummaryReport.request_usageDatabaseSummaryReport.target_quotaDatabaseSummaryReport.total_recosDatabaseSummaryReport.from_response_dict()
TargetStatusesTargetSummaryReportTargetSummaryReport.statusTargetSummaryReport.database_nameTargetSummaryReport.target_nameTargetSummaryReport.upload_dateTargetSummaryReport.active_flagTargetSummaryReport.tracking_ratingTargetSummaryReport.total_recosTargetSummaryReport.current_month_recosTargetSummaryReport.previous_month_recosTargetSummaryReport.from_response_dict()
TargetRecordTargetDataQueryResultTargetStatusAndRecordRecoCountsReportRequestModelTargetDatasetStatusesModelTargetGenerationDetailModelTargetGenerationErrorModelTargetGenerationWarningModelTargetDatasetStatusReportModelTargetDatasetStatusReport.statusModelTargetDatasetStatusReport.dataset_uuidModelTargetDatasetStatusReport.created_atModelTargetDatasetStatusReport.etaModelTargetDatasetStatusReport.completed_atModelTargetDatasetStatusReport.errorModelTargetDatasetStatusReport.warningModelTargetDatasetStatusReport.from_response_dict()
RecoCountRecoCountsReportCloudRecoIncludeTargetDataVuMarkAcceptResponseTransportRequestsTransportHTTPXTransportAsyncTransportAsyncHTTPXTransport
- Exceptions
- Base exceptions
- VWS exceptions
UnknownTargetErrorFailErrorBadImageErrorAuthenticationFailureErrorRequestQuotaReachedErrorTargetStatusProcessingErrorDateRangeErrorTargetQuotaReachedErrorProjectSuspendedErrorProjectHasNoAPIAccessErrorProjectInactiveErrorMetadataTooLargeErrorRequestTimeTooSkewedErrorTargetNameExistErrorImageTooLargeErrorTargetStatusNotSuccessErrorTooManyRequestsErrorInvalidAcceptHeaderErrorInvalidInstanceIdErrorBadRequestErrorInvalidTargetTypeErrorQuotaExceededErrorLicenseCheckFailedErrorAuthorizationFailedError
- CloudRecoService exceptions
- ModelTargetService exceptions
- Custom exceptions
- Contributing to vws-python
- Release Process
- Unreleased changes
- Changelog
- 2026.08.14
- 2026.02.25.1
- 2026.02.25
- 2026.02.24
- 2026.02.23
- 2026.02.22
- 2026.02.21
- 2026.02.15
- 2025.03.10.1
- 2025.03.10
- 2024.09.21
- 2024.09.04.1
- 2024.09.04
- 2024.09.03
- 2024.09.02
- 2024.02.19
- 2024.02.06
- 2024.02.04.1
- 2024.02.04
- 2023.12.27
- 2023.12.26
- 2023.05.21
- 2023.03.25
- 2023.03.05
- 2021.03.28.2
- 2021.03.28.1
- 2021.03.28.0
- 2020.09.07.0
- 2020.08.21.0
- 2020.06.19.0
- 2020.03.21.0
- 2019.11.23.0