Templates and Schemas¶
Templates are a Graphene feature which help with financial modelling by hiding structuring details.
Although the Graphene Data API is schema-less upon definition, providing a schema name (referring to a specific template) tells Graphene how to interpret your data at analysis time. The template that is used upon analysis is determined by 3 relevant pieces of information:
The element type (i.e. node, or link)
The
_schema
field on the element.The
template_search_paths`
defined in the request context
The element type refers to the specific element(s) stored in the Data API and used at analysis time. See Data API for further details on how data is structured in Graphene, and more information on nodes and links.
The _schema
field is a label that identifies what templates could apply to this structure, and is generally the name of a business structure such as CatXL in unison with a version. An example value would be CatXL_1.0.0
The template_search_paths
is part of the request Context and tells Graphene which set of templates to apply for your analysis. The template_search_paths
is an ordered list of paths that correspond to paths where your templates are stored. A typical value for this is ["financial_model"]
, which contains the built-in Graphene templates that ship with the product.
Template Naming Conventions¶
Template names are free-form text, and can be any name you wish with one exception. The exception being that your template must be prefixed with either node_
or link_
, depending on the type of structure you wish it to apply to.
Although the rest of the name is free-form, it is advised that you follow a strict naming convention on Graphene in order to facilitate easy discovery of your structures in the future. It is likely that future versions of Graphene will expose more advanced features for templates that conform to the following naming convention.
<elementType>_<templateName>_<version>.jq
For example,
node_CatXL_1.0.0.jq
The extension (.jq
) identifies the language the template is written in. Currently, Graphene supports jq as a template definition language. Each of the inputs mentioned above is further defined below.
elementType¶
The element type indicates whether the template applies to links or nodes.
The type acts as a safeguard against applying templates meant for nodes to links and vice-versa. For example it ensures that for a link, only a link-typed template (i.e. prefixed with link_
) will be loaded.
templateName¶
The template name should use CamelCase and be limited to printable characters suitable for use in filenames, typically but not limited to [a-zA-Z]
. The initial character should be capitalized.
version¶
The version field serves to order revisions of templates and should always be included. Any changes to templates should receive a new version number. Version numbers take the form
<integer>[[.<integer>][.<integer>][...]]
Structures of the same type should be given an identical prefix. For example, all CatXL structures should begin with CatXL
, such as node_CatXL_1.0.0.jq
, node_CatXL_1.0.1.jq
, etc.
Template Usage Example¶
This shows an example of how templates might be used to alter the results that Graphene produces using templates.
We begin by defining a data node on the Data API.
{
"_schema": "LossSet_1.0",
"paths": {
"v1": "s3://my-bucket/uploads/ledgers/losses_1.parquet",
"v2": "s3://my-bucket/uploads/ledgers/losses_2.parquet",
},
"label": "MyNode"
}
We then define two templates that provide different values for path
.
{
vertices: [
{
_schema: "LossSet_1.0",
path: .paths.v1,
occurrence_key_column: .occurrence_key_column,
currency: .currency,
}
],
edges: []
}
and
{
vertices: [
{
_schema: "LossSet_1.0",
path: .paths.v2,
occurrence_key_column: .occurrence_key_column,
currency: .currency,
}
],
edges: []
}
Finally, when we make a request, we can determine which template is applied by providing different values to template_search_paths
in the Context
of the request. This example shows a request that retrieves both sets of results in a single request.
request = analysis_types.NetworkAnalysisStreamRequest(
trial_range=common.TrialRange(trial_begin=1, trial_count=10),
network_analysis_requests=[
analysis_types.NetworkAnalysisRequest(
query=dms_types.TraversalQuery(
source_constraint=dms_types.NodeQuery(query='label = "MyNode"')
),
context=analysis_types.Context(
template_search_paths=["financial_model/indexed_loss_set/v1"]
),
distribution_metrics=[
analysis.DistributionMetricsDescriptor(
aggregation=analysis.AggregationDescriptor(
aggregation_method=analysis.AEP
),
windows=[analysis.ProbabilityWindow(max_probability=1.0)],
)],
),
analysis_types.NetworkAnalysisRequest(
query=dms_types.TraversalQuery(
source_constraint=dms_types.NodeQuery(query='label = "MyNode"')
),
context=analysis_types.Context(
template_search_paths=["financial_model/indexed_loss_set/v2"]
),
distribution_metrics=[
analysis.DistributionMetricsDescriptor(
aggregation=analysis.AggregationDescriptor(
aggregation_method=analysis.AEP
),
windows=[analysis.ProbabilityWindow(max_probability=1.0)],
)],
),
],
)