Shotgun一些官方例子

参考来源:https://developer.shotgunsoftware.com/python-api/reference.html

创建一个镜头

Shotgun.create(entity_type, data, return_fields=None)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> data = {
"project": {"type": "Project", "id": 161},
"sg_sequence": {"type": "Sequence", "id": 109},
"code": "001_100",
'sg_status_list': "ip"
}

>>> sg.create('Shot', data)

{'code': '001_100',
'id': 2557,
'project': {'id': 161, 'name': 'Pied Piper', 'type': 'Project'},
'sg_sequence': {'id': 109, 'name': 'Sequence 001', 'type': 'Sequence'},
'sg_status_list': 'ip',
'type': 'Shot'}

指定Project id 和 Sequence id,返回所有Character的资产

Shotgun.find(entity_type, filters, fields=None, order=None, filter_operator=None, limit=0, retired_only=False, page=0, include_archived_projects=True, additional_filter_presets=None)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
>>> # Find Character Assets in Sequence 100_FOO
>>> # -------------
>>> fields = ['id', 'code', 'sg_asset_type']
>>> sequence_id = 2 # Sequence "100_FOO"
>>> project_id = 4 # Demo Project
>>> filters = [
... ['project', 'is', {'type': 'Project', 'id': project_id}],
... ['sg_asset_type', 'is', 'Character'],
... ['sequences', 'is', {'type': 'Sequence', 'id': sequence_id}]
... ]
>>> assets= sg.find("Asset",filters,fields)
[{'code': 'Gopher', 'id': 32, 'sg_asset_type': 'Character', 'type': 'Asset'},
{'code': 'Cow', 'id': 33, 'sg_asset_type': 'Character', 'type': 'Asset'},
{'code': 'Bird_1', 'id': 35, 'sg_asset_type': 'Character', 'type': 'Asset'},
{'code': 'Bird_2', 'id': 36, 'sg_asset_type': 'Character', 'type': 'Asset'},
{'code': 'Bird_3', 'id': 37, 'sg_asset_type': 'Character', 'type': 'Asset'},
{'code': 'Raccoon', 'id': 45, 'sg_asset_type': 'Character', 'type': 'Asset'},
{'code': 'Wet Gopher', 'id': 149, 'sg_asset_type': 'Character', 'type': 'Asset'}]

指定Project id 和 animation step id,返回所有Version

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
>>> # Find Versions created by Tasks in the Animation Pipeline Step
>>> # -------------
>>> fields = ['id', 'code']
>>> pipeline_step_id = 2 # Animation Step ID
>>> project_id = 4 # Demo Project
>>> # you can drill through single-entity link fields
>>> filters = [
... ['project','is', {'type': 'Project','id': project_id}],
... ['sg_task.Task.step.Step.id', 'is', pipeline_step_id]
>>> ]
>>> sg.find("Version", filters, fields)
[{'code': 'scene_010_anim_v001', 'id': 42, 'type': 'Version'},
{'code': 'scene_010_anim_v002', 'id': 134, 'type': 'Version'},
{'code': 'bird_v001', 'id': 137, 'type': 'Version'},
{'code': 'birdAltBlue_v002', 'id': 236, 'type': 'Version'}]

指定类型和id,返回名称

Shotgun.find_one(entity_type, filters, fields=None, order=None, filter_operator=None, retired_only=False, include_archived_projects=True, additional_filter_presets=None)

1
2
3
4
# 这里的Asset可以是Project,Sequence,Shot,Version等等

>>> sg.find_one("Asset", [["id", "is", 32]], ["id", "code", "sg_status_list"])
{'code': 'Gopher', 'id': 32, 'sg_status_list': 'ip', 'type': 'Asset'}

更新选定镜头的制作状态

