-
Notifications
You must be signed in to change notification settings - Fork 282
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
new SchemaDef plugin type to define site-specific schemas (#342)
* new SchemaDef plugin type to define site-specific schemas * add missing _update_plugin_source for pkg_resources; force schemadefs to load * add SchemaDef plugin test * add method to extend all three manifest plugin lists at once * cleaner save/restore of existing _MANIFEST * schemadef plugin classes added to otio.schemadef namespace * Explicitly include our source files in MANIFEST.in Travis-CI is having some problems reconciling the file list between sdist and the repo and suggested adding this line: recursive-include opentimelineio * so I'm adding it to see if that works. The particular problem is that it is not picking up one of my latest additions, namely the schemadef directory and the __init__.py file in it. That's the only source file in that directory -- maybe that's the problem? * add UnknownSchema object to pass through undefined schemas Old behavior was to through an exception if any object being read (or created by instance_from_schema) had an unregistered schema name. New behavior is to replace the schema of such objects with the UnknownSchema schema type and save the original schema label in a field called "UnknownSchemaOriginalLabel". Such objects are then available within the OTIO data structure. The new property "is_unknown_schema" will be True for these objects and False for all other SerializableObjects. When an UnknownSchema is serialized, the json_serializer will replace the UnknownSchema label with the original label, so that (for instance) otiocat will pass such unregistered objects through unchanged. This is part of the schemadef project because schemadef plugins imply that we will start to see site or studio-specific OTIO schema types, and it would be more polite to pass these through quietly if you don't understand them. * improve docs and tests for schemadef and unknown schema
- Loading branch information
1 parent
a13284e
commit 9459b2c
Showing
19 changed files
with
542 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
# Writing an OTIO SchemaDef Plugin | ||
|
||
OpenTimelineIO SchemaDef plugins are plugins that define new schemas within the | ||
otio type registry system. | ||
You might want to do this to add new schemas that are specific to your own | ||
internal studio workflow and shouldn't be part of the generic OpenTimelineIO | ||
package. | ||
|
||
To write a new SchemaDef plugin, you create a Python source file that | ||
defines and registers one or more new classes subclassed from | ||
``otio.core.SerializeableObject``. Multiple schema classes can be defined | ||
and registered in one plugin, or you can use a separate plugin for each of them. | ||
|
||
Here's an example of defining a very simple class called ``MyThing``: | ||
|
||
``` | ||
import opentimelineio as otio | ||
@otio.core.register_type | ||
class MyThing(otio.core.SerializableObject): | ||
"""A schema for my thing.""" | ||
_serializable_label = "MyThing.1" | ||
_name = "MyThing" | ||
def __init__( | ||
self, | ||
arg1=None, | ||
argN=None | ||
): | ||
otio.core.SerializableObject.__init__(self) | ||
self.arg1 = arg1 | ||
self.argN = argN | ||
arg1 = otio.core.serializable_field( | ||
"arg1", | ||
doc = ( "arg1's doc string") | ||
) | ||
argN = otio.core.serializable_field( | ||
"argN", | ||
doc = ( "argN's doc string") | ||
) | ||
def __str__(self): | ||
return "MyThing({}, {})".format( | ||
repr(self.arg1), | ||
repr(self.argN) | ||
) | ||
def __repr__(self): | ||
return "otio.schema.MyThing(arg1={}, argN={})".format( | ||
repr(self.arg1), | ||
repr(self.argN) | ||
) | ||
``` | ||
|
||
In the example, the ``MyThing`` class has two parameters ``arg1`` and ``argN``, | ||
but your schema class could have any number of parameters as needed to | ||
contain the data fields you want to have in your class. | ||
|
||
One or more class definitions like this one can be included in a plugin | ||
source file, which must then be added to the plugin manifest as shown below: | ||
|
||
|
||
## Registering Your SchemaDef Plugin | ||
|
||
To create a new SchemaDef plugin, you need to create a Python source file | ||
as shown in the example above. Let's call it ``mything.py``. | ||
Then you must add it to a plugin manifest: | ||
|
||
``` | ||
{ | ||
"OTIO_SCHEMA" : "PluginManifest.1", | ||
"schemadefs" : [ | ||
{ | ||
"OTIO_SCHEMA" : "MyThing.1", | ||
"name" : "mything", | ||
"execution_scope" : "in process", | ||
"filepath" : "mything.py" | ||
} | ||
] | ||
} | ||
``` | ||
|
||
The same plugin manifest may also include adapters and media linkers, if desired. | ||
|
||
Then you need to add this manifest to your `$OTIO_PLUGIN_MANIFEST_PATH` environment variable (which is "`:`" separated). | ||
|
||
## Using the New Schema in Your Code | ||
|
||
Now that we've defined a new otio schema, how can we create an instance of the | ||
schema class in our code (for instance, in an adapter or media linker)? | ||
SchemaDef plugins are magically loaded into a namespace called ``otio.schemadef``, | ||
so you can create a class instance just like this: | ||
|
||
``` | ||
import opentimelineio as otio | ||
mine = otio.schemadef.my_thing.MyThing(arg1, argN) | ||
``` | ||
|
||
An alternative approach is to use the ``instance_from_schema`` | ||
mechanism, which requires that you create and provide a dict of the parameters: | ||
|
||
``` | ||
mything = otio.core.instance_from_schema("MyThing", 1, { | ||
"arg1": arg1, | ||
"argN": argN | ||
}) | ||
``` | ||
|
||
This ``instance_from_schema`` approach has the added benefit of calling the | ||
schema upgrade function to upgrade the parameters in the case where the requested | ||
schema version is earlier than the current version defined by the schemadef plugin. | ||
This seems rather unlikely to occur in practice if you keep your code up-to-date, | ||
so the first technique of creating the class instance directly from | ||
``otio.schemadef`` is usually preferred. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ | |
exceptions, | ||
core, | ||
schema, | ||
schemadef, | ||
plugins, | ||
adapters, | ||
algorithms, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# | ||
# Copyright 2017 Pixar Animation Studios | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "Apache License") | ||
# with the following modification; you may not use this file except in | ||
# compliance with the Apache License and the following modification to it: | ||
# Section 6. Trademarks. is deleted and replaced with: | ||
# | ||
# 6. Trademarks. This License does not grant permission to use the trade | ||
# names, trademarks, service marks, or product names of the Licensor | ||
# and its affiliates, except as required to comply with Section 4(c) of | ||
# the License and to reproduce the content of the NOTICE file. | ||
# | ||
# You may obtain a copy of the Apache License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the Apache License with the above modification is | ||
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
# KIND, either express or implied. See the Apache License for the specific | ||
# language governing permissions and limitations under the Apache License. | ||
# | ||
|
||
""" | ||
Implementation of the UnknownSchema schema. | ||
""" | ||
|
||
from .serializable_object import SerializableObject | ||
from .type_registry import register_type | ||
|
||
|
||
@register_type | ||
class UnknownSchema(SerializableObject): | ||
"""Represents an object whose schema is unknown to us.""" | ||
|
||
_serializable_label = "UnknownSchema.1" | ||
_name = "UnknownSchema" | ||
_original_label = "UnknownSchemaOriginalLabel" | ||
|
||
@property | ||
def is_unknown_schema(self): | ||
return True |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.