Skip to main content

Easy query generation for the FTrack API.

Project description


FTrack Query is an object-orientated wrapper over the FTrack API. While the default query syntax is powerful, it is entirely text based so dynamic queries can be difficult to construct. This module supports and/or operators with nested comparisons.

It is recommended to first read for a basic understanding of how the FTrack API works.


pip install ftrack_query


from ftrack_query import FTrackQuery, entity, or_

with FTrackQuery() as session:
    # Create
    note = session.Note.create(
        content='My new note',
        category=session.NoteLabel.where(entity.color!=None, name='Internal').one(),

    # Query
    task = session.Task.where('Lighting', 'Rendering'),
        name='My Task',


    # Events



Main class inherited from ftrack_api.Session.


Every available entity type is an attribute of a session. What was originally session.query('Note') is now session.Note. This results in the Query object, which is used for constructing and executing queries.

.where(*args, **kwargs)

Filter the result.

Using kwargs is the recommended way, with a syntax like .where(first_name='Peter', last_name='Hunt').

Using args is required for complex queries. This uses the Comparison object, which is automatically created when comparing multiple Query objects. An example would be .where(entity.project.metadata.any(entity.key!='disabled')).

.populate(*args) | .select(*args)

Pre-fetch entity attributes.

An an example, in order to iterate through the name of every user, it would be a good idea to prefetch first_name and last_name, as otherwise two queries will be performed for each individual user.


Sort the results by an attribute.

The attribute and order can be given in the format, or as a raw string such as name descending.


Reverse the sorting direction.


Limit the amount of results to a certain value.


In the case of using a limit, this applies an offset to the result that is returned.

.in_(subquery) | .not_in(subquery)

Perform a check to check if an attribute matches any results.

This can accept a subquery such .in_('select id from table where x is y'), or a list of items like .in_('x', 'y').


If an entity has a primary key, by calling the value of that primary key, the entity or None will be returned. Currently only User supports this.


The Comparison object is designed to convert data to a string. It contains a wide array of operators that can be used against any data type, including other Comparison objects.

Any comparison can be reversed with the ~ prefix or the not_ function.

  • String Comparison: entity.attr=='value'
  • Number comparison: entity.attr>5
  • Pattern Comparison:'value%')
  • Time Comparison: entity.attr.after('day'))
  • Scalar Relationship: entity.attr.has(subattr='value')
  • Collection Relationship: entity.attr.any(subattr='value')
  • Subquery Relationship: entity.attr.in_(subquery)

and_(*args, **kwargs) | or_(*args, **kwargs)

Join multiple comparisons. and_ is used by default if nothing is provided.

Equivalent examples from the API reference:

Note: If an entity type is used multiple times, it's recommended to use <Entity> = session.<Entity> after the session is initialised. To save space below, that part has been omitted.

# projects = session.query('Project')
# for project in projects:
#     print project['name']
projects = Project
for project in projects:
    print project['name']

# session.query('Project').all()

# session.query('Project where status is active')

# session.query('Project where status is active and name like "%thrones"')
Project.where('%thrones'), status='active')

# session.query('Project where status is active and (name like "%thrones" or full_name like "%thrones")')
Project.where(or_('%thrones'),'%thrones')), status='active')

# session.query('Task where is "{0}"'.format(project['id']))

# session.query('Task where is "{0}" and is "Done"'.format(project['id']))
Task.where('Done', project=project)

# session.query('Task where timelogs.start >= "{0}"'.format('day')))

# session.query('Note where author has (first_name is "Jane" and last_name is "Doe")')
Note.where('Jane', User.last_name=='Doe'))

# session.query('User where not timelogs any ()')

# projects = session.query('select full_name, from Project')'full_name', '')

# select name from Project where allocations.resource[Group].memberships any (user.username is "john_doe")'name').where(Project.allocations.resource[Group].memberships.any(Membership.user.username=='john_doe'))

# Note where parent_id is "{version_id}" or parent_id in (select id from ReviewSessionObject where version_id is "{version_id}")
Note.where(or_(entity.parent_id.in_(ReviewSessionObject.where(version_id=version_id).select(, parent_id=version_id))

Project details

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Files for ftrack-query, version 1.6.0
Filename, size File type Python version Upload date Hashes
Filename, size ftrack-query-1.6.0.tar.gz (14.8 kB) File type Source Python version None Upload date Hashes View

Supported by

Pingdom Pingdom Monitoring Google Google Object Storage and Download Analytics Sentry Sentry Error logging AWS AWS Cloud computing DataDog DataDog Monitoring Fastly Fastly CDN DigiCert DigiCert EV certificate StatusPage StatusPage Status page