Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

JSON Schemas primarily supplement Annotations /wiki/spaces/DOCS/pages/2667708522; you should understand Annotations annotations in Synapse before using JSON Schemas. This document also assumes you are comfortable with using the Synapse Python Client.

Note

JSON Schemas are an experimental feature in Synapse. Functionality in the web UI and programmatic clients is currently limited, but we have plans to improve support for managing organizations, schemas, and annotations in the near future.

...

Organizations are different from Teams /wiki/spaces/DOCS/pages/1985446029, which can be used for collaboration, communication, and data sharing.

...

To create an Organization, all you need is a name, which must meet certain requirements.

In Python, after logging in, you can create an organization. Note that you’ll have to change the organization name to something unique.

Code Block
breakoutModewide
breakoutWidth760
languagepy
organizationName = "SynapseDocs"

organizationRequestBody = f"{{ \"organizationName\": \"{organizationName}\"}}"

organization = syn.restPOST("/schema/organization", organizationRequestBody)

...

Note

All JSON Schemas published to Synapse are publicly viewable by anyone on the internet, so make sure your schemas don’t include sensitive information.

Code Block
breakoutModewide
breakoutWidth760
languagepy
schemaRequestBody = """
{
	"schema": {
		"$schema": "http://json-schema.org/draft-07/schema#",
		"$id": "https://repo-prod.prod.sagebase.org/repo/v1/schema/type/registered/SynapseDocs-Color",
		"properties": {
			"color": {
				"type": "string",
				"title": "Color",
				"description": "The color of the object",
				"enum": [
					"Red",
					"Green",
					"Blue",
					"Yellow",
					"Orange",
					"Purple",
					"Brown",
					"Black",
					"White"
				]
			}
		},
		"required": [
			"color"
		]
	},
	"dryRun": false
}
"""

# Issue a request to create the schema
schemaJobResponse = syn.restPOST("/schema/type/create/async/start", schemaRequestBody)

# Check on the job until it completes.
asyncJobStatus = syn.restGET(f"/asynchronous/job/{schemaJobResponse['token']}")

while asyncJobStatus["jobState"] == "PROCESSING":
    time.sleep(1) 
    asyncJobStatus = syn.restGET(f"/asynchronous/job/{schemaJobResponse['token']}")

...

Bound schema inheritance is similar to Sharing Settings /wiki/spaces/DOCS/pages/2024276030 inheritance, but is tracked separately.

If you have edit access on a Synapse object, you can bind a schema to the entity in Python:

Code Block
breakoutModewide
breakoutWidth760
languagepy
objectId = 'syn########' # Replace the ID with your own

bindSchemaRequestjsonSchemaObjectBinding = f"""{{ "entityId": "{objectId}", "schema$id": "SynapseDocs-Color"}}"""

syn.restPUT(f"/entity/{entityId}/schema/binding", bindSchemaRequest)

Even though only one schema can be applied to an item, you can use JSON schema references to create a schema composed of multiple sub-schemas.

In the jsonSchemaObjectBinding, you may also include the boolean property enableDerivedAnnotations to have Synapse automatically calculate derived annotations based on the schema. See the Derived Annotations section below for more information.

Annotate an Object with a Schema

...

In Experimental Mode, you’ll also be able to see if a file’s metadata or annotations are invalid because of missing or invalid data.

...

...

Derived Annotations

JSON Schemas can also be used to prescribe default annotation values. The annotations can be static, or based on conditional properties.

Defining Derived Annotations using a JSON Schema

Derived annotations can be enabled for a set of objects in Synapse when the schema is bound to the object. The JsonSchemaObjectBinding request object should contain the enabledDerivedAnnotations property with a value of true.

The contents of the bound JSON Schema will be used to determine the derived annotations. Derived annotations are denoted using the JSON Schema keywords default and const. For example, consider the following JSON Schema:

Code Block
breakoutModewide
breakoutWidth760
languagejson
{
  "type": "object",
  "properties": {
    "derivedFromConst": {
      "type": "string",
      "const": "Derived Constant Value"
    },
    "derivedFromDefault": {
      "type": "string",
      "default": "Derived Default Value"
    }
  }
}

Any object that has this schema will have the following derived annotations:

Annotation Key

Value

derivedFromConst

Derived Constant Value

derivedFromDefault

Derived Default Value

Conditionally Derived Annotations

JSON Schemas can also be written to conditionally apply annotations. For example, consider the following JSON Schema:

Code Block
breakoutModewide
breakoutWidth760
languagejson
{
  "type": "object",
  "properties": {
    "country": {
      "type": "string",
      "enum": [
        "United States",
        "Canada"
      ]
    },
    "measurementSystem": {
      "type": "string"
    }
  },
  "if": {
    "properties": {
      "country": {
        "const": "United States"
      }
    },
    "required": [
      "country"
    ]
  },
  "then": {
    "properties": {
      "measurementSystem": {
        "const": "Imperial"
      }
    }
  },
  "else": {
    "properties": {
      "measurementSystem": {
        "const": "Metric"
      }
    }
  }
}

On an object where this schema is bound, the derived annotation value for measurementSystem of an object would depend on the actual annotation value of country.

Viewing Derived Annotations

Derived annotations will be returned when fetching annotations using the GET /entity/{id}/annotations2 API by setting the includeDerived parameter to true. Derived annotations will be included with other entity metadata when using the GET /entity/{id}/json service by setting the includeDerivedAnnotations parameter to true.

A table or view can be updated to show derived annotations using the POST /column/column/view/scope/async/start API by passing includeDerivedAnnotations in the request body with a value of true.

Limitations of Derived Annotations

  • Conditionally derived annotations cannot be derived from other conditional annotations

  • Derived annotations will only be generated when the annotation data is valid against the bound JSON Schema