Steve Petterborg

  • Content Count

  • Joined

  • Last visited

  • Days Won


Steve Petterborg last won the day on October 22 2019

Steve Petterborg had the most liked content!

About Steve Petterborg

  • Rank
    Advanced Member

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Hi Fernando, Is it possible you have cached the old value for the status? You could clear the cached value and query again to ensure that you're getting the latest value from the server. See these two lines I've added above your "state = . . ." line. del link['from']['status'] link.session.populate(link['from'], 'status') state = link['from']['status']['state']['short']
  2. Hi Ozen, I wouldn't rely on their being a stable sort order in the internal review. (Consider the case of selecting multiple versions of an Asset. Then there will not even be as many items on the timeline as you had clicked.) Client reviews do have an ordering (which you can drag and drop to re-order or use the API to set the sort_order attribute directly). I'm afraid we might have to file it as a feature request, having an order-able list of clips in the experimental internal review tool.
  3. Indeed you currently have to filter in the callback.
  4. Cool! Take a look at this if you don't want to hand out that highly-provisioned API key to everyone,75:76,84,87,92,95,100,103
  5. How's the user running this tool? Is there one persistent process running in a central location or is it more like a short-lived command invoked on the command line? Are you using ftrack Connect? Just the web UI? Depending on your use-case, either running your tool as a plugin in Connect, pulling the API key from the config file written by Connect, or using the method demonstrated by Connect to use an authenticated browser session to generate a new API key all sound like good options. If you're exposing this tool as a web page or widget itself, you could embed that in a dashboard and pull API credentials there too. Also, and I don't necessarily suggest this, a global API key can have the permissions to manage User's API keys, so you could generate a new one for each of your users, store them, then create sessions as needed. Be careful not to revoke their existing keys as that will log them out of Connect.
  6. Hi Tony, What's your use case exactly? As you've found, the global API keys are not limited by the role(s) assigned to the user's whose username you use to instantiate your session.
  7. I've seen this exact error where some tool imports it's own version of (some portion of) backports, which then masks (maybe "masks" is not the correct word since it's encountered first) the particular portion that we (or our dependencies need). I'm glad the re-installation/downgrading solved it since I don't have a great general solution to the issue.
  8. Hi Peter, The simplest solution is to use session.ensure() if there's a chance the object exists already. In any case, that line alone won't implicitly create any parents, so I read the error as a not very clear version of "can't create Task, as one with the same name already exists with that same parent".
  9. del asset_version['notes'] session.populate(asset_version, 'notes') This missing piece here was clearing the cached value of the collection attribute.
  10. Hi Lise, Unfortunately not. You're looking to record or transfer from one Role to another Role? It may be the next thing we tackle now that ProjectSchemas are supported in the API.
  11. Hi Andriy, session.api_user is a username, not an id, so your line should instead read: target='applicationId=ftrack.client.web and user.username="{0}"'.format( Also, when setting "synchronous" to True, only the listeners registered with that specific local instance of Python (i.e. plugins whose register() methods were called when the session was created) will be notified--there is no communication across the network or even between processes. I hope that helps! Let us know if you have further questions.
  12. Hi Janis, Which browser/os/and part of ftrack are you seeing the issue with? I tried a quick test in Chrome on macOS and Windows 10 in the task spreadsheet and while editing a note and I didn't notice anything surprising.
  13. Hi Ozen, If you mean grouping by types, this might help: Unfortunately I don't believe you can limit a view to a particular type however.
  14. Hey Peter, nice work! I've been thinking about something like this myself--I love tab-completable everything and am excited to give this a try.
  15. Hi Justin, Since we store the multi-select enumerator value as a ", "-delimited string, you'd need to search the four possibilities: Your value is the only value, it's the first value, last value or a middle value. That snippet would look like: custom_attributes any (key is "userDynEnum_Coordinator" and (value is "greyc" or value like "greyc, %" or value like "%, greyc" or value like "%, greyc, %")) Since that's tedious and error-prone, I wrote this: import itertools def subquery_builder(*args): perms = itertools.permutations(args) for perm in perms: spacers = itertools.product((None, '%'), repeat=len(args) + 1) for spacer in spacers: if all(elem is None for elem in spacer): op = 'is' else: op = 'like' condition = ', '.join( e for sublist in itertools.izip_longest(spacer, perm) for e in sublist if e is not None) yield '{} "{}"'.format(op, condition) def query_builder(attr, *args): subq = subquery_builder(*args) return '({})'.format( ' or '.join( '{} {}'.format( attr, item ) for item in subq ) ) def custom_attr_multi_search(key, *args): return 'custom_attributes any (key is "{}" and {})'.format( key, query_builder('value', *args) ) I don't recommend using it with more than a few args.