Ftrack Review Submission, Resource not found error
0

6 posts in this topic

Hello all, 

I've been trying to upload an existing .mov file to ftrack for review, I've made quite a progress using the examples provided, however I'm stuck at the component part. 

At the moment, it submits an encoding job, waits for the job to be done, and gives me the URLs of the paths. 

If I set the path key on the create_component() to the MOV_FILE, it uploads. but if I set it to the url of the encoded item, it gives me the error below.

What am I doing wrong?

Quote

Traceback (most recent call last):
  File "L:\HAL\Alican\ftrack\_hooks\review_submission_hook\review_submitter_003.py", line 104, in <module>
    location=location
  File "\\qumulo\Libraries\python-lib\FTRACK\ftrack_api\entity\asset_version.py", line 47, in create_component
    return self.session.create_component(path, data=data, location=location)
  File "\\qumulo\Libraries\python-lib\FTRACK\ftrack_api\session.py", line 1956, in create_component
    'FileComponent', path, data, location
  File "\\qumulo\Libraries\python-lib\FTRACK\ftrack_api\session.py", line 2028, in _create_component
    location.add_component(component, origin_location, recursive=False)
  File "\\qumulo\Libraries\python-lib\FTRACK\ftrack_api\entity\location.py", line 78, in add_component
    [component], sources=source, recursive=recursive
  File "\\qumulo\Libraries\python-lib\FTRACK\ftrack_api\entity\location.py", line 211, in add_components
    transferred=transferred
ftrack_api.exception.LocationError: Failed to transfer component <FileComponent(73db44a1-3df3-4fe4-b9c7-d050a253d2c1)> data to location <ServerLocation("ftrack.server", 3a372bde-05bc-11e4-8908-20c9d081909b)> due to error:
    Resource not found: https://XXXXXXXXX.ftrackapp.com/component/get?id=78063fdd-2018-4319-bf14-7d9cde0beab6&username=XXXXXXX&apiKey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Transferred component data that may require cleanup: []

When I inspect the link from the line that says Resoruce not found, I can see that it does exist. and it downloads a file called main.mov, which is exactly what I want. This tells me that this resource indeed exists in the server.

 

The following is a standalone script that gets the MOV_FILE and uploads it as an asset for a task(TASK_TYPE) that belongs to a shot (SHOT_NAME).

import os, sys
import subprocess
import time
import getpass
import ftrack_api
import json


os.environ['FTRACK_SERVER'] = FTRACK_SERVER
os.environ['FTRACK_API_USER'] = getpass.getuser()
os.environ['FTRACK_API_KEY'] = FTRACK_API_KEY
session = ftrack_api.session.Session(auto_connect_event_hub=True)


SHOT_NAME = 'CHM201_033_050'
TASK_TYPE = 'Compositing'
MOV_FILE  = 'Q:/Charmed_S2/CHM201/07_DAILIES/SLATED_OUTPUTS/offline/AVdn/201_033_050_cmp_v023.mov'


shot = session.query('select name, id from Shot where name is {}'.format(SHOT_NAME)).first()
comp = session.query('select name, id from Task where parent.id is {} and type.name is {}'.format(shot['id'], TASK_TYPE)).first()
mov = MOV_FILE

task = session.get('Task', comp['id'])
asset_parent = task['parent']

job = session.encode_media(mov)
job_data = json.loads(job['data'])

print 'Source component id', job_data['source_component_id']
print 'Keeping original component', job_data['keep_original']

location = session.query('Location where name is "ftrack.server"').one()

for output in job_data['output']:
    print u'Output component - id: {0}, format: {1}'.format( output['component_id'], output['format'] )

#Wait for the job to complete
keep_waiting = True
timer = 0
wait  = 5
while keep_waiting:
    print 'waiting.. {} seconds'.format(timer)
    time.sleep(wait)
    timer+=5
    listen_session = ftrack_api.session.Session(auto_connect_event_hub=True)
    the_job = listen_session.query('Job where id is{}'.format(job['id'])).first()
    if the_job['status'] == 'done':
        print 'proceeding...'
        keep_waiting = False

location = session.query('Location where name is "ftrack.server"').one()

#Print out the urls and test them to make sure they exist
for component in job['job_components']:
    component_name = component['component']['name']
    print component_name, location.get_url(component)

asset_type    = session.query('AssetType where name is "Compositing"').one()
asset         = session.create('Asset',         { 'name' : 'Compositing Asset v7', 'type': asset_type, 'parent': asset_parent })
asset_version = session.create('AssetVersion',  { 'asset': asset, 'task': task })

for component in job['job_components']:
    component_name = component['component']['name']
    print component_name, location.get_url(component)

    if component_name == 'thumbnail':
        new_component = asset_version.create_component(
            path=location.get_url(component),
            data={
                'name': 'thumbnail'
            },
            location=location
        )

    if component_name == 'ftrackreview-mp4':
        new_component = asset_version.create_component(
            path=location.get_url(component),
            data={
                'name': 'ftrackreview-mp4'
            },
            location=location
        )

