-
Notifications
You must be signed in to change notification settings - Fork 12
Code Snippets
The avalon database uses MongoDB. In Avalon's python api it exposes a thin wrapper around pymongo
through avalon.io
. Here are some example code snippets of how you could interact with the database.
Pymongo supports searching by regex and even allows to send a re.compile
returned object as the value for a query directly.
import avalon.io as io
import re
# Compile a regex pattern
pattern = re.compile("character_.*")
# Search in avalon database by pattern
for asset in io.find({"name": pattern, "type": "asset"}):
print(asset)
Using MongoDB it's trivial to list the unique set of values for a specific key using distinct
.
import avalon.io as io
# Get all families that are stored in all versions in version["data"]["families"]
families = io.distinct("data.families", {"type": "version"})
import avalon.io as io
def get_latest_version(asset_name, subset_name):
# Get asset and its subset by name
asset = io.find_one({"name": asset_name,
"type": "asset"})
subset = io.find_one({"name": subset_name,
"type": "subset",
"parent": asset["_id"]})
# Get last version by using io.find_one() and sorting in reverse by name
version = io.find_one({"type": "version",
"parent": subset["_id"]},
sort=[("name", -1)])
return version
version = get_latest_version("hero_x", "modelDefault")
Avalon comes with a Loader tool that makes it easy for artists to load publishes. However, this snippet shows how to do it through code for when you need some automated loading or load assets in bulk, e.g. for a scene builder.
import avalon.api as api
# Get the loader plug-in by its name
name = "AlembicLoader"
loader = next(loader for loader in api.discover(api.Loader)
if loader.__name__ = name)
assert loader, "Loader not found.."
# Assuming you already have the representation id you can load it directly
api.load(loader, representation_id)
You can easily filter the discoverable Loaders to only those that are compatible with a specific representation.
import avalon.api as api
loaders = list(api.discover(api.Loader))
compatible_loaders = api.loaders_from_representation(loaders, representation_id)
If you have a single Loader and want to check whether it's compatible you can do so using api.loaders_from_representation
too, just a pass it [loader]
.
import avalon.api as api
compatible_loaders = api.loaders_from_representation([loader], representation_id)
is_compatible = any(compatible_loaders)
Avalon does have a function to check compatibility of a single Loader. However this function is not exposed in avalon.api
as such it is not enforced to keep its function signature backwards compatible throughout development. It could be stable for use, however the behavior of the functions might change in the future.
import avalon.pipeline
context = avalon.pipeline.get_representation_context(representation_id)
is_compatible = avalon.pipeline.is_compatible_loader(loader, context)
As such, to ensure a stable future, use the avalon.api
.
When loading published content into your work file the loaded content can be found in Avalon's Scene Inventory. You can also query these loaded containers through the api.
# Warning: Running this snippet will remove all loaded content from your scene!
import avalon.api as api
host = api.registered_host()
containers = host.ls()
for container in containers:
api.remove(container)
Note: It is possible for a Loader implemented in a studio configuration to load data unmanaged without a container. In those specific (rare) cases they will not be found with this method. Similarly Avalon's Scene Inventory will also not show them. The loaded content in those cases is "unmanaged".
The Avalon pipeline uses Pyblish for publishing. As such you can publish through a nice interface using Pyblish-QML or Pyblish-Lite. However, you can also publish directly through Python. This would also work when running an application in the background, for example if you want to publish on the farm.
For publishing with pyblish easily through python directly it offers some utility functions in pyblish.util
.
import pyblish.util
pyblish.util.publish()
However, it's likely you want to check whether your publish succeeded. Note that these utility functions return the Pyblish context:
import pyblish.util
context = pyblish.util.publish()
print(context)
Here's a more verbose example from the Pyblish documentation on reporting:
import pyblish.util
context = pyblish.util.publish()
# Create a printed report of errors that occurred
# See: https://learn.pyblish.com/chapters/16-report-ii.html
header = "{:<10}{:<40} -> {}".format("Success", "Plug-in", "Instance")
result = "{success:<10}{plugin.__name__:<40} -> {instance}"
error = "{:<10}+-- EXCEPTION: {:<70}"
results = list()
for r in context.data["results"]:
results.append(result.format(**r))
if r["error"]:
results.append(error.format("", r["error"]))
report = """
{header}
{line}
{results}
"""
print(report.format(header=header,
results="\n".join(results),
line="-" * 70))