Objects, URLs, and Schemas#

In this section, we cover the fundamentals of the 3LC object-model and primary usage of the tlc Python package.

In this article, we will cover the basics of Objects, Urls, and Schemas.

Objects#

The base class for all objects in the tlc Python package is Object. An Object is a simple container for keys and values. All objects must contain the keys

  • type

  • created

Let’s create a single object and inspect it:

{
  "type":"Object",
  "created":"2023-11-24 12:15:45.045266+00:00"
}

Urls#

Instances of type Object are capable of being serialized into JSON format and can be stored in various locations. The specific location of an object is defined by a Url, which might represent either a local file path or a remote URL.

Now, let’s proceed to create an Object and save it to a local file path.

[2]:
# Create a relative filepath Url
url = tlc.Url("./my_object.json")

# Create an object with the given url and write it to the url
my_object = tlc.Object(url=url)
my_object.write_to_url()

[2]:
Url(relative://my_object.json)

Objects can be read back into memory using Object.from_url().

{
  "type":"Object",
  "created":"2023-11-24 12:15:45.058269+00:00"
}

Our object has now round-tripped from in-memory to a location specified by a tlc.Url, and back again. The JSON representation of an object contains all of the information needed to reconstruct the object, so this defines a mechanism for sharing objects between users or processes.

Schemas#

All tlc Objects are described by schemas. A schema in tlc is a tree-like structure that describes the layout of an object. Schemas and related functionality are defined in the tlc.core.schema module.

A Schema describes an attribute of an object. This means not only describing the data type of the attribute, but also the dimensionality, size, display parameters, and more.

An object-attribute can be either composite or atomic. This is signalled by the presence of either the value attribute, or the values attribute. If the value attribute is present, then the schema is atomic, and the data is described by the ScalarValue subclass stored in the value attribute of the schema. If the values attribute is present, then the attribute is composite, and the schema can be recursed by following the sub-attributes defined in the values attribute of the schema, which is of type dict[str, Schema].

tlc does not have a separate notion of list- or array-schemas. Instead, the dimensionality and shape of an attribute is described by the size0, size1, …, size5 attributes of [Schema], which are of type DimensionNumericValue.

Enough theory, let’s look at some examples!

[4]:
# Create some atomic schemas

## A schema describing a integer value between 0 and 100.
int_schema = tlc.Schema(
    display_name="Integer Value Schema",
    description="This is an example schema",
    writable=False,  # The value described by this schema is not writable
    value=tlc.Int32Value(value_min=0, value_max=100),
    )

print(int_schema)

## A schema describing a variable sized array of floats.
float_array_schema = tlc.Schema(
    display_name="Float Array Schema",
    description="This is an example schema",
    writable=True,  # The value described by this schema is writable
    value=tlc.Float32Value(unit="ms"),
)
float_array_schema.size0 = tlc.DimensionNumericValue(value_min=1, value_max=10)

# Create a composite schema from the atomic schemas
composite_schema = tlc.Schema(values={"float_array": float_array_schema, "int_value": int_schema})

print(composite_schema)
{
  "display_name":"Integer Value Schema",
  "description":"This is an example schema",
  "writable":false,
  "value":{
    "type":"int32",
    "min":0,
    "max":100
  }
}
{
  "values":{
    "float_array":{
      "display_name":"Float Array Schema",
      "description":"This is an example schema",
      "size0":{
        "type":"int32",
        "min":1,
        "max":10,
        "enforce_min":true
      },
      "value":{
        "unit":"ms"
      }
    },
    "int_value":{
      "display_name":"Integer Value Schema",
      "description":"This is an example schema",
      "writable":false,
      "value":{
        "type":"int32",
        "min":0,
        "max":100
      }
    }
  }
}