Alican Posted December 11, 2019 Report Share Posted December 11, 2019 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 Link to comment Share on other sites More sharing options...
Alican Posted December 11, 2019 Author Report Share Posted December 11, 2019 Just to add on, In the end, I would like to have a system that works just like drag and dropping the mov file to the Versions area of the task. Link to comment Share on other sites More sharing options...
Lorenzo Angeli Posted December 12, 2019 Report Share Posted December 12, 2019 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. Alican 1 Link to comment Share on other sites More sharing options...
Alican Posted December 12, 2019 Author Report Share Posted December 12, 2019 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_001.jpg : Desired result after Drag&Dropping ftrack_upload_002.jpg : My result Link to comment Share on other sites More sharing options...
Alican Posted December 13, 2019 Author Report Share Posted December 13, 2019 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: use the session.encode_media(file) to encode and generate my new file and it's thumbnail, and then download the new encoded file, 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! Link to comment Share on other sites More sharing options...
Julian Martinz Posted December 13, 2019 Report Share Posted December 13, 2019 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 Alican 1 Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now