From 22a98faf08a9fb866c9949fe05f90378bcfe9fe4 Mon Sep 17 00:00:00 2001 From: Jinzhe Zeng Date: Mon, 3 Jun 2024 03:30:47 -0400 Subject: [PATCH] feat: support generating JSON schema for integration with VSCode Signed-off-by: Jinzhe Zeng --- deepmd/entrypoints/doc.py | 3 ++ deepmd/main.py | 2 +- deepmd/utils/argcheck.py | 18 ++++++++++ doc/train/train-input.rst | 38 +++++++++++++++++++-- pyproject.toml | 2 +- source/tests/common/test_doc_train_input.py | 33 ++++++++++++++++++ 6 files changed, 92 insertions(+), 4 deletions(-) create mode 100644 source/tests/common/test_doc_train_input.py diff --git a/deepmd/entrypoints/doc.py b/deepmd/entrypoints/doc.py index 2f0d57e645..65e38940f8 100644 --- a/deepmd/entrypoints/doc.py +++ b/deepmd/entrypoints/doc.py @@ -4,6 +4,7 @@ from deepmd.utils.argcheck import ( gen_doc, gen_json, + gen_json_schema, ) __all__ = ["doc_train_input"] @@ -15,6 +16,8 @@ def doc_train_input(*, out_type: str = "rst", **kwargs): doc_str = gen_doc(make_anchor=True) elif out_type == "json": doc_str = gen_json() + elif out_type == "json_schema": + doc_str = gen_json_schema() else: raise RuntimeError(f"Unsupported out type {out_type}") print(doc_str) # noqa: T201 diff --git a/deepmd/main.py b/deepmd/main.py index e8b93320c6..322933333c 100644 --- a/deepmd/main.py +++ b/deepmd/main.py @@ -500,7 +500,7 @@ def main_parser() -> argparse.ArgumentParser: parsers_doc.add_argument( "--out-type", default="rst", - choices=["rst", "json"], + choices=["rst", "json", "json_schema"], type=str, help="The output type", ) diff --git a/deepmd/utils/argcheck.py b/deepmd/utils/argcheck.py index 7b6e13be3a..fadec096eb 100644 --- a/deepmd/utils/argcheck.py +++ b/deepmd/utils/argcheck.py @@ -14,7 +14,13 @@ Variant, dargs, ) +from dargs.json_schema import ( + generate_json_schema, +) +from deepmd import ( + __version__, +) from deepmd.common import ( VALID_ACTIVATION, VALID_PRECISION, @@ -2450,6 +2456,18 @@ def gen_args(**kwargs) -> List[Argument]: ] +def gen_json_schema() -> str: + """Generate JSON schema. + + Returns + ------- + str + JSON schema. + """ + arg = Argument("DeePMD-kit", dict, gen_args(), doc=f"DeePMD-kit {__version__}") + return json.dumps(generate_json_schema(arg)) + + def normalize(data): base = Argument("base", dict, gen_args()) data = base.normalize_value(data, trim_pattern="_*") diff --git a/doc/train/train-input.rst b/doc/train/train-input.rst index 04e82451e4..9ffec83fd3 100644 --- a/doc/train/train-input.rst +++ b/doc/train/train-input.rst @@ -1,8 +1,42 @@ Training Parameters ====================================== .. note:: - One can load, modify, and export the input file by using our effective web-based tool `DP-GUI `_ online or hosted using the :ref:`command line interface ` :code:`dp gui`. All training parameters below can be set in DP-GUI. By clicking "SAVE JSON", one can download the input file for furthur training. + One can load, modify, and export the input file by using our effective web-based tool `DP-GUI `_ online or hosted using the :ref:`command line interface ` :code:`dp gui`. All training parameters below can be set in DP-GUI. By clicking "SAVE JSON", one can download the input file for further training. + +.. note:: + One can benefit from IntelliSense and validation when + :ref:`writing JSON files using Visual Studio Code `. + See :ref:`here ` to learn how to configure. .. dargs:: - :module: deepmd.tf.utils.argcheck + :module: deepmd.utils.argcheck :func: gen_args + +.. _json_vscode: + +Writing JSON files using Visual Studio Code +------------------------------------------- + +When writing JSON files using Visual Studio Code, one can benefit from IntelliSense and +validation by adding a `JSON schema `_. +To do so, in a VS Code workspace, one can generate a JSON schema file for the input file by running the following command: + +.. code-block:: bash + + dp doc-train-input --out-type json_schema > deepmd.json + +Then one can `map the schema `_ +by updating the workspace settings in the `.vscode/settings.json` file as follows: + +.. code-block:: json + + { + "json.schemas": [ + { + "fileMatch": [ + "/**/*.json" + ], + "url": "./deepmd.json" + } + ] + } diff --git a/pyproject.toml b/pyproject.toml index 75aab35936..f22ff40fa2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,7 +39,7 @@ dependencies = [ 'numpy', 'scipy', 'pyyaml', - 'dargs >= 0.4.1', + 'dargs >= 0.4.6', 'typing_extensions; python_version < "3.8"', 'importlib_metadata>=1.4; python_version < "3.8"', 'h5py', diff --git a/source/tests/common/test_doc_train_input.py b/source/tests/common/test_doc_train_input.py new file mode 100644 index 0000000000..9522d8d527 --- /dev/null +++ b/source/tests/common/test_doc_train_input.py @@ -0,0 +1,33 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +import io +import json +import unittest +from contextlib import ( + redirect_stdout, +) + +from deepmd.entrypoints.doc import ( + doc_train_input, +) + + +class TestDocTrainInput(unittest.TestCase): + def test_rst(self): + f = io.StringIO() + with redirect_stdout(f): + doc_train_input(out_type="rst") + self.assertTrue(f.getvalue() != "") + + def test_json(self): + f = io.StringIO() + with redirect_stdout(f): + doc_train_input(out_type="json") + # validate json + json.loads(f.getvalue()) + + def test_json_schema(self): + f = io.StringIO() + with redirect_stdout(f): + doc_train_input(out_type="json_schema") + # validate json + json.loads(f.getvalue())