ftrack_api.session

class ftrack_api.session.SessionAuthentication(api_key, api_user)[source]

Attach ftrack session authentication information to requests.

__init__(api_key, api_user)[source]

Initialise with api_key and api_user.

class ftrack_api.session.Session(server_url=None, api_key=None, api_user=None, auto_populate=True, plugin_paths=None, cache=None, cache_key_maker=None, auto_connect_event_hub=False, schema_cache_path=None, plugin_arguments=None, timeout=60, cookies=None, headers=None, strict_api=False)[source]

An isolated session for interaction with an ftrack server.

__init__(server_url=None, api_key=None, api_user=None, auto_populate=True, plugin_paths=None, cache=None, cache_key_maker=None, auto_connect_event_hub=False, schema_cache_path=None, plugin_arguments=None, timeout=60, cookies=None, headers=None, strict_api=False)[source]

Initialise session.

server_url should be the URL of the ftrack server to connect to including any port number. If not specified attempt to look up from FTRACK_SERVER.

api_key should be the API key to use for authentication whilst api_user should be the username of the user in ftrack to record operations against. If not specified, api_key should be retrieved from FTRACK_API_KEY and api_user from FTRACK_API_USER.

If auto_populate is True (the default), then accessing entity attributes will cause them to be automatically fetched from the server if they are not already. This flag can be changed on the session directly at any time.

plugin_paths should be a list of paths to search for plugins. If not specified, default to looking up FTRACK_EVENT_PLUGIN_PATH.

cache should be an instance of a cache that fulfils the ftrack_api.cache.Cache interface and will be used as the cache for the session. It can also be a callable that will be called with the session instance as sole argument. The callable should return None if a suitable cache could not be configured, but session instantiation can continue safely.

Note

The session will add the specified cache to a pre-configured layered cache that specifies the top level cache as a ftrack_api.cache.MemoryCache. Therefore, it is unnecessary to construct a separate memory cache for typical behaviour. Working around this behaviour or removing the memory cache can lead to unexpected behaviour.

cache_key_maker should be an instance of a key maker that fulfils the ftrack_api.cache.KeyMaker interface and will be used to generate keys for objects being stored in the cache. If not specified, a StringKeyMaker will be used.

If auto_connect_event_hub is True then embedded event hub will be automatically connected to the event server and allow for publishing and subscribing to non-local events. If False, then only publishing and subscribing to local events will be possible until the hub is manually connected using EventHub.connect.

Note

The event hub connection is performed in a background thread to improve session startup time. If a registered plugin requires a connected event hub then it should check the event hub connection status explicitly. Subscribing to events does not require a connected event hub.

Enable schema caching by setting schema_cache_path to a folder path. If not set, FTRACK_API_SCHEMA_CACHE_PATH will be used to determine the path to store cache in. If the environment variable is also not specified then a local cache directory will be used. Set to False to disable schema caching entirely.

plugin_arguments should be an optional mapping (dict) of keyword arguments to pass to plugin register functions upon discovery. If a discovered plugin has a signature that is incompatible with the passed arguments, the discovery mechanism will attempt to reduce the passed arguments to only those that the plugin accepts. Note that a warning will be logged in this case.

timeout how long to wait for server to respond, default is 60 seconds.

cookies should be an optional mapping (dict) of key-value pairs specifying custom cookies that we need to pass in alongside the requests to the server.

headers should be an optional mapping (dict) of key-value pairs specifying custom headers that we need to pass in alongside the requests to the server.

strict_api should be an optional boolean flag (defaulting to False if not specified) indicating whether to add the ‘ftrack-strict-api’: ‘true’ header to the request or not.

property auto_populate

The current state of auto populate, stored per thread.

property record_operations

The current state of record operations, stored per thread.

property closed

Return whether session has been closed.

property server_information

Return server information such as server version.

property server_url

Return server ulr used for session.

property api_user

Return username used for session.

property api_key

Return API key used for session.

property event_hub

Return event hub.

check_server_compatibility()[source]

Check compatibility with connected server.

close()[source]

Close session.

Close connections to server. Clear any pending operations and local cache.

Use this to ensure that session is cleaned up properly after use.

reset()[source]

Reset session clearing local state.

Clear all pending operations and expunge all entities from session.

Also clear the local cache. If the cache used by the session is a LayeredCache then only clear top level cache. Otherwise, clear the entire cache.

Plugins are not rediscovered or reinitialised, but certain plugin events are re-emitted to properly configure session aspects that are dependant on cache (such as location plugins).

Warning

Previously attached entities are not reset in memory and will retain their state, but should not be used. Doing so will cause errors.

auto_populating(auto_populate)[source]

Temporarily set auto populate to auto_populate.

The current setting will be restored automatically when done.

Example:

with session.auto_populating(False):
    print entity['name']
operation_recording(record_operations)[source]

Temporarily set operation recording to record_operations.

The current setting will be restored automatically when done.

Example:

