pythonazuredata-scienceazure-video-indexer

Azure Video Indexer API: "USER_NOT_ALLOWED" Error When Checking Blurring Job Status After Completion of Bluring


Current permissions

I am working with the Azure Video Indexer API in Python to process videos, specifically to index and blur them. While both the indexing and blurring processes run successfully up to a point, I encounter an issue when attempting to retrieve the status of the blurring job after it completes.

When querying the Location URL (provided by the indexing job for checking the blurring job status), I receive valid responses until the blurring process reaches 100% completion. After that, every request returns the following error:

{
    "ErrorType": "USER_NOT_ALLOWED",
    "Message": "User has no permission on account"
}

The access token I am using is generated with the following permissions:

I suspect this issue is related to IAM (Identity and Access Management), but I have already assigned all meaningful permissions I can think of.

My Goal My ultimate goal is to download the video after the blurring process is complete. However, I cannot query the API to get the status or the download link due to the above error.

Job URL Format Here’s the job_url I’m using to check the blurring job status:

https://api.videoindexer.ai/{self.location}/Accounts/{self.account_id}/Videos/{video_id}/redact/?accessToken={self.access_token}&name={name}

Current Code Below is the Python code I use to query the job status. It works perfectly until the blurring process is 100% complete:

def get_video_blurring_processing_status(self, job_url):
    try:
        # Append the access token to the job URL
        url_with_token = f"{job_url}?accessToken={self.access_token}"
        
        # Send the request to the job status endpoint
        response = requests.get(url_with_token)
        
        if response.status_code == 200:
            data = response.json()
            processing_progress = data.get("progress", "Unknown")
            state = data.get("state", "Unknown")
            return {"processing_progress": processing_progress, "state": state}
        
        else:
            # Temporary hack
            # return {"processing_progress": 100, "state": "Succeeded"}
            print(f"Failed to get job status. Status Code: {response.status_code}, Response: {response.content}")
            return None
    
    except Exception as e:
        print(f"❌ Error while checking blurring status: {e}")
        return None

What I’ve Tried

Request for Help

Any insights or suggestions would be greatly appreciated...


Solution

  • Try regenerating the access token after the blurring process hits 100%. This checks the token has the correct scope for post-processing operations.

    import requests
    
    class VideoIndexer:
        def __init__(self, account_id, location, access_token):
            self.account_id = account_id
            self.location = location
            self.access_token = access_token
    
        def generate_new_token(self):
            # Simulated token refresh endpoint
            url = f"https://api.videoindexer.ai/Auth/{self.location}/Accounts/{self.account_id}/AccessToken?allowEdit=true"
            response = requests.get(url)
            if response.status_code == 200:
                return response.json()['accessToken']
            else:
                print("Failed to refresh access token.")
                return None
    
        def refresh_access_token(self):
            new_token = self.generate_new_token()
            if new_token:
                self.access_token = new_token
                print("✅ Access token refreshed successfully.")
            else:
                print("❌ Failed to refresh access token.")
    
        def get_video_blurring_processing_status(self, job_url):
            try:
                url_with_token = f"{job_url}?accessToken={self.access_token}"
                response = requests.get(url_with_token)
    
                if response.status_code == 200:
                    data = response.json()
                    processing_progress = data.get("progress", "Unknown")
                    state = data.get("state", "Unknown")
                    print(f"🟩 Job Status - Progress: {processing_progress}%, State: {state}")
    
                    if state == "Succeeded":
                        self.refresh_access_token()
                    return {"processing_progress": processing_progress, "state": state}
    
                elif response.status_code == 403 and b"USER_NOT_ALLOWED" in response.content:
                    print("⚠️ Access denied. Refreshing token...")
                    self.refresh_access_token()
                    return self.get_video_blurring_processing_status(job_url)
    
                else:
                    print(f"❌ Failed to get job status. Status Code: {response.status_code}, Response: {response.content}")
                    return None
    
            except Exception as e:
                print(f"❌ Error: {e}")
                return None
    
        def get_video_download_url(self, video_id):
            url = f"https://api.videoindexer.ai/{self.location}/Accounts/{self.account_id}/Videos/{video_id}/SourceFile/DownloadUrl?accessToken={self.access_token}"
            response = requests.get(url)
    
            if response.status_code == 200:
                download_url = response.json().get("downloadUrl")
                print(f"✅ Download URL retrieved: {download_url}")
                return download_url
            else:
                print(f"❌ Failed to get download URL. Response: {response.content}")
                return None
    
    # Simulated Execution
    indexer = VideoIndexer(account_id="12345", location="trial", access_token="initial_token")
    job_url = "https://api.videoindexer.ai/trial/Accounts/12345/Videos/67890/redact/"
    
    print("🔄 Checking blurring job status...")
    status = indexer.get_video_blurring_processing_status(job_url)
    
    if status and status['state'] == "Succeeded":
        video_url = indexer.get_video_download_url(video_id="67890")
        if video_url:
            print(f"🎉 Video ready for download at: {video_url}")
        else:
            print("❌ Unable to fetch video download URL.")
    else:
        print("⏳ Blurring still in progress or failed.")
    

    Add Owner or Video Indexer Admin permissions at the Video Indexer resource level, not just Contributor.

    In the Azure portal, navigate to Video Indexer > Access Control (IAM) > Role Assignments > + Add > Owner or Admin

    enter image description here

    Result:

    enter image description here