Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add schema for embed API requests #117

Merged
merged 15 commits into from
Jan 17, 2024
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,6 @@ tests/testcontent/
# Pycharm project settings
.idea/
*.iml

# pytest
.pytest_cache/
126 changes: 126 additions & 0 deletions js/EmbedRequest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
// -*- coding: utf-8 -*-
// Generated by scripts/generate_from_specs.py
// EmbedRequest


export const SCHEMA = {
"$id": "/schemas/embed_request",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"description": "Schema for embed requests received by RayServe",
"additionalProperties": false,
"definitions": {
"ancestors": {
"type": "array",
"description": "The ancestors of the topic, in order, from the parent to the root",
"items": {
"$ref": "#/definitions/topic"
}
},
"language": {
"type": "string",
"description": "Language code from https://github.com/learningequality/le-utils/blob/main/le_utils/resources/languagelookup.json",
"pattern": "^[a-z]{2,3}(?:-[a-zA-Z]+)?$"
},
"topic": {
"type": "object",
"description": "A topic in the tree structure",
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "The ID of the topic content node on Studio"
},
"title": {
"type": "string",
"description": "The title of the topic"
},
"description": {
"type": "string",
"description": "The description of the topic"
},
"language": {
"$ref": "#/definitions/language"
},
"ancestors": {
"$ref": "#/definitions/ancestors"
}
},
"required": [
"id",
"title",
"description"
]
},
"resource": {
"type": "object",
"description": "The key textual metadata and data for a content resource",
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"description": "The ID of the content resource"
},
"title": {
"type": "string",
"description": "The title of the content resource"
},
"description": {
"type": "string",
"description": "The description of the content resource"
},
"text": {
"type": "string",
"description": "The cleaned up text extracted from the content resource (in markdown or plaintext format)"
},
"language": {
"$ref": "#/definitions/language"
}
},
"required": [
"id",
"title",
"description",
"text"
]
}
},
"properties": {
"topics": {
"type": "array",
"description": "A list of topics to embed",
"items": {
"$ref": "#/definitions/topic"
}
},
"resources": {
"type": "array",
"description": "A list of content resources to embed",
"items": {
"$ref": "#/definitions/resource"
}
},
"metadata": {
"type": "object",
"description": "The metadata of the channel for logging purposes",
"properties": {
"channel_id": {
"type": "string",
"description": "The ID of the channel"
},
"channel_title": {
"type": "string",
"description": "The title of the channel"
}
},
"required": [
"channel_id",
"channel_title"
]
akolson marked this conversation as resolved.
Show resolved Hide resolved
}
},
"required": [
"topics",
"resources"
]
};
102 changes: 102 additions & 0 deletions le_utils/constants/embed_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# -*- coding: utf-8 -*-
# Generated by scripts/generate_from_specs.py
from __future__ import unicode_literals

# EmbedRequest


choices = ()

EMBEDREQUESTLIST = []

SCHEMA = {
"$id": "/schemas/embed_request",
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"description": "Schema for embed requests received by RayServe",
"additionalProperties": False,
"definitions": {
"ancestors": {
"type": "array",
"description": "The ancestors of the topic, in order, from the parent to the root",
"items": {"$ref": "#/definitions/topic"},
},
"language": {
"type": "string",
"description": "Language code from https://github.com/learningequality/le-utils/blob/main/le_utils/resources/languagelookup.json",
"pattern": "^[a-z]{2,3}(?:-[a-zA-Z]+)?$",
},
"topic": {
"type": "object",
"description": "A topic in the tree structure",
"additionalProperties": False,
"properties": {
"id": {
"type": "string",
"description": "The ID of the topic content node on Studio",
},
"title": {"type": "string", "description": "The title of the topic"},
"description": {
"type": "string",
"description": "The description of the topic",
},
"language": {"$ref": "#/definitions/language"},
"ancestors": {"$ref": "#/definitions/ancestors"},
},
"required": ["id", "title", "description"],
},
"resource": {
"type": "object",
"description": "The key textual metadata and data for a content resource",
"additionalProperties": False,
"properties": {
"id": {
"type": "string",
"description": "The ID of the content resource",
},
"title": {
"type": "string",
"description": "The title of the content resource",
},
"description": {
"type": "string",
"description": "The description of the content resource",
},
"text": {
"type": "string",
"description": "The cleaned up text extracted from the content resource (in markdown or plaintext format)",
},
"language": {"$ref": "#/definitions/language"},
},
"required": ["id", "title", "description", "text"],
},
},
"properties": {
"topics": {
"type": "array",
"description": "A list of topics to embed",
"items": {"$ref": "#/definitions/topic"},
},
"resources": {
"type": "array",
"description": "A list of content resources to embed",
"items": {"$ref": "#/definitions/resource"},
},
"metadata": {
"type": "object",
"description": "The metadata of the channel for logging purposes",
"properties": {
"channel_id": {
"type": "string",
"description": "The ID of the channel",
},
"channel_title": {
"type": "string",
"description": "The title of the channel",
},
},
"required": ["channel_id", "channel_title"],
},
},
"required": ["topics", "resources"],
}
Empty file added le_utils/validators/__init__.py
Empty file.
11 changes: 11 additions & 0 deletions le_utils/validators/embed_request.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import jsonschema

from le_utils.constants.embed_request import SCHEMA


def validate(data):
"""
:param data: Dictionary of data to validate
:raises: jsonschema.ValidationError: When invalid
"""
jsonschema.validate(instance=data, schema=SCHEMA)
25 changes: 15 additions & 10 deletions scripts/generate_from_specs.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,11 @@ def write_js_file(output_file, name, ordered_output, schema=None):
write_js_header(f)
f.write("// {}\n".format(name))
f.write("\n")
f.write("export default {\n")
for key, value in ordered_output.items():
f.write(' {key}: "{value}",\n'.format(key=key, value=value))
f.write("};\n")
if ordered_output:
f.write("export default {\n")
for key, value in ordered_output.items():
f.write(' {key}: "{value}",\n'.format(key=key, value=value))
f.write("};\n")
if schema:
f.write("\n")
f.write("export const SCHEMA = {};\n".format(schema))
Expand All @@ -255,16 +256,20 @@ def write_labels_src_files(label_outputs):

def write_constants_src_files(constants_outputs, schemas):
output_files = []
for constant_type, ordered_output in constants_outputs.items():
keys = set(list(constants_outputs.keys()) + list(schemas.keys()))

for key in keys:
constant_outputs = constants_outputs.get(key, {})
schema = schemas.get(key, None)

py_output_file = os.path.join(
py_output_dir, "{}.py".format(pascal_to_snake(constant_type))
py_output_dir, "{}.py".format(pascal_to_snake(key))
)
schema = schemas.get(constant_type)
write_python_file(py_output_file, constant_type, ordered_output, schema=schema)
write_python_file(py_output_file, key, constant_outputs, schema=schema)
output_files.append(py_output_file)

js_output_file = os.path.join(js_output_dir, "{}.js".format(constant_type))
write_js_file(js_output_file, constant_type, ordered_output, schema=schema)
js_output_file = os.path.join(js_output_dir, "{}.js".format(key))
write_js_file(js_output_file, key, constant_outputs, schema=schema)
output_files.append(js_output_file)
return output_files

Expand Down
Loading
Loading