diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml index c87a3da..2ed0828 100644 --- a/.github/workflows/main.yaml +++ b/.github/workflows/main.yaml @@ -14,23 +14,11 @@ jobs: python-version: ["3.11"] steps: - - name: Check out repository - uses: actions/checkout@v3 - - - name: Set up Python - uses: actions/setup-python@v4 - with: - python-version: ${{ matrix.python-version }} - - - name: Install Poetry - run: pipx install poetry - - - name: Install dependencies - run: poetry install --no-interaction --no-root + uses: actions/checkout@v4 - - name: Install project - run: poetry install --no-interaction + - name: Set up uv + run: curl -LsSf https://astral.sh/uv/install.sh | sh - - name: Run test suite - run: make test + - name: Run the program + run: uv run main.py diff --git a/.gitignore b/.gitignore index c342e95..c0a010f 100644 --- a/.gitignore +++ b/.gitignore @@ -133,7 +133,8 @@ dmypy.json .pyre/ # Only commit the lockfile in the release branch -poetry.lock +uv.lock # Never commit generated files resources/gens/ +src/wot_thing_description_toolchain_tmp diff --git a/README.md b/README.md index 33e4abb..0b907e9 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,7 @@ This project leverages [LinkML](https://linkml.io/linkml/) for modelling the [We ## Prerequisites -* Python 3.11 or greater. [Download and install Python.](https://www.python.org/downloads/) -* The `poetry` dependency manager. [See the poetry installation documentation for more details.](https://python-poetry.org/docs/#installing-with-pipx) - +The [uv](https://docs.astral.sh/uv/) package manager. ## Quick Start 1. Clone the repository and navigate to the project directory: @@ -23,24 +21,15 @@ This project leverages [LinkML](https://linkml.io/linkml/) for modelling the [We git clone https://github.com/w3c/wot-thing-description-toolchain-tmp.git cd wot-thing-description-toolchain-tmp ``` -2. Prepare a clean environment -``` -python -m venv .venv -. .venv/bin/activate +2. Run the script using `uv` ``` - -3. Install project dependencies with `poetry`: +uv run main.py -h ``` -poetry install -``` - -4. View all supported commands: -`python main.py -h` ## Usage The main.py script supports various options: ``` -main.py [-h] [-l] [-s] +uv run main.py [-h] [-l] [-s] options: -h, --help show this help message and exit @@ -50,11 +39,11 @@ options: ## Examples Generate resources using the default schema and configuration: ``` -python main.py +uv run main.py ``` Generate documentation locally and serve it: -`python main.py -l -s` +`uv run main.py -l -s` #### Default Paths * LinkML schema: `resources/schemas/thing_description.yaml` diff --git a/main.py b/main.py index d624116..31027e5 100644 --- a/main.py +++ b/main.py @@ -1,4 +1,5 @@ import argparse +import json import subprocess from linkml.generators.jsonschemagen import JsonSchemaGenerator @@ -7,7 +8,12 @@ from linkml.generators.jsonldcontextgen import ContextGenerator from linkml.generators.docgen import DocGenerator from linkml.generators.linkmlgen import LinkmlGenerator +from linkml_runtime.utils.schemaview import SchemaView +from linkml_runtime.linkml_model.meta import AnonymousSlotExpression from pathlib import Path +from pyld import jsonld + +from linkml_runtime.linkml_model.meta import SlotDefinition RESOURCES_PATH = Path('resources') GENS_PATH = RESOURCES_PATH / 'gens' @@ -25,28 +31,102 @@ def generate_docs(): doc_generator = DocGenerator(YAML_SCHEMA_PATH, mergeimports=False) doc_generator.serialize(directory=str(DOCDIR)) + +#camelCase conversion of class names in the generated context file + # updated_context = {} + # for cn, value in generated_context.items(): + # camel_case_key = cn[0].lower() + cn[1:] + # if value != {}: + # updated_context[camel_case_key] = value + # serialized_schema_json['@context'] = updated_context + # generated_context = updated_context +def post_process_jsonld_context(schema_view: SchemaView, serialized_schema: str) -> str: + serialized_schema_json = json.loads(serialized_schema) + generated_context = serialized_schema_json.get('@context', {}) + default_range = schema_view.schema.default_range if schema_view.schema.default_range else "string" + for slot in schema_view.all_slots().values(): + slot_name = slot.name + context_entry = generated_context.get(slot_name, {}) + # Update JSON-LD context for slots with multi-language support + is_langstring = slot.range == 'langString' + is_exactly_one_language = ( + slot.range is None and + any( + expr.range == 'langString' + for expr in slot.exactly_one_of if isinstance(expr, AnonymousSlotExpression) + ) + ) + if is_langstring or is_exactly_one_language and isinstance(context_entry, dict): + serialized_schema_json['@context'][slot_name]['@container'] = '@language' + if '@type' in serialized_schema_json['@context'][slot_name].keys(): + del serialized_schema_json['@context'][slot_name]['@type'] + # Update JSON-LD context for slots with a specific encoded language + if slot.in_language and isinstance(context_entry, dict): + context_entry['@language'] = slot.in_language + # inlined and multivalued slot conditions are used to identify dictionaries + if slot.inlined and slot.multivalued and not slot.inlined_as_list and isinstance(context_entry, dict): + context_entry['@container'] = '@index' + if not hasattr(context_entry, '@type'): + context_entry['@type'] = '@id' + if slot.instantiates: + context_entry['@index'] = slot.instantiates + #exactly_one_of expressions + if hasattr(slot, 'exactly_one_of') and slot.exactly_one_of: + ranges = [opt['range'] for opt in slot.exactly_one_of if 'range' in opt] + if len(set(ranges)) == 1: + range_type = ranges[0] + context_entry["@type"] = f"xsd:{range_type}" + else: + print(f"Warning: Slot {slot_name} has different ranges") + elif slot.range == default_range: + context_entry["@type"] = f"xsd:{default_range}" + #Change property name with those that provide aliases + # if slot.aliases and isinstance(context_entry, dict): + # generated_context[slot.aliases[0]] = generated_context.pop(slot_name) + # context_entry = generated_context[slot.aliases[0]] + generated_context[slot_name] = context_entry + #The multivalued slots which do not already have a @container are assigned to a @set + for slot in schema_view.all_slots().values(): + context_entry = generated_context.get(slot.name, {}) + if slot.multivalued and isinstance(context_entry, dict) and '@container' not in context_entry: + context_entry['@container'] = '@set' + context_entry.pop('@type', None) + generated_context[slot.name] = context_entry + # for c in schema_view.all_classes().values(): + # class_name = c.name + # context_entry = generated_context.get(class_name, {}) + # if c.aliases and isinstance(context_entry, dict): + # generated_context[c.aliases[0]] = generated_context.pop(class_name) + # context_entry = generated_context[c.aliases[0]] + # generated_context[class_name] = context_entry + return json.dumps(serialized_schema_json, indent=3) + + def main(generate_docs_flag, serve_docs_flag): if not YAML_SCHEMA_PATH.exists(): print(f"LinkML schema file does not exist: {YAML_SCHEMA_PATH}") return + linkml_schema_view = SchemaView(YAML_SCHEMA_PATH, merge_imports=True) + # TODO: add pre processing for LinkML if needed for generator in GENERATORS: output_dir = GENS_PATH / generator output_dir.mkdir(parents=True, exist_ok=True) if generator == 'jsonschema': # json_schema_generator = JsonSchemaGenerator(yaml_content, top_class="Thing") - json_schema_generator = JsonSchemaGenerator(YAML_SCHEMA_PATH, mergeimports=True) + json_schema_generator = JsonSchemaGenerator(linkml_schema_view.schema, mergeimports=True) (output_dir / 'jsonschema.json').write_text(json_schema_generator.serialize()) elif generator == 'shacl': - shacl_generator = ShaclGenerator(YAML_SCHEMA_PATH, mergeimports=False, closed=True, suffix='Shape') + shacl_generator = ShaclGenerator(linkml_schema_view.schema, mergeimports=False, closed=True, suffix='Shape') (output_dir / 'shapes.shacl.ttl').write_text(shacl_generator.serialize()) elif generator == 'owl': - owl_generator = OwlSchemaGenerator(YAML_SCHEMA_PATH,) + owl_generator = OwlSchemaGenerator(linkml_schema_view.schema,) (output_dir / 'ontology.owl.ttl').write_text(owl_generator.serialize()) elif generator == 'jsonldcontext': - context_generator = ContextGenerator(YAML_SCHEMA_PATH, mergeimports=False) - (output_dir / 'context.jsonld').write_text(context_generator.serialize()) + context_generator = ContextGenerator(linkml_schema_view.schema, mergeimports=True) + (output_dir / 'context.jsonld').write_text(post_process_jsonld_context(linkml_schema_view, + context_generator.serialize())) elif generator == 'linkml': - linkml_generator = LinkmlGenerator(YAML_SCHEMA_PATH, mergeimports=True, format='yaml', output='linkml.yaml') + linkml_generator = LinkmlGenerator(linkml_schema_view.schema, mergeimports=True, format='yaml', output='linkml.yaml') (output_dir / 'linkml.yaml').write_text(linkml_generator.serialize()) else: print(f"Unknown generator: {generator}") @@ -69,3 +149,4 @@ def main(generate_docs_flag, serve_docs_flag): help='Boolean for serving the generated documentation.') args = parser.parse_args() main(args.local_docs, args.serve_docs) + diff --git a/pyproject.toml b/pyproject.toml index 7deda29..70f0a21 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,31 +1,26 @@ -[tool.poetry] +[project] name = "thing_description_schema" -version = "0.0.0.post1.dev0+dfeaf46" +version = "0.1.0" description = "Thing Description Information Model as a LinkML schema" -authors = ["Mahda Noura "] +authors = [ + { name = "Mahda Noura", email = "mahdanoura@gmail.com" } +] license = "MIT" readme = "README.md" include = ["README.md", "src/thing_description_schema/schema", "project"] -package-mode = false -[tool.poetry.dependencies] -python = "^3.11" -linkml-runtime = "^1.8.0rc2" - -[tool.poetry-dynamic-versioning] -enable = false -vcs = "git" -style = "pep440" - -[tool.poetry.dev-dependencies] -linkml = "^1.8.0rc2" -mkdocs-material = "^8.2.8" -mkdocs-mermaid2-plugin = "^0.6.0" -schemasheets = "^0.1.14" +requires-python = ">=3.12" +dependencies = [ + "linkml-runtime>=1.8.2", + "linkml>=1.8.2", + "mkdocs-mermaid2-plugin>=1.1.1", + "mkdocs-material>=9.5.32", + "schemasheets>=0.3.1", +] [build-system] -requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"] -build-backend = "poetry_dynamic_versioning.backend" +requires = ["hatchling"] +build-backend = "hatchling.build" -[tool.poetry.extras] -docs = ["linkml", "mkdocs-material"] +[tool.hatch.build] +only-include = ["main.py"] \ No newline at end of file diff --git a/resources/schemas/hctl.yaml b/resources/schemas/hctl.yaml index 54ecf1f..0e998c0 100644 --- a/resources/schemas/hctl.yaml +++ b/resources/schemas/hctl.yaml @@ -4,6 +4,7 @@ title: hctl version: "1.1-11-June-2024" description: |- LinkML schema for modelling the TD Hypermedia Control information model, in particular links and forms. +contributors: Mahda_Noura license: MIT see_also: - https://www.w3.org/TR/wot-thing-description11/ @@ -40,26 +41,32 @@ classes: Link: class_uri: hctl:Link description: >- - A link can be viewed as a statement of the form link context that has a relation type resource at link target, where the optional target attributes may further describe the resource. + A link can be viewed as a statement of the form link context that has a relation type resource at link target, + where the optional target attributes may further describe the resource. attributes: type: description: Target attribute providing a hint indicating what the media type [IANA-MEDIA-TYPES] of the result of dereferencing the link should be. slot_uri: hctl:hintsAtMediaType - relation: + rel: description: >- A link relation type identifies the semantics of a link. + slot_uri: hctl:hasRelationType anchor: description: >- - By default, the context, or anchor, of a link conveyed in the Link header field is the URL of the representation it is associated with, as defined in RFC7231, Section 3.1.4.1, and is serialized as a URI. - range: uriorcurie + By default, the context, or anchor, of a link conveyed in the Link header field is the URL of the + representation it is associated with, as defined in RFC7231, Section 3.1.4.1, and is serialized as a URI. + slot_uri: hctl:hasAnchor + range: uri sizes: description: >- - Target attribute that specifies one or more sizes for the referenced icon. Only applicable for relation type 'icon'. The value pattern follows {Height}x{Width} (e.g., \"16x16\", \"16x16 32x32\"). + Target attribute that specifies one or more sizes for the referenced icon. Only applicable for relation type + 'icon'. The value pattern follows {Height}x{Width} (e.g., \"16x16\", \"16x16 32x32\"). + slot_uri: hctl:hasSizes hreflang: description: >- - The hreflang attribute specifies the language of a linked document. The value of this must be a valid language tag [[BCP47]]. - multivalued: true - pattern: "^(((([A-Za-z]{2,3}(-([A-Za-z]{3}(-[A-Za-z]{3}){0,2}))?)|[A-Za-z]{4}|[A-Za-z]{5,8})(-([A-Za-z]{4}))?(-([A-Za-z]{2}|[0-9]{3}))?(-([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*(-([0-9A-WY-Za-wy-z](-[A-Za-z0-9]{2,8})+))*(-(x(-[A-Za-z0-9]{1,8})+))?)|(x(-[A-Za-z0-9]{1,8})+)|((en-GB-oed|i-ami|i-bnn|i-default|i-enochian|i-hak|i-klingon|i-lux|i-mingo|i-navajo|i-pwn|i-tao|i-tay|i-tsu|sgn-BE-FR|sgn-BE-NL|sgn-CH-DE)|(art-lojban|cel-gaulish|no-bok|no-nyn|zh-guoyu|zh-hakka|zh-min|zh-min-nan|zh-xiang)))$" + The hreflang attribute specifies the language of a linked document. The value of this must be a valid + language tag [[BCP47]]. + slot_uri: hctl:hasHreflang slots: - href Form: @@ -81,20 +88,13 @@ classes: Content codings are primarily used to allow a representation to be compressed or otherwise usefully transformed without losing the identity of its underlying media type and without loss of information. Examples of content coding include \"gzip\", \"deflate\", etc. - securityDefinitions: - description: >- - Set of security definition names, chosen from those defined in securityDefinitions. These must all be satisfied for access to resources. - slot_uri: td:hasSecurityConfiguration - exactly_one_of: - - range: string - - range: string - multivalued: true + slot_uri: hctl:forContentCoding scopes: description: >- - TODO Check, was not in hctl ontology, if not could be source of discrepancy. Set of authorization scope identifiers provided as an array. These are provided in tokens returned by an authorization server and associated with forms in order to identify what resources a client may access and how. The values associated with a form SHOULD be chosen from those defined in an OAuth2SecurityScheme active on that form. + slot_uri: hctl:scopes exactly_one_of: - range: string - range: string @@ -104,8 +104,8 @@ classes: This optional term can be used if, e.g., the output communication metadata differ from input metadata (e.g., output contentType differ from the input contentType). The response name contains metadata that is only valid for the response messages. slot_uri: hctl:returns - aliases: - - returns + exact_mappings: + - hctl:returns range: ExpectedResponse additionalResponse: description: >- @@ -115,8 +115,8 @@ classes: slot_uri: hctl:additionalReturns multivalued: true range: AdditionalExpectedResponse - aliases: - - additional returns + exact_mappings: + - hctl:additionalReturns subprotocol: slot_uri: hctl:forSubProtocol description: >- @@ -134,6 +134,7 @@ classes: multivalued: true slots: - href + - security ExpectedResponse: class_uri: hctl:ExpectedResponse description: >- @@ -174,10 +175,10 @@ slots: description: >- Target IRI of a link or submission target of a Form. slot_uri: hctl:hasTarget - aliases: - - target required: true - range: uriorcurie + range: uri + exact_mappings: + - hctl:target enums: SubProtocolTypes: diff --git a/resources/schemas/jsonschema.yaml b/resources/schemas/jsonschema.yaml index a5cb6a7..d0507bb 100644 --- a/resources/schemas/jsonschema.yaml +++ b/resources/schemas/jsonschema.yaml @@ -4,6 +4,7 @@ title: jsonschema version: "1.1-05-July-2024" description: |- LinkML schema for modelling the TD Module for data schema specifications. +contributors: Mahda_Noura license: MIT see_also: - https://www.w3.org/TR/wot-thing-description11/ @@ -97,17 +98,19 @@ classes: Used to ensure that the data is valid against one of the specified schemas in the array. This can be used to describe multiple input or output schemas. slot_uri: jsonschema:oneOf + multivalued: true allOf: description: >- Used to ensure that the data is valid against all of the specified schemas in the array. multivalued: true slot_uri: jsonschema:allOf - range: DataSchema +# range: DataSchema anyOf: description: >- Used to ensure that the data is valid against any of the specified schemas in the array. slot_uri: jsonschema:anyOf range: DataSchema + multivalued: true enum: description: >- Restricted set of values provided as an array. @@ -150,21 +153,23 @@ classes: TODO: Check, maybe the range is not a Datatype property rather pointing to classes slot_uri: rdf:type exactly_one_of: - - range: arraySchema - - range: nullSchema - - range: objectSchema - - range: booleanSchema - - range: stringSchema - - range: numberSchema - - range: integerSchema + - range: ArraySchema + - range: NullSchema + - range: ObjectSchema + - range: BooleanSchema + - range: StringSchema + - range: NumberSchema + - range: IntegerSchema slots: - description - title - titles - descriptions - arraySchema: + ArraySchema: is_a: DataSchema class_uri: jsonschema:ArraySchema + aliases: + - array attributes: items: description: >- @@ -182,15 +187,19 @@ classes: Defines the maximum number of items that have to be in the array. slot_uri: jsonschema:maxItems range: integer - booleanSchema: + BooleanSchema: is_a: DataSchema class_uri: jsonschema:BooleanSchema + aliases: + - boolean description: >- Metadata describing data of type boolean. This Subclass is indicated by the value boolean assigned to type in DataSchema instances. - numberSchema: + NumberSchema: is_a: DataSchema class_uri: jsonschema:NumberSchema + aliases: + - number description: >- Metadata describing data of type number. This Subclass is indicated by the value number assigned to type in DataSchema instances. @@ -200,9 +209,11 @@ classes: - exclusiveMinimum - exclusiveMaximum - multipleOf - integerSchema: + IntegerSchema: is_a: DataSchema class_uri: jsonschema:IntegerSchema + aliases: + - integer description: >- Metadata describing data of type integer. This Subclass is indicated by the value integer assigned to type in DataSchema instances. @@ -212,9 +223,11 @@ classes: - exclusiveMinimum - exclusiveMaximum - multipleOf - objectSchema: + ObjectSchema: is_a: DataSchema class_uri: jsonschema:ObjectSchema + aliases: + - object description: >- Metadata describing data of type Object. This Subclass is indicated by the value object assigned to type in DataSchema instances. @@ -224,7 +237,11 @@ classes: Data schema nested definitions. slot_uri: jsonschema:properties range: DataSchema + instantiates: propertyName multivalued: true + inlined: true + inlined_as_list: false + required: slot_uri: jsonschema:required description: >- @@ -232,10 +249,12 @@ classes: is to be sent (e.g. input of invokeaction, writeproperty) and what members will be definitely delivered in the payload that is being received (e.g. output of invokeaction, readproperty). multivalued: true - stringSchema: + StringSchema: # the name has to be changed because apparantly there is an issue with LinkML is_a: DataSchema class_uri: jsonschema:StringSchema + aliases: + - string description: >- Metadata describing data of type string. This Subclass is indicated by the value string assigned to type in DataSchema instances. @@ -267,9 +286,11 @@ classes: - value: base16 - value: base32 - value: base64 - nullSchema: + NullSchema: is_a: DataSchema class_uri: jsonschema:NullSchema + aliases: + - null description: >- Metadata describing data of type null. This subclass is indicated by the value null assigned to type in DataSchema instances. This Subclass describes only one acceptable value, namely null. It is important to note that null does diff --git a/resources/schemas/thing_description.yaml b/resources/schemas/thing_description.yaml index 59b82dc..03b299e 100644 --- a/resources/schemas/thing_description.yaml +++ b/resources/schemas/thing_description.yaml @@ -7,6 +7,7 @@ description: |- according to the W3C WoT Group (https://github.com/w3c/wot). This schema is based on LinkML and is used to generate the required WoT resources e.g., JSON Schema, SHACL shapes, and RDF programmatically. license: MIT +contributors: Mahda_Noura see_also: - https://www.w3.org/TR/wot-thing-description11/ @@ -32,9 +33,6 @@ prefixes: rdf: prefix_prefix: rdf prefix_reference: http://www.w3.org/1999/02/22-rdf-syntax-ns# - dcterms: - prefix_prefix: dcterms - prefix_reference: http://purl.org/dc/terms/ schema: prefix_prefix: schema prefix_reference: http://schema.org/ @@ -50,7 +48,7 @@ prefixes: tm: prefix_prefix: tm prefix_reference: https://www.w3.org/2019/wot/tm# -default_prefix: td +#default_prefix: td default_range: string imports: @@ -60,16 +58,12 @@ imports: - jsonschema types: - MultiLanguage: - name: MultiLanguage - description: Description with a language tag. - from_schema: rdf - exact_mappings: - - rdf:langString - base: rdf:PlainLiteral - uri: rdf:PlainLiteral - structured_pattern: - syntax: "{text}@{tag}" + langString: + name: langString + description: A boolean flag indicating that the string could also include language tag. + base: Bool + uri: xsd:boolean + slots: id: @@ -80,26 +74,24 @@ slots: title: description: >- Provides a human-readable title (e.g., display a text for UI representation) based on a default language. - range: string + in_language: en slot_uri: td:title titles: description: >- Provides multi-language human-readable titles (e.g., display a text for UI representation in different languages). slot_uri: td:titleInLanguage multivalued: true - exactly_one_of: - - range: string - - range: MultiLanguage - inlined_as_list: true + range: langString description: description: >- Provides additional (human-readable) information based on a default language. + in_language: en descriptions: description: >- Can be used to support (human-readable) information in different languages. slot_uri: td:descriptionInLanguage multivalued: true - inlined: true + range: langString # currently less restrictions are applied, with further restrictions according to the json schema, the following can be partially utilized # exactly_one_of: # - range: type_declaration_string @@ -113,6 +105,15 @@ slots: # - range: string # multivalued: true # inlined: false + security: + description: >- + A security configuration is a a security scheme applied to a (set of) affordance(s). + slot_uri: td:hasSecurityConfiguration + required: true + exactly_one_of: + - range: string + multivalued: true + - range: string uriVariables: description: >- Define URI template variables according to RFC6570 as collection based on schema specifications. The individual @@ -120,7 +121,9 @@ slots: slot_uri: td:hasUriTemplateSchema range: DataSchema inlined: true + inlined_as_list: false multivalued: true + instantiates: name forms: slot_uri: td:hasForm description: >- @@ -144,10 +147,10 @@ classes: multivalued: true none_of: - equals_string: 'tm:ThingModel' - + # start of main classes, required for RDF generation - VersionInfo: + versionInfo: description: >- Provides version information. class_uri: td:versionInfo @@ -157,32 +160,34 @@ classes: Provides a version identicator of this TD instance. slot_uri: td:instance required: true + range: string model: description: >- Provides a version indicator of the underlying TM. slot_uri: td:model - securityDefinitionsRange: - description: >- - TODO. - attributes: - name: - description: >- - Indexing property to store entity names when serializing them in a JSON-LD @index container. - slot_uri: wotsec:name - identifier: true - value: - inlined: true - range: Any - exactly_one_of: - - range: bearer - - range: oauth2 - - range: combo - - range: digest - - range: basic - - range: nosec - - range: auto - - range: psk - - range: apikey + range: string +# securityDefinitionsRange: +# description: >- +# TODO. +# attributes: +# name: +# description: >- +# Indexing property to store entity names when serializing them in a JSON-LD @index container. +# slot_uri: wotsec:name +# identifier: true +# value: +# inlined: true +# range: Any +# exactly_one_of: +# - range: bearer +# - range: oauth2 +# - range: combo +# - range: digest +# - range: basic +# - range: nosec +# - range: auto +# - range: psk +# - range: apikey InteractionAffordance: description: >- Metadata of a Thing that shows the possible choices to Consumers, thereby suggesting how Consumers may interact @@ -290,13 +295,13 @@ classes: description: >- JSON-LD keyword to define short-hand names called terms that are used throughout a TD document. required: true - range: uriorcurie + range: uri array: version: description: >- Provides version information. slot_uri: td:versionInfo - range: VersionInfo + range: versionInfo created: slot_uri: dct:created description: >- @@ -323,27 +328,29 @@ classes: slot_uri: td:followsProfile range: Any any_of: - - range: uriorcurie - multivalued: true - - range: uriorcurie - security: - description: >- - A security configuration is a a security scheme applied to a (set of) affordance(s). - slot_uri: td:hasSecurityConfiguration - required: true - exactly_one_of: - - range: string + - range: uri multivalued: true - - range: string + - range: uri securityDefinitions: description: >- A Thing may define abstract security schemes, used to configure the secure access of (a set of) affordance(s). slot_uri: td:definesSecurityScheme - range: securityDefinitionsRange + exactly_one_of: + - range: bearer + - range: oauth2 + - range: combo + - range: digest + - range: basic + - range: nosec + - range: auto + - range: psk + - range: apikey required: true minimum_cardinality: 1 inlined: true + inlined_as_list: false multivalued: true + instantiates: hasInstanceConfiguration schemaDefinitions: description: >- TODO This has to be checked, it is not in the ontologies anywhere. @@ -351,6 +358,8 @@ classes: slot_uri: td:schemaDefinitions multivalued: true range: DataSchema + inlined: true + inlined_as_list: false links: slot_uri: td:hasLink description: >- @@ -363,21 +372,27 @@ classes: slot_uri: td:hasPropertyAffordance multivalued: true inlined: true + inlined_as_list: false range: PropertyAffordance + instantiates: name actions: description: >- All Action-based interaction affordances of the Thing. slot_uri: td:hasActionAffordance multivalued: true inlined: true + inlined_as_list: false range: ActionAffordance + instantiates: name events: description: >- All Event-based interaction affordances of the Thing. slot_uri: td:hasEventAffordance multivalued: true inlined: true + inlined_as_list: false range: EventAffordance + instantiates: name slots: - id - title @@ -388,6 +403,7 @@ classes: - descriptions - uriVariables - forms + - security enums: OperationTypes: @@ -466,4 +482,4 @@ enums: meaning: td:readProperty it: description: Italian - meaning: td:readProperty + meaning: td:readProperty \ No newline at end of file diff --git a/resources/schemas/wot_security.yaml b/resources/schemas/wot_security.yaml index 9d707b7..4785b03 100644 --- a/resources/schemas/wot_security.yaml +++ b/resources/schemas/wot_security.yaml @@ -4,6 +4,7 @@ title: wot_security version: "1.1-5-July-2024" description: |- LinkML schema for modelling the TD Security mechanisms. +contributors: Mahda_Noura license: MIT see_also: - https://www.w3.org/TR/wot-thing-description11/ @@ -66,6 +67,7 @@ classes: range: uri scheme: required: true + #if this is extra in the json schema, you can remove the range, and use induced slot range: SecuritySchemeType hasInstanceConfiguration: slot_uri: td:hasInstanceConfiguration @@ -230,13 +232,11 @@ classes: In this case the key may not be using a standard token format. This scheme indicates that the key provided by the service provider needs to be supplied as part of service requests using the mechanism indicated by the \"in\" field. attributes: - apiKeyIn: - description: >- - Specifies the location of security authentication information. scheme: equals_string: apikey slots: - name + - in psk: is_a: SecurityScheme class_uri: wotsec:PSKSecurityScheme