Shotgun.update(entity_type, entity_id, data, multi_entity_update_modes=None)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 看起来好像有问题,待测试
>>> shots = [
... {'type':'Shot', 'id':'40435'},
... {'type':'Shot', 'id':'40438'},
... {'type':'Shot', 'id':'40441'}]
>>> data = {
... 'shots': shots,
... 'sg_status_list':'rev'}
>>> sg.update("Asset", 55, data)
{'type': 'Shot',
'id': 55,
'sg_status_list': 'rev',
'shots': [{'id': 40435, 'name': '100_010', 'type': 'Shot', 'valid': 'valid'},
{'id': 40438, 'name': '100_040', 'type': 'Shot', 'valid': 'valid'},
{'id': 40441, 'name': '100_070', 'type': 'Shot', 'valid': 'valid'}]
}

删除一个镜头

1
2
>>> sg.delete("Shot", 2557)
True

恢复之前删除的镜头

Shotgun.revive(entity_type, entity_id)

1
2
>>> sg.revive("Shot", 860)
True

批量处理(创建,删除,更新)镜头

Shotgun.batch(requests)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# batch可用作于create(), update(), delete()
# 使用batch函数的任务,要么全部完成,要么全都不完成

batch_data = []
for i in range(1,100):
data = {
"code": "shot_%04d" % i,
"project": project
}
batch_data.append({"request_type": "create", "entity_type": "Shot", "data": data})
sg.batch(batch_data)

# 三种不同类型可同时存在
batch_data = [
{"request_type": "create", "entity_type": "Shot", "data": {"code": "New Shot 1", "project": project}},
{"request_type": "update", "entity_type": "Shot", "entity_id": 3624, "data": {"code": "Changed 1"}},
{"request_type": "delete", "entity_type": "Shot", "entity_id": 3624}
]
sg.batch(batch_data)

计算指定项目中所有Assets数量

Shotgun.summarize(entity_type, filters, summary_fields, filter_operator=None, grouping=None, include_archived_projects=True)

1
2
3
4
5
6
>>> sg.summarize(entity_type='Asset',
... filters = [['project', 'is', {'type':'Project', 'id':4}]],
... summary_fields=[{'field':'id', 'type':'count'}])
{'groups': [], 'summaries': {'id': 15}}

# 返回值的id即为数量

计算指定项目中所有Assets数量,按照sg_asset_type排序

1
2
3
4
5
6
7
8
9
10
11
12
13
>>> sg.summarize(entity_type='Asset',
... filters=[['project', 'is', {'type': 'Project', 'id': 4}]],
... summary_fields=[{'field': 'id', 'type': 'count'}],
... grouping=[{'field': 'sg_asset_type', 'type': 'exact', 'direction': 'asc'}])

# Groups里是每个类型资产的总数
{'groups': [{'group_name': 'Character','group_value': 'Character', 'summaries': {'id': 3}},
{'group_name': 'Environment','group_value': 'Environment', 'summaries': {'id': 3}},
{'group_name': 'Matte Painting', 'group_value': 'Matte Painting', 'summaries': {'id': 1}},
{'group_name': 'Prop', 'group_value': 'Prop', 'summaries': {'id': 4}},
{'group_name': 'Vehicle', 'group_value': 'Vehicle', 'summaries': {'id': 4}}],
'summaries': {'id': 15}}
# 最后是所有资产的总和

计算一个Sequence里所有的任务数量,并找到其中最近截止日期

1
2
3
4
5
6
7
8
9
>>> sg.summarize(entity_type='Task',
... filters = [
... ['entity.Shot.sg_sequence', 'is', {'type':'Sequence', 'id':2}],
... ['sg_status_list', 'is_not', 'na']],
... summary_fields=[{'field':'id', 'type':'count'},
... {'field':'due_date','type':'latest'}])

# 最近的截至日期,和当前场次所有任务的总数
{'groups': [], 'summaries': {'due_date': '2013-07-05', 'id': 30}}