with session.operation_recording(False):
    entity['name'] = 'change_not_recorded'
property created

Return list of newly created entities.

property modified

Return list of locally modified entities.

property deleted

Return list of deleted entities.

reset_remote(reset_type, entity=None)[source]

Perform a server side reset.

reset_type is a server side supported reset type, passing the optional entity to perform the option upon.

Please refer to ftrack documentation for a complete list of supported server side reset types.

create(entity_type, data=None, reconstructing=False)[source]

Create and return an entity of entity_type with initial data.

If specified, data should be a dictionary of key, value pairs that should be used to populate attributes on the entity.

If reconstructing is False then create a new entity setting appropriate defaults for missing data. If True then reconstruct an existing entity.

Constructed entity will be automatically merged into the session.

ensure(entity_type, data, identifying_keys=None)[source]

Retrieve entity of entity_type with data, creating if necessary.

data should be a dictionary of the same form passed to create().

By default, check for an entity that has matching data. If identifying_keys is specified as a list of keys then only consider the values from data for those keys when searching for existing entity. If data is missing an identifying key then raise KeyError.

If no identifying_keys specified then use all of the keys from the passed data. Raise ValueError if no identifying_keys can be determined.

Each key should be a string.

Note

Currently only top level scalars supported. To ensure an entity by looking at relationships, manually issue the query() and create() calls.

If more than one entity matches the determined filter criteria then raise MultipleResultsFoundError.

If no matching entity found then create entity using supplied data.

If a matching entity is found, then update it if necessary with data.

Note

If entity created or updated then a commit() will be issued automatically. If this behaviour is undesired, perform the query() and create() calls manually.

Return retrieved or created entity.

Example:

# First time, a new entity with `username=martin` is created.
entity = session.ensure('User', {'username': 'martin'})

# After that, the existing entity is retrieved.
entity = session.ensure('User', {'username': 'martin'})

# When existing entity retrieved, entity may also be updated to
# match supplied data.
entity = session.ensure(
    'User', {'username': 'martin', 'email': 'martin@example.com'}
)
delete(entity)[source]

Mark entity for deletion.

get(entity_type, entity_key)[source]

Return entity of entity_type with unique entity_key.

First check for an existing entry in the configured cache, otherwise issue a query to the server.

If no matching entity found, return None.

query(expression, page_size=500)[source]

Query against remote data according to expression.

expression is not executed directly. Instead return an ftrack_api.query.QueryResult instance that will execute remote call on access.

page_size specifies the maximum page size that the returned query result object should be configured with.

merge(value, merged=None)[source]

Merge value into session and return merged value.

merged should be a mapping to record merges during run and should be used to avoid infinite recursion. If not set will default to a dictionary.

populate(entities, projections)[source]

Populate entities with attributes specified by projections.

Any locally set values included in the projections will not be overwritten with the retrieved remote value. If this ‘synchronise’ behaviour is required, first clear the relevant values on the entity by setting them to ftrack_api.symbol.NOT_SET. Deleting the key will have the same effect:

>>> print(user['username'])
martin
>>> del user['username']
>>> print(user['username'])
Symbol(NOT_SET)

Note

Entities that have been created and not yet persisted will be skipped as they have no remote values to fetch.

commit()[source]

Commit all local changes to the server.

rollback()[source]

Clear all recorded operations and local state.

Typically this would be used following a failed commit() in order to revert the session to a known good state.

Newly created entities not yet persisted will be detached from the session / purged from cache and no longer contribute, but the actual objects are not deleted from memory. They should no longer be used and doing so could cause errors.

call(data)[source]

Make request to server with data batch describing the actions.

encode(data, entity_attribute_strategy='set_only')[source]

Return data encoded as JSON formatted string.

entity_attribute_strategy specifies how entity attributes should be handled. The following strategies are available:

  • all - Encode all attributes, loading any that are currently NOT_SET.

  • set_only - Encode only attributes that are currently set without loading any from the remote.

  • modified_only - Encode only attributes that have been modified locally.

  • persisted_only - Encode only remote (persisted) attribute values.

entity_reference(entity)[source]

Return entity reference that uniquely identifies entity.

Return a mapping containing the __entity_type__ of the entity along with the key, value pairs that make up it’s primary key.

decode(string)[source]

Return decoded JSON string as Python object.

pick_location(component=None)[source]

Return suitable location to use.

If no component specified then return highest priority accessible location. Otherwise, return highest priority accessible location that component is available in.

Return None if no suitable location could be picked.

pick_locations(components)[source]

Return suitable locations for components.

Return list of locations corresponding to components where each picked location is the highest priority accessible location for that component. If a component has no location available then its corresponding entry will be None.

create_component(path, data=None, location='auto')[source]

Create a new component from path with additional data

Note

This is a helper method. To create components manually use the standard Session.create() method.

