Tutorial¶
This tutorial is a walkthrough on how you interact with Locations using the ftrack API. Before you read this tutorial, make sure you familiarize yourself with the location concepts by reading the Overview.
All examples assume you are using Python 2.x, have the ftrack_api
module imported and a session
created.
import ftrack_api
session = ftrack_api.Session()
Creating locations¶
Locations can be created just like any other entity using
Session.create
:
location = session.create('Location', dict(name='my.location'))
session.commit()
Note
Location names beginning with ftrack.
are reserved for internal use. Do
not use this prefix for your location names.
To create a location only if it doesn’t already exist use the convenience
method Session.ensure
. This will return
either an existing matching location or a newly created one.
Retrieving locations¶
You can retrieve existing locations using the standard session
get()
and
query()
methods:
# Retrieve location by unique id.
location_by_id = session.get('Location', 'unique-id')
# Retrieve location by name.
location_by_name = session.query(
'Location where name is "my.location"'
).one()
To retrieve all existing locations use a standard query:
all_locations = session.query('Location').all()
for existing_location in all_locations:
print existing_location['name']
Configuring locations¶
At this point you have created a custom location “my.location” in the database and have an instance to reflect that. However, the location cannot be used in this session to manage data unless it has been configured. To configure a location for the session, set the appropriate attributes for accessor and structure:
import tempfile
import ftrack_api.accessor.disk
import ftrack_api.structure.id
# Assign a disk accessor with *temporary* storage
location.accessor = ftrack_api.accessor.disk.DiskAccessor(
prefix=tempfile.mkdtemp()
)
# Assign using ID structure.
location.structure = ftrack_api.structure.id.IdStructure()
# Set a priority which will be used when automatically picking locations.
# Lower number is higher priority.
location.priority = 30
To learn more about how to configure locations automatically in a session, see Configuring locations.
Note
If a location is not configured in a session it can still be used as a standard entity and to find out availability of components
Using components with locations¶
The Locations API tries to use sane defaults to stay out of your way.
When creating components, a location is automatically picked
using Session.pick_location
:
(_, component_path) = tempfile.mkstemp(suffix='.txt')
component_a = session.create_component(path=component_path)
To override, specify a location explicitly:
(_, component_path) = tempfile.mkstemp(suffix='.txt')
component_b = session.create_component(
path=component_path, location=location
)
If you set the location to None
, the component will only be present in the
special origin location for the duration of the session:
(_, component_path) = tempfile.mkstemp(suffix='.txt')
component_c = session.create_component(path=component_path, location=None)
After creating a component in a location, it can be added to another
location by calling Location.add_component
and passing the location to
use as the source location:
origin_location = session.query(
'Location where name is "ftrack.origin"'
).one()
location.add_component(component_c, origin_location)
To remove a component from a location use Location.remove_component
:
location.remove_component(component_b)
Each location specifies whether to automatically manage data when adding or removing components. To ensure that a location does not manage data, mixin the relevant location mixin class before use:
import ftrack_api
import ftrack_api.entity.location
ftrack_api.mixin(location, ftrack_api.entity.location.UnmanagedLocationMixin)
Accessing paths¶
The locations system is designed to help avoid having to deal with filesystem paths directly. This is particularly important when you consider that a number of locations won’t provide any direct filesystem access (such as cloud storage).
However, it is useful to still be able to get a filesystem path from locations
that support them (typically those configured with a
DiskAccessor
). For example, you might need to
pass a filesystem path to another application or perform a copy using a faster
protocol.
To retrieve the path if available, use Location.get_filesystem_path
:
print location.get_filesystem_path(component_c)
Obtaining component availability¶
Components in locations have a notion of availability. For regular components, consisting of a single file, the availability would be either 0 if the component is unavailable or 100 percent if the component is available in the location. Composite components, like image sequences, have an availability which is proportional to the amount of child components that have been added to the location.
For example, an image sequence might currently be in a state of being
transferred to test.location
. If half of the images are transferred, it
might be possible to start working with the sequence. To check availability use
the helper Session.get_component_availability
method:
print session.get_component_availability(component_c)
There are also convenience methods on both components
and locations
for
retrieving availability as well:
print component_c.get_availability()
print location.get_component_availability(component_c)
Location events¶
If you want to receive event notifications when components are added to or
removed from locations, you can subscribe to the topics published,
ftrack_api.symbol.COMPONENT_ADDED_TO_LOCATION_TOPIC
or
ftrack_api.symbol.COMPONENT_REMOVED_FROM_LOCATION_TOPIC
and the callback
you want to be run.