-
Notifications
You must be signed in to change notification settings - Fork 13
Getting started tutorial
Before beginning this tutorial it is assumed that you have installed the ShotgunORM into a folder located on your Python path so it can be imported for the purposes of this tutorial.
This brief tutorial will get you up and running with the ShotgunORM.
In this tutorial you will learn how to do the following.
- Connect to a Shotgun database
- Query Entities
- Return a fields value
- Change a fields value and commit the new value to Shotgun
- Change a fields value and revert the modification
- Create a new Entity and commit it to Shotgun
- Clone a Entity
Connections to the Shotgun database are created with the SgConnection class.
The SgConnection class represents a single login, key, and url connection to a Shotgun database. Most facilities provide Shotgun API access keys on a per tool basis, in those situations you would have a SgConnection per login/key pair.
SgConnections are singleton objects thus if you create multiple SgConnections with the same login/key/url combination the same SgConnection will be returned instead of separate instances.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)After running the above code you now have a connection to your Shotgun database represented by the variable connection.
The ShotgunORM supports two distinct methods for searching the Shotgun database. All queries to the database are handled by the SgConnection objects.
The official Shotgun Software Python API search method is supported by the ShotgunORM.
Searches are ran by calling the SgConnection.find() or SgConnection.findOne() functions and specifiying an Entity type followed by a nested list of search parameters.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.findOne('Asset', [ ['id', 'is_not', 420] ])Info:For more information on the official Shotgun Software Python API search syntax refer to Reference: Filter Syntax.
The ShotgunORM methods for searching SgConnection.search() and SgConnection.searchOne() while similiar to the official API differ in there search filters parameter.
The search filters parameter for the ShotgunORM is an expression string instead of a nested list like in the official API method. Using a search string is more readable then the nested list method and supports joins in a more user friendly manner.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.searchOne('Asset', 'id != 420')Info:For more information on the ShotgunORM search syntax refer to the ShotgunORM search syntax wiki page.
The ShotgunORM can perform searches asynchronously allowing code to continue executing while the search is performed.
Methods
- SgConnection.findAsync
- SgConnection.findOneAsync
- SgConnection.searchAsync
- SgConnection.searchOneAsync
The async functions return a single SgAsyncSearchResult object instead of the usual SgEntity or list of SgEntity objects.
Tip:The SgAsyncSearchResult can be tested if the search has completed by calling the SgAsyncSearchResult.isReady() method.
To retrieve the value simply call the SgAsyncSearchResult.value() method. If the search has not yet completed then calling this function will block until it has.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
users = connection.findAsync('HumanUser', [])
# Perform some operations
if not users.isReady():
# Do some more stuff while waiting
pass
# Nothing left to do so either block or the search should be completed
users = users.value()Once a search has successfully returned results from Shotgun its time to interact with the data.
Entities from Shotgun are represented by SgEntity objects. Entities have an id and contain all the fields of the Shotgun Entity as SgField objects.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.findOne('Asset', [])
print someRandomAsset
result: <Shotgun.Project.Asset(id:1337)>While an Entity exists in Python it is a singleton object. If two fields point to the same Entity the object returned will be the same.
It's highly recommended that you read the section Entity field caching located in the Advanced tutorial for more information about the Entity objects.
Info:The repr for SgEntity objects displays wether the Entity is specific to a project or is a global Entity. When the repr string begins with "Shotgun.Project." you know the Entity is specific to a project. When it only begins with "Shotgun." its a global Entity.
Entity fields are represented by the SgField class. In most casses you do not directly interact with the field object itself but instead query and set its value by accessing it as a property on the Entity object.
To retrieve the field obj for an Entity's field you call the SgEntity.field() function and specifiy the fields name.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.findOne('Asset', [])
print someRandomAsset.field('code').label()
result: 'Asset Name'It is also possible to retrieve all the field objects of an Entity by calling its SgEntity.fields() function.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.findOne('Asset', [])
fields = someRandomAsset.fields()To retrieve the value of a field you can either query the Entity object for a property with the same name as the field or by getting the field object and calling its SgField.value() function.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.findOne('Asset', [])
# Accessing the field value as a property on the SgEntity.
assetCode = someRandomAsset.code
assetId = someRandomAsset.id
# Accessing the field value by treating the SgEntity like a dict.
assetCode = someRandomAsset['code']
assetId = someRandomAsset['id']
# Accessing the field value from the field object.
assetCode = someRandomAsset.field('code').value()
assetId = someRandomAsset.field('id').value()
# Walk the Assets project field to get the name of the project.
assetProjectName = someRandomAsset.project.name
# In dict form walk the Assets project field to get the name of the project.
assetProjectName = someRandomAsset['project']['name']
# The walk example but in long form.
projectEntity = someRandomAsset.project
assetProjectName = projectEntity.nameTo retrieve multiple field values at once you call the SgEntity.fieldValues() function and pass it a list of field names. The result will be a dict with the keys being the name of the field and the values the fields value
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.findOne('Asset', [])
# Get a range of field values.
values = someRandomAsset.fieldValues(['code', 'project', 'created_by'])
print values
result: {
'code': 'Uber_Asset',
'project': <Shotgun.Project(id:65)>,
'created_by': <Shotgun.HumanUser(id:534)>
}To modify the value of a field you can either set the value of the Entities property that has the same name as the field or by getting the field object and calling its SgField.setValue() function.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.findOne('Asset', [])
# Set the description field to a new value.
someRandomAsset.description = 'super awesome new description!'
print someRandomAsset.description
result: 'super awesome new description'
# Set the description field to a new value with the field object.
someRandomAsset.field('description').setValue('way better description')
print someRandomAsset.description
result: 'way better description'When a field is modified the change is only represented locally, the Shotgun database does not yet reflect the new modification. To make the modification permanent you must commit the change.
Commits for Entities can be achieved in one of two ways. The first method invloves invoking the SgEntity.commit() function and the second is by passing the Entity to your connections SgConnection.batch() function.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.findOne('Asset', [])
# Set the description field to a new value.
someRandomAsset.description = 'super awesome new description!'
# Commit the change using the Entity.
someRandomAsset.commit()
# Set the description field to a new value.
someRandomAsset.description = 'way better description'
# Commit the change in a batch call with the connection.
connection.batch([someRandomAsset])You may have noticed that the connection does not require you to formulate a batch blob. The ShotgunORM strictly deals with SgEntity objects and there is not need to manually build the Shotgun dictionary for a batch call.
If you would like the raw Shotgun formatted batch blob of the Entity you can call the SgEntity.toBatchFieldData() function.
Tip:You can specify a specific range of fields to commit by passing a list of field names to the SgEntity.commit() function
Reverting un-commited field changes to Entities is achieved by calling the SgEntity.revert() function.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.findOne('Asset', [])
# Set the description field to a new value.
someRandomAsset.description = 'super awesome new description!'
# Revert all field modifications.
someRandomAsset.revert()
print someRandomAsset.description
result: 'original value'Tip:You can specify a specific range of fields to revert by passing a list of field names to the SgEntity.revert() function
To bring an Entity and all its field values up to date with Shotgun you call its SgEntity.sync() function.
Calling sync invalidates any previously pulled field values. Make sure to read the documetation on SgEntity.sync() for additional arguments.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = connection.findOne('Asset', [])
print someRandomAsset.description
result: 'blah blah blah'
# Sync the Entity something may have changed.
someRandomAsset.sync()
print someRandomAsset.description
result: 'Bob was here!'New Entities are created by calling the connections SgConnection.create() function.
The connections create function is very similar to the official Shotgun Python API with the one major difference being that newly created Entities are not immediately created in Shotgun. It is up to the developer to run SgEntity.commit() on the returned Entity.
In cases where you want to create a new Entity and immediately have it reflected in Shotgun the argument "sgCommit=True" can be passed to the create function. This will create a new Entity and imediately commit it to the Shotgun database.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
assetData = {
'code': 'All_Your_Base',
'description': 'Asset for set up the bomb'
}
# Create a new Asset Entity.
newAsset1 = connection.create('Asset', assetData)
# Commit the Asset to Shotgun.
newAsset1.commit()
assetData2 = {
'code': 'Gun_BFG',
'description': 'For noobs'
}
# Create a new Asset and have it immediately commited to Shotgun.
newAsset2 = connection.create('Asset', assetData2, sgCommit=True)Creating new Entities and pre-filling field values with the values of another like-type Entity is called cloning. To create a clone of an Entity you call its SgEntity.clone() function.
Cloning is beneficial when you are going to be creating a number of Entities that will share the same data for a number of fields. This functionality is great for automation scripts.
import ShotgunORM
SERVER_URL = 'https://leetstudios.shotgunstudio.com'
SCRIPT_LOGIN = 'uber_script'
SCRIPT_KEY = 'bf8522eb4fc16a2b5bdf5ae8fc235e8439f3eadb'
connection = ShotgunORM.SgConnection(SERVER_URL, SCRIPT_LOGIN, SCRIPT_KEY)
someRandomAsset = sg.findOne('Asset', [])
cloneFields = ['project', 'sg_asset_type', 'sequence']
# Create 4 clones that will inherit the project, asset type, and sequence field from the Asset.
newEntities = someRandomAsset.clone(inheritFields=cloneFields, numberOfEntities=4)
print newEntities
result : [
<Shotgun.Project.Asset(id:-1)>,
<Shotgun.Project.Asset(id:-1)>,
<Shotgun.Project.Asset(id:-1)>,
<Shotgun.Project.Asset(id:-1)>,
]