rez.utils.resources#

A general resource system.

Use the classes in this file to create a resource system that supports registering of resource classes, lazy validation of resource attributes, and resource caching. You would not typically have users create Resource instances directly; instead, some factory would be responsible for creating resources, and would probably contain a ResourcePool to manage the resource instances.

Resources have attributes whos names match the entries in Resource.schema. When a resource attribute is accessed for the first time, data validation (and possibly conversion) is applied and cached. Resource data is also loaded lazily - when the first attribute is accessed.

Resources themselves are also cached, according to the cache_size argument of ResourcePool.

Use the ResourceWrapper class to implement classes that provide a public API for a resource. This extra layer is useful because the same resource type may be available from several sources or in different formats. In this situation you can implement multiple Resource subclasses, but wrap them with a single ResourceWrapper class.

Another reason to use ResourceWrapper is when you have attributes on your Resource that don’t require its data to be loaded - instead, some attributes can be derived directly from the resource’s variables. If you provide properties in your resource wrapper for these attributes, then the unnecessary resource data load is avoided.

See the ‘pets’ unit test in tests/test_resources.py for a complete example.

class rez.utils.resources.Resource#

Bases: object

Abstract base class for a data resource.

A resource is an object uniquely identified by a ‘key’ (the resource type), and a dict of variables. For example, a very simple banking system might have a resource type with key ‘account.checking’, and a single variable ‘account_owner’ that uniquely identifies each checking account.

Resources may have a schema, which describes the data associated with the resource. For example, a checking account might have a current balance (an integer) and a social security number (also an integer).

Keys in a resource’s schema are mapped onto the resource class. So a checking account instance ‘account’ would have attributes ‘account.balance’, ‘account.ssn’ etc. Attributes are lazily validated, using the schema, on first access.

A resource’s data is loaded lazily, on first attribute access. This, combined with lazy attribute validation, means that many resources can be iterated, while potentially expensive operations (data loading, attribute validation) are put off as long as possible.

Note

You can access the entire validated resource data dict using the validated_data function, and test full validation using validate_data.

key = None#

Unique identifier of the resource type.

schema = None#

Schema for the resource data. Must validate a dict. Can be None, in which case the resource does not load any data.

schema_error#

The exception type to raise on key validation failure.

alias of Exception

classmethod normalize_variables(variables)#

Give subclasses a chance to standardize values for certain variables

__init__(variables=None)#
handle()#

Get the resource handle.

get(key, default=None)#

Get the value of a resource variable.

class rez.utils.resources.ResourceHandle#

Bases: object

A Resource handle.

A handle uniquely identifies a resource. A handle can be stored and used with a ResourcePool to retrieve the same resource at a later date.

__init__(key, variables=None)#
get(key, default=None)#

Get the value of a resource variable.

to_dict()#

Serialize the contents of this resource handle to a dictionary representation.

classmethod from_dict(d)#

Return a ResourceHandle instance from a serialized dict

This should ONLY be used with dicts created with ResourceHandle.to_dict; if you wish to create a “new” ResourceHandle, you should do it through PackageRepository.make_resource_handle

class rez.utils.resources.ResourcePool#

Bases: object

A resource pool.

A resource pool manages a set of registered resource types, and acts as a resource cache. It will create any resource you ask for - typically resources are created via some factory class, which first checks for the existence of the resource before creating one from a pool.

__init__(cache_size=None)#
register_resource(resource_class)#
get_resource_from_handle(resource_handle)#
clear_caches()#
get_resource_class(resource_key)#
class rez.utils.resources.ResourceWrapper#

Bases: object

An object that wraps a resource instance.

A resource wrapper is useful for two main reasons. First, we can wrap several different resources with the one class, giving them a common interface. This is useful when the same resource can be loaded from various different sources (perhaps a database and the filesystem for example), and further common functionality needs to be supplied.

Second, some resource attributes can be derived from the resource’s variables, which means the resource’s data doesn’t need to be loaded to get these attributes. The wrapper can provide its own properties that do this, avoiding unnecessary data loads.

You must subclass this class and provide keys - the list of attributes in the resource that you want to expose in the wrapper. The schema_keys function is provided to help get a list of keys from a resource schema.

keys = None#
__init__(resource)#
property resource#
property handle#
property data#
validated_data()#
validate_data()#