session.commit()

 

Thank you for all your help as always!

Ali

Share this post


Link to post
Share on other sites

Hi @Alican

you cannot use the location.get_url(component) as path for the component as is relative to the server, path requires to be a local path to your file system.

What you might be after, if I'm getting it right , is an event which collect the data which might have been manually uploaded and then transfer them first to you local disk , before being re uploaded as reviewable. For this to work , you need to have a listener running which will intercept the update event for components and use that to move the data from the ftrack.server to the local storage. Something along these lines should work (https://bitbucket.org/snippets/ftrack/ynxGp4


Hope it helps.
L.


 

Share this post


Link to post
Share on other sites

I am trying to do the uploading and encoding of my .mov renders through the API. Just like how I would if I was drag & dropping it into the Version tab of a task.   I am not really trying to download anything. 

The manual uploading of versions is very clean, it encodes it, creates a thumbnail, and i can review it anytime and anywhere i want. 

> ftrack_upload_000.jpg --- result = ftrack_upload_001.jpg

> ftrack_upload_001.jpg --- desired result that i'm looking for

 

I want to upload in the same fashion though the API. 

 

I have read through the following documents:

http://ftrack-python-api.rtd.ftrack.com/en/stable/example/encode_media.html (This creates encoded file, and thumbnail that lives in the ftrack server)

http://ftrack-python-api.rtd.ftrack.com/en/stable/example/publishing.html (But these seem to always source the local file though the path key, instead of my encoded files in the server)

http://ftrack-python-api.rtd.ftrack.com/en/stable/example/web_review.html 

 

None of these examples seem to get me a result like manually Drag&Dropping a file and having the file live in the server (ftrack_upload_001.jpg).

They all end up linking to my file in our local drive. (path=path/to/my/file.mov) (ftrack_upload_002.jpg)

 

> ftrack_upload_002.jpg --- my result following the 'publishing' example

And yes, when I set the 'path' of the create_component() to the file that lives in our system it works. But then that means it still lives in our local storage instead of the ftrack server, and that also means i have to create the thumbnails individually as well. 

Is there a way to use the linkgs generated from encode_media to be used as a path somehow? So that my action replicates the Drag&Drop process?

 

ftrack_upload_000.jpg : Manual Drag&Dropping

ftrack_upload_000.jpg


ftrack_upload_001.jpg : Desired result after Drag&Dropping

ftrack_upload_001.jpg

 

ftrack_upload_002.jpg : My result

ftrack_upload_002.jpg

Share this post


Link to post
Share on other sites

UPDATE: 

I just got it to work.

 

When I set the path to my local path in my file system, it actually uploads it to the ftrack server, it doesn't actually source from my local file. This is great! 

 

Sooo... @Lorenzo your initial reply makes so much more sense now, thank you.

 

Which brings me to an important final question:

Does this mean that I have to:

  1.  use the session.encode_media(file) to encode and generate my new file and it's thumbnail, 
  2.  and then download the new encoded file
  3.  and then link the new downloaded file on my local directory to the path of create_component()

Did I get this right? Is this the correct workflow? 

 

 

Here is my new updated code that works:

SHOT_NAME = 'CHM201_033_050'
TASK_TYPE = 'Compositing'

session = ftrack_api.session.Session(auto_connect_event_hub=True)

shot = session.query('select name, id from Shot where name is {}'.format(SHOT_NAME)).first()
comp = session.query('select name, id from Task where parent.id is {} and type.name is {}'.format(shot['id'], TASK_TYPE)).first()

task = session.get('Task', comp['id'])
asset_parent = task['parent']

location = session.query('Location where name is "ftrack.server"').one()
asset_type    = session.query('AssetType where name is "Compositing"').one()
asset         = session.create('Asset',         { 'name' : 'Compositing Asset v24', 'type': asset_type, 'parent': asset_parent })
asset_version = session.create('AssetVersion',  { 'asset': asset, 'task': task })

component = asset_version.create_component(
    path='C:/Users/luxali/Downloads/main.mov',
    data={
        'name': 'ftrackreview-mp4'
    },
    location=location
)

# Meta data needs to contain *frameIn*, *frameOut* and *frameRate*.
component['metadata']['ftr_meta'] = json.dumps({
    'frameIn': 0,
    'frameOut': 67,
    'frameRate': 25
})

thumbnail_component = session.create_component(
    'C:/Users/luxali/Downloads/main.jpg',
    dict(name='thumbnail'),
    location=location
)

asset_version['thumbnail'] = thumbnail_component

component.session.commit()


 

Thank you so much!

 

Share this post


Link to post
Share on other sites

Hey  Alican,

I didn't read through the entire thread but I think all you wanna do is adding a reviewable version to an assetversion. If that's correct you just can use the encode_media helper method from the asset_version itself and call it a day. With that method the media will be uploaded and encoded.

...
asset_version = session.create('AssetVersion', {'asset': asset})
asset_version.encode_media(local_path_to_media)

Best,
Julian

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
0