计算一个Sequence里所有的任务数量,并列出所有Shots,按照截至日期排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
>>> sg.summarize(entity_type='Task',
... filters = [
... ['entity.Shot.sg_sequence', 'is', {'type': 'Sequence', 'id': 2}],
... ['sg_status_list', 'is_not', 'na']],
... summary_fields=[{'field': 'id', 'type': 'count'}, {'field': 'due_date', 'type': 'latest'}],
... grouping=[{'field': 'entity', 'type': 'exact', 'direction': 'asc'}]))
{'groups': [{'group_name': 'shot_010',
'group_value': {'id': 2, 'name': 'shot_010', 'type': 'Shot', 'valid': 'valid'},
'summaries': {'due_date': '2013-06-18', 'id': 10}},
{'group_name': 'shot_020',
'group_value': {'id': 3, 'name': 'shot_020', 'type': 'Shot', 'valid': 'valid'},
'summaries': {'due_date': '2013-06-28', 'id': 10}},
{'group_name': 'shot_030',
'group_value': {'id': 4, 'name': 'shot_030', 'type': 'Shot', 'valid': 'valid'},
'summaries': {'due_date': '2013-07-05', 'id': 10}}],
'summaries': {'due_date': '2013-07-05', 'id': 30}}

计算一个Sequence里所有任务数量,找到最近的截止日期,并列出所有Shots和Step

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
>>> sg.summarize(entity_type='Task',
... filters = [
... ['entity.Shot.sg_sequence', 'is', {'type': 'Sequence', 'id': 2}],
... ['sg_status_list', 'is_not', 'na']],
... summary_fields=[{'field': 'id', 'type': 'count'},
... {'field': 'due_date', 'type': 'latest'}],
... grouping=[{'field': 'entity', 'type': 'exact', 'direction': 'asc'},
... {'field': 'step', 'type': 'exact', 'direction': 'asc'}])
# shot_010
{'groups': [{'group_name': 'shot_010',
'group_value': {'id': 2, 'name': 'shot_010', 'type': 'Shot', 'valid': 'valid'},
'groups': [{'group_name': 'Client',
'group_value': {'id': 1, 'name': 'Client', 'type': 'Step', 'valid': 'valid'},
'summaries': {'due_date': '2013-05-04', 'id': 1}},
{'group_name': 'Online',
'group_value': {'id': 2, 'name': 'Online', 'type': 'Step', 'valid': 'valid'},
'summaries': {'due_date': '2013-05-05', 'id': 1}},
...
... truncated for brevity
...
{'group_name': 'Comp',
'group_value': {'id': 8, 'name': 'Comp', 'type': 'Step', 'valid': 'valid'},
'summaries': {'due_date': '2013-06-18', 'id': 1}}],
'summaries': {'due_date': '2013-06-18', 'id': 10}},
# shot_020
{'group_name': 'shot_020',
'group_value': {'id': 3, 'name': 'shot_020', 'type': 'Shot', 'valid': 'valid'},
'groups': [{'group_name': 'Client',
'group_value': {'id': 1, 'name': 'Client', 'type': 'Step', 'valid': 'valid'},
'summaries': {'due_date': '2013-05-15', 'id': 1}},
{'group_name': 'Online',
'group_value': {'id': 2, 'name': 'Online', 'type': 'Step', 'valid': 'valid'},
'summaries': {'due_date': '2013-05-16', 'id': 1}},
...
... truncated for brevity
...
{'group_name': 'Comp',
'group_value': {'id': 8, 'name': 'Comp', 'type': 'Step', 'valid': 'valid'},
'summaries': {'due_date': '2013-06-28', 'id': 1}}],
'summaries': {'due_date': '2013-06-28', 'id': 10}},
# shot_030
{'group_name': 'shot_030',
'group_value': {'id': 4, 'name': 'shot_030', 'type': 'Shot', 'valid': 'valid'},
'groups': [{'group_name': 'Client',
'group_value': {'id': 1, 'name': 'Client', 'type': 'Step', 'valid': 'valid'},
'summaries': {'due_date': '2013-05-20', 'id': 1}},
{'group_name': 'Online',
'group_value': {'id': 2, 'name': 'Online', 'type': 'Step', 'valid': 'valid'},
'summaries': {'due_date': '2013-05-21', 'id': 1}},
...
... truncated for brevity
...
{'group_name': 'Comp',
'group_value': {'id': 8, 'name': 'Comp', 'type': 'Step', 'valid': 'valid'},
'summaries': {'due_date': '2013-07-05', 'id': 1}}],
'summaries': {'due_date': '2013-07-05', 'id': 10}}],

# 总数
'summaries': {'due_date': '2013-07-05', 'id': 30}}

