food-analyzer-API / utils /vuforia_utils.py
Prathamesh Sable
little twicks
f746ed1
import json
import hmac
import hashlib
import base64
import time
from datetime import datetime
from logger_manager import log_info, log_error
import os
import aiohttp
from env import VUFORIA_SERVER_ACCESS_KEY, VUFORIA_SERVER_SECRET_KEY,UPLOADED_IMAGES_DIR
async def add_target_to_vuforia(image_name: str, image_path: str) -> str:
"""
Adds a target to the Vuforia database and returns the Vuforia target ID.
Implements proper Vuforia authentication and request format.
"""
log_info(f"Adding target {image_name} to Vuforia")
try:
# Read image data
with open(image_path, "rb") as image_file:
image_data = image_file.read()
# Base64 encode the image
image_base64 = base64.b64encode(image_data).decode('utf-8')
# Create request data
request_path = '/targets'
host = 'vws.vuforia.com'
url = f"https://{host}{request_path}"
# Create payload
payload = {
"name": image_name,
"width": 150.0, # Default width in scene units
"image": image_base64,
"active_flag": True,
}
# Convert payload to JSON
body = json.dumps(payload)
# Get current date in proper format for Vuforia
date = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
# Set content type
content_type = 'application/json'
# Calculate MD5 of request body
content_md5 = hashlib.md5(body.encode('utf-8')).hexdigest()
# Create string to sign according to Vuforia docs
string_to_sign = f"POST\n{content_md5}\n{content_type}\n{date}\n{request_path}"
# Generate signature
signature = hmac.new(
VUFORIA_SERVER_SECRET_KEY.encode('utf-8'),
string_to_sign.encode('utf-8'),
hashlib.sha1
).digest()
signature_hex = base64.b64encode(signature).decode('utf-8')
# Create headers
headers = {
'Authorization': f'VWS {VUFORIA_SERVER_ACCESS_KEY}:{signature_hex}',
'Content-Type': content_type,
'Date': date,
'Content-MD5': content_md5
}
# Make the API request
async with aiohttp.ClientSession() as session:
async with session.post(url, headers=headers, data=body) as response:
# Get response text and try to parse as JSON
response_text = await response.text()
try:
response_json = json.loads(response_text)
except:
response_json = {"error": "Failed to parse response"}
log_info(f"Vuforia response status: {response.status}")
if response.status == 201: # Created
log_info(f"Target added successfully: {response_json}")
return response_json.get("target_id", "unknown_target_id")
else:
log_error(f"Failed to add target: Status {response.status}, Response: {response_text}")
raise Exception(f"Failed to add target {image_name}: Status {response.status}, Error: {response_json.get('result_code', 'Unknown')}")
except Exception as e:
log_error(f"Error adding target {image_name}: {e}", e)
raise