path can be a string representing a filesystem path to the data to use for the component. The path can also be specified as a sequence string, in which case a sequence component with child components for each item in the sequence will be created automatically. The accepted format for a sequence is ‘{head}{padding}{tail} [{ranges}]’. For example:

'/path/to/file.%04d.ext [1-5, 7, 8, 10-20]'

data should be a dictionary of any additional data to construct the component with (as passed to Session.create()).

If location is specified then automatically add component to that location. The default of ‘auto’ will automatically pick a suitable location to add the component to if one is available. To not add to any location specifiy locations as None.

Note

A Session.commit may be automatically issued as part of the components registration in the location.

get_component_availability(component, locations=None)[source]

Return availability of component.

If locations is set then limit result to availability of component in those locations.

Return a dictionary of {location_id:percentage_availability}

get_component_availabilities(components, locations=None)[source]

Return availabilities of components.

If locations is set then limit result to availabilities of components in those locations.

Return a list of dictionaries of {location_id:percentage_availability}. The list indexes correspond to those of components.

get_widget_url(name, entity=None, theme=None)[source]

Return an authenticated URL for widget with name and given options.

The returned URL will be authenticated using a token which will expire after 6 minutes.

name should be the name of the widget to return and should be one of ‘info’, ‘tasks’ or ‘tasks_browser’.

Certain widgets require an entity to be specified. If so, specify it by setting entity to a valid entity instance.

theme sets the theme of the widget and can be either ‘light’ or ‘dark’ (defaulting to ‘dark’ if an invalid option given).

encode_media(media, version_id=None, keep_original='auto')[source]

Return a new Job that encode media to make it playable in browsers.

media can be a path to a file or a FileComponent in the ftrack.server location.

The job will encode media based on the file type and job data contains information about encoding in the following format:

{
    'output': [{
        'format': 'video/mp4',
        'component_id': 'e2dc0524-b576-11d3-9612-080027331d74'
    }, {
        'format': 'image/jpeg',
        'component_id': '07b82a97-8cf9-11e3-9383-20c9d081909b'
    }],
    'source_component_id': 'e3791a09-7e11-4792-a398-3d9d4eefc294',
    'keep_original': True
}

The output components are associated with the job via the job_components relation.

An image component will always be generated if possible that can be used as a thumbnail.

If media is a file path, a new source component will be created and added to the ftrack server location and a call to commit() will be issued. If media is a FileComponent, it will be assumed to be in available in the ftrack.server location.

If version_id is specified, the new components will automatically be associated with the AssetVersion. Otherwise, the components will not be associated to a version even if the supplied media belongs to one. A server version of 3.3.32 or higher is required for the version_id argument to function properly.

If keep_original is not set, the original media will be kept if it is a FileComponent, and deleted if it is a file path. You can specify True or False to change this behavior.

get_upload_metadata(component_id, file_name, file_size, checksum=None)[source]

Return URL and headers used to upload data for component_id.

file_name and file_size should match the components details.

The returned URL should be requested using HTTP PUT with the specified headers.

The checksum is used as the Content-MD5 header and should contain the base64-encoded 128-bit MD5 digest of the message (without the headers) according to RFC 1864. This can be used as a message integrity check to verify that the data is the same data that was originally sent.

send_user_invite(user)[source]

Send a invitation to the provided user.

user is a User instance

send_user_invites(users)[source]

Send a invitation to the provided user.

users is a list of User instances

send_review_session_invite(invitee)[source]

Send an invite to a review session to invitee.

invitee is a instance of ReviewSessionInvitee.

Note

The invitee must be committed.

send_review_session_invites(invitees)[source]

Send an invite to a review session to a list of invitees.

invitee is a list of ReviewSessionInvitee objects.

Note

All invitees must be committed.

class ftrack_api.session.AutoPopulatingContext(session, auto_populate)[source]

Context manager for temporary change of session auto_populate value.

__init__(session, auto_populate)[source]

Initialise context.

class ftrack_api.session.OperationRecordingContext(session, record_operations)[source]

Context manager for temporary change of session record_operations.

__init__(session, record_operations)[source]

Initialise context.

class ftrack_api.session.OperationPayload(*args, **kwargs)[source]

Represent operation payload.

__init__(*args, **kwargs)[source]

Initialise payload.

clear() None.  Remove all items from D.
get(k[, d]) D[k] if k in D, else d.  d defaults to None.
items() a set-like object providing a view on D's items
keys() a set-like object providing a view on D's keys
pop(k[, d]) v, remove specified key and return the corresponding value.

If key is not found, d is returned if given, otherwise KeyError is raised.

popitem() (k, v), remove and return some (key, value) pair

as a 2-tuple; but raise KeyError if D is empty.

setdefault(k[, d]) D.get(k,d), also set D[k]=d if k not in D
update([E, ]**F) None.  Update D from mapping/iterable E and F.

If E present and has a .keys() method, does: for k in E: D[k] = E[k] If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v In either case, this is followed by: for k, v in F.items(): D[k] = v

values() an object providing a view on D's values