给notes id参数,返回完整notes对话,包括回复与附件

Shotgun.note_thread_read(note_id, entity_fields=None)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
>>> Shotgun.note_thread_read(note_id, entity_fields=None)

[{'content': 'Please add more awesomeness to the color grading.',
'created_at': '2015-07-14 21:33:28 UTC',
'created_by': {'id': 38,
'name': 'John Pink',
'status': 'act',
'type': 'HumanUser',
'valid': 'valid'},
'id': 6013,
'type': 'Note'},
{'created_at': '2015-07-14 21:33:32 UTC',
'created_by': {'id': 38,
'name': 'John Pink',
'status': 'act',
'type': 'HumanUser',
'valid': 'valid'},
'id': 159,
'type': 'Attachment'},
{'content': 'More awesomeness added',
'created_at': '2015-07-14 21:54:51 UTC',
'id': 5,
'type': 'Reply',
'user': {'id': 38,
'name': 'David Blue',
'status': 'act',
'type': 'HumanUser',
'valid': 'valid'}}]

给定一个text参数,和entiry_type参数,全局搜索匹配条件的资产

Shotgun.text_search(text, entity_types, project_ids=None, limit=None) # 这里可以给定Project id参数,限制搜索范围

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
>>> entity_types = {
... "Asset": [["sg_asset_type", "is", "Character"]],
... "Task": []
... }
>>> sg.text_search("bunny", entity_types)

{'matches': [{'id': 734,
'type': 'Asset',
'name': 'Bunny',
'project_id': 65,
'image': 'https://...',
'links': ['', ''],
'status': 'fin'},
...
{'id': 558,
'type': 'Task'
'name': 'FX',
'project_id': 65,
'image': 'https://...',
'links': ['Shot', 'bunny_010_0010'],
'status': 'fin'}],
'terms': ['bunny']}

上传mov到指定的shot,标志为sg_latest_quicktime

Shotgun.upload(entity_type, entity_id, path, field_name=None, display_name=None, tag_list=None)

1
2
3
4
5
6
7
8
9
10
11
12
13
# 官方的例子
>>> mov_file = '/data/show/ne2/100_110/anim/01.mlk-02b.mov'
>>> sg.upload("Shot", 423, mov_file, field_name="sg_latest_quicktime",
... display_name="Latest QT")
72

# 自己尝试的方法
if (not os.environ.get('PYTHONHTTPSVERIFY', '') and getattr(ssl, '_create_unverified_context', None)):
ssl._create_default_https_context = ssl._create_unverified_context

sg = shotgun_api.Shotgun(const.SHOTGUN_WEB_PATH, const.SCRIPT_NAME, const.API_KEY)
mov_file = r'D:\\show\VPT\B003C022\img\B003C022_layout_v001.mov'
sg.upload('Version', 8676, mov_file, 'sg_uploaded_movie')

上传本地文件到指定的entity下

Shotgun.upload_thumbnail(entity_type,entity_id,path,** kwargs )

图像将在服务器上自动调整大小,以生成适合大小的图像文件。但是,原始文件也将保留,并且在Web UI中单击缩略图时可以访问。如果您使用本地安装的Shotgun而未启用S3,则如果您要为缩略图上传非常大的源图像,则会占用磁盘空间。

从给定的版本下载附件

Shotgun.download_attachment(attachment=False, file_path=None, attachment_id=None)

1
2
3
4
5
>>> version = sg.find_one("Version", [["id", "is", 7115]], ["sg_uploaded_movie"])
>>> local_file_path = "/var/tmp/%s" % version["sg_uploaded_movie"]["name"]
>>> sg.download_attachment(version["sg_uploaded_movie"], file_path=local_file_path)

/var/tmp/100b_scene_output_v032.mov

返回下载附件的URL

Shotgun.get_attachment_download_url(attachment)