import json
import time
import requests
import paho.mqtt.client as mqtt
class FileUploader:
def __init__(self, device_id, mqtt_client):
self.device_id = device_id
self.client = mqtt_client
self.presigned_url = None
# Subscribe to response topic
response_topic = f"roboticks/fleet/{device_id}/file_upload/response"
self.client.subscribe(response_topic)
self.client.on_message = self._on_message
def _on_message(self, client, userdata, msg):
"""Handle presigned URL response"""
response = json.loads(msg.payload)
if response.get('success'):
self.presigned_url = response
else:
print(f"Error: {response.get('error')}")
def upload_file(self, session_id, filepath, content_type="application/octet-stream"):
"""Upload file to session"""
import os
filename = os.path.basename(filepath)
# Step 1: Request presigned URL
request_topic = f"roboticks/fleet/{self.device_id}/file_upload/request"
request_payload = {
"session_id": session_id,
"filename": filename,
"content_type": content_type
}
self.presigned_url = None
self.client.publish(request_topic, json.dumps(request_payload))
# Step 2: Wait for response
timeout = 5 # seconds
start = time.time()
while self.presigned_url is None and (time.time() - start) < timeout:
time.sleep(0.1)
if self.presigned_url is None:
raise TimeoutError("No response from server")
# Step 3: Upload to S3
with open(filepath, 'rb') as f:
files = {'file': f}
response = requests.post(
self.presigned_url['url'],
data=self.presigned_url['fields'],
files=files
)
if response.status_code == 204:
print(f"✓ Uploaded: {self.presigned_url['object_key']}")
return True
else:
print(f"✗ Upload failed: {response.status_code}")
return False
# Usage
uploader = FileUploader("ROBOT-ABC123", mqtt_client)
uploader.upload_file(
session_id=123,
filepath="/tmp/image.jpg",
content_type="image/jpeg"
)